feat: уточнение модели/количества для любых позиций словаря (ОС и др.)

- кнопка «✏️ Уточнить модель/кол-во» теперь всегда в окне выбора из словаря
- для позиций без маркера (Windows 10 Pro и т.п.) запрашивает количество:
  вводишь 5 → «Windows 10 Pro 5 шт.»
- для позиций с «(уточнить …)» вычищает маркер из названия и дописывает модель + количество
- формат: «Позиция Модель N шт.» (без запятой)
This commit is contained in:
2026-08-04 17:31:09 +04:00
parent 0b3aff4ae9
commit 42a243f7b6
+12 -12
View File
@@ -1991,15 +1991,11 @@ class DokoGenApp:
for var in vars.values(): for var in vars.values():
var.set(False) var.set(False)
has_refinable = any('уточн' in str(item).lower() for item in items)
def _refine_selected(): def _refine_selected():
"""Для отмеченных позиций с «(уточнить …)» запросить модель и количество.""" """Для отмеченных позиций запросить модель/версию и количество."""
for item, (var, cb) in list(items_map.items()): for item, (var, cb) in list(items_map.items()):
if not var.get(): if not var.get():
continue continue
if 'уточн' not in item.lower():
continue
new_text = self._refine_dict_item_dialog(item) new_text = self._refine_dict_item_dialog(item)
if new_text is None or new_text == item: if new_text is None or new_text == item:
continue continue
@@ -2010,7 +2006,6 @@ class DokoGenApp:
vars[new_text] = var vars[new_text] = var
items_map[new_text] = (var, cb) items_map[new_text] = (var, cb)
if has_refinable:
ttk.Button(btn_frame, text="✏️ Уточнить модель/кол-во", ttk.Button(btn_frame, text="✏️ Уточнить модель/кол-во",
command=_refine_selected).pack(side=tk.LEFT, padx=2) command=_refine_selected).pack(side=tk.LEFT, padx=2)
ttk.Button(btn_frame, text="Выбрать всё", command=_select_all).pack(side=tk.LEFT, padx=2) ttk.Button(btn_frame, text="Выбрать всё", command=_select_all).pack(side=tk.LEFT, padx=2)
@@ -2022,8 +2017,13 @@ class DokoGenApp:
def _refine_dict_item_dialog(self, base_item): def _refine_dict_item_dialog(self, base_item):
"""Окно уточнения модели и количества для позиции из словаря. """Окно уточнения модели и количества для позиции из словаря.
Возвращает полную строку вида «Сервер <модель>, <N> шт.» или None. Возвращает полную строку вида «Windows 10 Pro 5 шт.» или
«Сервер Supermicro SSG-2027R -E1R24N 2 шт.» или None.
""" """
import re
# Убираем из базы маркер «(уточнить …)»
base = re.sub(r'\s*\([^)]*уточн[^)]*\)', '', base_item, flags=re.I).strip() or base_item
dialog = tk.Toplevel(self.root) dialog = tk.Toplevel(self.root)
dialog.title("Уточнить модель и количество") dialog.title("Уточнить модель и количество")
dialog.geometry("500x180") dialog.geometry("500x180")
@@ -2033,15 +2033,15 @@ class DokoGenApp:
frame = ttk.Frame(dialog, padding=10) frame = ttk.Frame(dialog, padding=10)
frame.pack(fill=tk.BOTH, expand=True) frame.pack(fill=tk.BOTH, expand=True)
ttk.Label(frame, text=f"Позиция: {base_item}", wraplength=470, ttk.Label(frame, text=f"Позиция: {base}", wraplength=470,
font=('Arial', 9, 'bold')).pack(anchor=tk.W, pady=(0, 8)) font=('Arial', 9, 'bold')).pack(anchor=tk.W, pady=(0, 8))
ttk.Label(frame, text="Модель / версия / конфигурация:").pack(anchor=tk.W) ttk.Label(frame, text="Модель / версия / конфигурация (необязательно):").pack(anchor=tk.W)
model_entry = ttk.Entry(frame, width=60) model_entry = ttk.Entry(frame, width=60)
model_entry.pack(fill=tk.X, pady=(2, 6)) model_entry.pack(fill=tk.X, pady=(2, 6))
model_entry.focus_set() model_entry.focus_set()
ttk.Label(frame, text="Количество (необязательно):").pack(anchor=tk.W) ttk.Label(frame, text="Количество:").pack(anchor=tk.W)
count_entry = ttk.Entry(frame, width=20) count_entry = ttk.Entry(frame, width=20)
count_entry.pack(anchor=tk.W, pady=(2, 6)) count_entry.pack(anchor=tk.W, pady=(2, 6))
@@ -2050,11 +2050,11 @@ class DokoGenApp:
def _ok(): def _ok():
model = model_entry.get().strip() model = model_entry.get().strip()
count = count_entry.get().strip() count = count_entry.get().strip()
text = base_item text = base
if model: if model:
text = f"{text} {model}" text = f"{text} {model}"
if count: if count:
text = f"{text}, {count} шт." text = f"{text} {count} шт."
result['val'] = text result['val'] = text
dialog.destroy() dialog.destroy()