@@ -218,6 +226,13 @@ class SelectionDialog {
// Поиск — обработчик вешается в setup_search_field()
+ // Фильтр "Только складские товары"
+ this.dialog.$wrapper.find('#selection-maintain-stock').on('change', function() {
+ me.filters.maintain_stock = $(this).prop('checked');
+ me.current_page = 0;
+ me.load_items();
+ });
+
// Фильтр "Только в наличии"
this.dialog.$wrapper.find('#selection-only-in-stock').on('change', function() {
if (!me.filters.warehouse) {
@@ -239,6 +254,7 @@ class SelectionDialog {
if (me.warehouse_field) me.warehouse_field.set_value('');
if (me.pricelist_field) me.pricelist_field.set_value('');
me.dialog.$wrapper.find('#selection-only-in-stock').prop('checked', false);
+ me.dialog.$wrapper.find('#selection-maintain-stock').prop('checked', false);
me.dialog.$wrapper.find('.item-group-tree .active').removeClass('active');
me._update_stock_toggle_state();
// Очищаем произвольные фильтры
@@ -353,29 +369,33 @@ class SelectionDialog {
const $rows = this.dialog.$wrapper.find('#selection-items-grid tbody tr');
const row_count = $rows.length;
- if (row_count === 0) return;
-
if (e.key === 'ArrowDown') {
+ if (row_count === 0) return;
e.preventDefault();
this.focused_row_index = Math.min(this.focused_row_index + 1, row_count - 1);
this._update_focused_row($rows);
+ $rows.eq(this.focused_row_index).find('.row-qty-input').focus().select();
} else if (e.key === 'ArrowUp') {
+ if (row_count === 0) return;
e.preventDefault();
this.focused_row_index = Math.max(this.focused_row_index - 1, 0);
this._update_focused_row($rows);
+ $rows.eq(this.focused_row_index).find('.row-qty-input').focus().select();
+ } else if (e.key === 'Enter' && e.ctrlKey) {
+ // Добавить всё в документ
+ e.preventDefault();
+ e.stopPropagation();
+ this.finalize_selection();
} else if (e.key === 'Enter' && !e.ctrlKey) {
- // Добавить выделенный товар в корзину
+ // Всегда блокируем — иначе Frappe перехватит и вызовет primary action
+ e.preventDefault();
+ e.stopPropagation();
if (this.focused_row_index >= 0 && this.items_data[this.focused_row_index]) {
- e.preventDefault();
const $row = $rows.eq(this.focused_row_index);
const qty_val = parseFloat(($row.find('.row-qty-input').val() || '').replace(',', '.')) || 1;
const item = this.items_data[this.focused_row_index];
this.add_to_cart(item, qty_val);
}
- } else if (e.key === 'Enter' && e.ctrlKey) {
- // Добавить всё в документ
- e.preventDefault();
- this.finalize_selection();
} else if (e.key === 'Escape') {
this.dialog.hide();
}
@@ -555,6 +575,7 @@ class SelectionDialog {
company: this.frm.doc.company || '',
transaction_date: this.frm.doc.posting_date || frappe.datetime.get_today(),
only_in_stock: this.filters.only_in_stock || false,
+ maintain_stock: this.filters.maintain_stock || false,
sort_by: this.sort_by,
sort_order: this.sort_order
};
@@ -645,6 +666,13 @@ class SelectionDialog {
${img_html} |
${item.item_name}
+
+
+
${item.item_code}
${item.item_group ? ` ${item.item_group}` : ''}
|
@@ -713,10 +741,12 @@ class SelectionDialog {
// Клик по строке для навигации и инфо-панели
$grid.find('tbody tr').on('click', function(e) {
- if (!$(e.target).closest('.btn-add-to-cart, .row-qty-input, .stock-indicator').length) {
+ if (!$(e.target).closest('.btn-add-to-cart, .row-qty-input, .stock-indicator, .item-open-link').length) {
me.focused_row_index = parseInt($(this).data('item-index'));
me._update_focused_row($grid.find('tbody tr'));
me.show_item_info(me.focused_row_index);
+ // Фокус на qty чтобы сразу можно было вводить количество
+ $(this).find('.row-qty-input').focus().select();
}
});
@@ -725,7 +755,21 @@ class SelectionDialog {
const item_index = parseInt($(this).data('item-index'));
const is_whole = me.items_data[item_index] && me.items_data[item_index].must_be_whole_number;
$(this).find('.row-qty-input')
- .on('keydown', function(e) { me._handle_qty_keydown(e, is_whole); });
+ .on('keydown', function(e) {
+ // Enter в qty — добавить в корзину, не пропускать дальше
+ if (e.key === 'Enter' && !e.ctrlKey) {
+ e.preventDefault();
+ e.stopPropagation();
+ const qty_val = parseFloat(($(this).val() || '').replace(',', '.')) || 1;
+ if (me.items_data[item_index]) {
+ me.add_to_cart(me.items_data[item_index], qty_val);
+ }
+ return;
+ }
+ // Ctrl+Enter пропускаем вверх — _handle_keydown вызовет finalize_selection
+ if (e.key === 'Enter' && e.ctrlKey) return;
+ me._handle_qty_keydown(e, is_whole);
+ });
});
// Tooltip остатков по складам
@@ -1315,27 +1359,15 @@ class SelectionDialog {
}
_handle_qty_keydown(e, is_whole) {
- // Останавливаем всплытие — иначе dialog._handle_keydown перехватит стрелки и Enter
+ // ArrowUp/Down пропускаем наверх — _handle_keydown обработает навигацию по строкам
+ if (e.key === 'ArrowUp' || e.key === 'ArrowDown') return;
+
+ // Останавливаем всплытие для всех остальных клавиш
e.stopPropagation();
// Разрешаем управляющие комбинации (Ctrl+A, Ctrl+C, Ctrl+V и т.п.)
if (e.ctrlKey || e.metaKey) return;
- // Стрелки вверх/вниз — шаг +1/-1
- if (e.key === 'ArrowUp') {
- e.preventDefault();
- const current = parseFloat(e.target.value.replace(',', '.')) || 0;
- e.target.value = current + 1;
- return;
- }
- if (e.key === 'ArrowDown') {
- e.preventDefault();
- const current = parseFloat(e.target.value.replace(',', '.')) || 0;
- const min_val = is_whole ? 1 : 0.001;
- e.target.value = Math.max(min_val, current - 1);
- return;
- }
-
// Всегда разрешаем служебные клавиши
const control_keys = [
'Backspace', 'Delete', 'Tab', 'Escape',