""" Part number search screen for the AUTOPARTES console application. Prompts the user for a part number (OEM, aftermarket, or cross-reference) and displays matching results in a table. Selecting a result navigates to the part detail screen. """ from console.core.screens import Screen from console.core.keybindings import Key from console.config import APP_NAME, VERSION from console.utils.formatting import truncate # Match type labels in Spanish _TYPE_LABELS = { "oem": "OEM", "aftermarket": "Aftermarket", "cross_reference": "X-Ref", } # Footer labels _FOOTER_INPUT = [ ("ENTER", "Buscar"), ("ESC", "Atras"), ] _FOOTER_RESULTS = [ ("1-9", "Ver parte"), ("ENTER", "Ver parte"), ("F3", "Nueva busqueda"), ("ESC", "Atras"), ] class BuscarParteScreen(Screen): """Search by part number (OEM, aftermarket, cross-reference).""" def __init__(self): super().__init__(name="buscar_parte", title="Buscar por Numero de Parte") self._results = None self._search_term = None self._selected = 0 self._needs_input = True # ------------------------------------------------------------------ # Render # ------------------------------------------------------------------ def render(self, context, db, renderer): # Header renderer.draw_header( f" {APP_NAME} v{VERSION}", " BUSCAR POR NUMERO DE PARTE ", ) if self._needs_input: # Show the input dialog (handled in on_key via on_enter-like flow) # Just draw footer; the input dialog will overlay renderer.draw_footer(_FOOTER_INPUT) return if self._results is None: renderer.draw_text(5, 4, "Presione F3 para buscar", "info") renderer.draw_footer(_FOOTER_RESULTS) return if not self._results: renderer.draw_text( 5, 4, f'No se encontraron resultados para "{self._search_term}"', "info", ) renderer.draw_footer(_FOOTER_RESULTS) return # Display results table headers = ["TIPO", "NUMERO", "DESCRIPCION", "FUENTE"] widths = [12, 20, 30, 20] rows = [] for r in self._results: rows.append(( _TYPE_LABELS.get(r.get("match_type", ""), r.get("match_type", "")), truncate(r.get("matched_number", ""), 20), truncate(r.get("name_es") or r.get("name", ""), 30), truncate(r.get("oem_part_number", ""), 20), )) renderer.draw_table( headers, rows, widths, selected_row=self._selected, ) renderer.draw_footer(_FOOTER_RESULTS) # ------------------------------------------------------------------ # Key handling # ------------------------------------------------------------------ def on_key(self, key, context, db, renderer, nav): # If we need input, show the input dialog if self._needs_input: self._needs_input = False value = renderer.show_input("Numero de parte", max_len=30) if value is None: # User pressed ESC in input dialog if self._results is not None: # Go back to results view return None return "back" if value.strip(): self._search_term = value.strip() self._results = db.search_part_number(self._search_term) self._selected = 0 return None # ESC: go back if key == Key.ESCAPE: return "back" # F3: new search if key == Key.F3: self._needs_input = True return None # Arrow navigation if key == Key.UP: if self._selected > 0: self._selected -= 1 return None if key == Key.DOWN: if self._results and self._selected < len(self._results) - 1: self._selected += 1 return None # ENTER: view selected part if key == Key.ENTER: if self._results and 0 <= self._selected < len(self._results): part = self._results[self._selected] return ("parte_detalle", {"part_id": part["id"]}, "Parte") return None # Number keys: direct selection (1-9) if 49 <= key <= 57: # '1'..'9' idx = key - 49 # 0-based if self._results and 0 <= idx < len(self._results): part = self._results[idx] return ("parte_detalle", {"part_id": part["id"]}, "Parte") return None return None