Rework of workflow, added the dock back. This is now the beginning of the SKU mismatch issues. FKN FUN TIMES AHEAD

This commit is contained in:
2026-09-04 12:09:49 -05:00
parent a1b438a61f
commit 52bd6f5da2
8 changed files with 395 additions and 68 deletions
+111 -42
View File
@@ -12,6 +12,8 @@ here is purely a label-generation step for JIRA tickets.
"""
from __future__ import annotations
import webbrowser
from PyQt6.QtGui import QAction
from PyQt6.QtWidgets import (
QMainWindow,
@@ -26,6 +28,7 @@ from PyQt6.QtWidgets import (
QDialog,
)
from app.external_links import jira_ticket_url, google_maps_search_url
from app.return_labels import is_emailed_label_order
from app.services import SERVICE_REGISTRY
from app.services.odoo_export import export_orders_to_csv
@@ -91,62 +94,92 @@ class MainWindow(QMainWindow):
self.setCentralWidget(central)
toolbar = QToolBar("Main")
toolbar.setMovable(False)
self.addToolBar(toolbar)
menu_bar = self.menuBar()
file_menu = menu_bar.addMenu("&File")
settings_action = QAction("Settings...", self)
settings_action.triggered.connect(self._on_settings_clicked)
file_menu.addAction(settings_action)
file_menu.addSeparator()
exit_action = QAction("Exit", self)
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
data_menu = menu_bar.addMenu("&Data")
jira_action = QAction("Import from JIRA", self)
jira_action.triggered.connect(lambda: self._on_import_clicked("jira"))
toolbar.addAction(jira_action)
data_menu.addAction(jira_action)
self._import_actions["jira"] = jira_action
shipstation_action = QAction("Pull Tracking Numbers (ShipStation)", self)
shipstation_action.triggered.connect(lambda: self._on_import_clicked("shipstation"))
toolbar.addAction(shipstation_action)
data_menu.addAction(shipstation_action)
self._import_actions["shipstation"] = shipstation_action
toolbar.addSeparator()
export_action = QAction("Export Visible Orders to Odoo CSV", self)
export_action.setToolTip("Exports from whichever tab is currently open")
export_action.triggered.connect(self._on_export_clicked)
toolbar.addAction(export_action)
self._pack_ticket_action = QAction("Pack Ticket", self)
self._pack_ticket_action.setToolTip(
"Enter serial numbers and mark packed - select a ticket first"
)
self._pack_ticket_action.triggered.connect(self._on_pack_ticket_clicked)
toolbar.addAction(self._pack_ticket_action)
toolbar.addSeparator()
emergency_action = QAction("Send to ShipStation", self)
emergency_action.setToolTip("Select a ticket in Active Orders first")
emergency_action.triggered.connect(self._on_emergency_send_clicked)
toolbar.addAction(emergency_action)
self._return_label_action = QAction("Create Return Label", self)
self._return_label_action.setToolTip(
"For emailed-return-label tickets (SH007/OK012) - select one in Active Orders first"
)
self._return_label_action.triggered.connect(self._on_create_return_label_clicked)
toolbar.addAction(self._return_label_action)
toolbar.addSeparator()
settings_action = QAction("Settings", self)
settings_action.triggered.connect(self._on_settings_clicked)
toolbar.addAction(settings_action)
data_menu.addSeparator()
refresh_action = QAction("Refresh from Local DB", self)
refresh_action.triggered.connect(self._refresh_everything)
toolbar.addAction(refresh_action)
data_menu.addAction(refresh_action)
reset_action = QAction("Reset Local Database", self)
reset_action.setToolTip("Wipes the local cache - re-import from JIRA afterward")
export_action = QAction("Export Visible Orders to Odoo CSV...", self)
export_action.setStatusTip("Exports from whichever tab is currently open")
export_action.triggered.connect(self._on_export_clicked)
data_menu.addAction(export_action)
data_menu.addSeparator()
reset_action = QAction("Reset Local Database...", self)
reset_action.setStatusTip("Wipes the local cache - re-import from JIRA afterward")
reset_action.triggered.connect(self._on_reset_database_clicked)
toolbar.addAction(reset_action)
data_menu.addAction(reset_action)
orders_menu = menu_bar.addMenu("&Orders")
self._pack_ticket_action = QAction("Pack Ticket", self)
self._pack_ticket_action.setStatusTip(
"Enter serial numbers and mark packed - select a ticket first"
)
self._pack_ticket_action.triggered.connect(self._on_pack_ticket_clicked)
orders_menu.addAction(self._pack_ticket_action)
emergency_action = QAction("Send to ShipStation", self)
emergency_action.setStatusTip("Select a ticket in Active Orders first")
emergency_action.triggered.connect(self._on_emergency_send_clicked)
orders_menu.addAction(emergency_action)
self._return_label_action = QAction("Create Return Label", self)
self._return_label_action.setStatusTip(
"For emailed-return-label tickets (SH007/OK012) - select one in Active Orders first"
)
self._return_label_action.triggered.connect(self._on_create_return_label_clicked)
orders_menu.addAction(self._return_label_action)
orders_menu.addSeparator()
view_jira_action = QAction("View in JIRA", self)
view_jira_action.setStatusTip("Opens the selected ticket in JIRA")
view_jira_action.triggered.connect(self._on_view_in_jira_clicked)
orders_menu.addAction(view_jira_action)
lookup_address_action = QAction("Look Up Address on Google Maps", self)
lookup_address_action.setStatusTip(
"Opens the selected ticket's shipping address in Google Maps"
)
lookup_address_action.triggered.connect(self._on_lookup_address_clicked)
orders_menu.addAction(lookup_address_action)
# Quick-access toolbar for the highest-frequency actions - everything
# here is also in the menus above (same QAction objects, so there's
# nothing to keep in sync); this is just a shortcut for the few used
# constantly enough to want one click instead of a menu dropdown.
quick_toolbar = QToolBar("Quick Actions")
quick_toolbar.setMovable(False)
self.addToolBar(quick_toolbar)
quick_toolbar.addAction(self._import_actions["jira"])
quick_toolbar.addAction(self._pack_ticket_action)
quick_toolbar.addAction(self._return_label_action)
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
@@ -481,6 +514,42 @@ class MainWindow(QMainWindow):
self._refresh_everything()
self.status_label.setText(f"Saved pack data for {ticket_number}.")
def _currently_selected_order(self):
"""Unlike orders_table.selected_order() (Active Orders specifically),
this checks whichever tab is actually showing - View in JIRA and
Look Up Address are read-only lookups that make just as much sense
for a Cancelled or Done ticket as an Active one."""
current_widget = self.tabs.currentWidget()
if isinstance(current_widget, OrdersTableView):
return current_widget.selected_order()
return None
def _on_view_in_jira_clicked(self) -> None:
order = self._currently_selected_order()
if order is None:
QMessageBox.information(self, "No ticket selected", "Select a ticket first.")
return
url = jira_ticket_url(order.ticket_number)
if url is None:
QMessageBox.warning(
self,
"JIRA URL not set",
"Add your JIRA URL in Settings first (or this ticket has no ticket number).",
)
return
webbrowser.open(url)
def _on_lookup_address_clicked(self) -> None:
order = self._currently_selected_order()
if order is None:
QMessageBox.information(self, "No ticket selected", "Select a ticket first.")
return
url = google_maps_search_url(order.shipping_info)
if url is None:
QMessageBox.information(self, "No address", "This ticket has no address on file.")
return
webbrowser.open(url)
def _on_reset_database_clicked(self) -> None:
confirm = QMessageBox.warning(
self,