EMailed label return generation (alpha)
This commit is contained in:
@@ -25,6 +25,7 @@ from PyQt6.QtWidgets import (
|
||||
QFileDialog,
|
||||
)
|
||||
|
||||
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
|
||||
from app.services.shipstation_send import export_order_to_shipstation_csv
|
||||
@@ -33,9 +34,11 @@ from app.ui.settings_dialog import SettingsDialog
|
||||
from app.ui.widgets.orders_table import OrdersTableView
|
||||
from app.ui.widgets.dashboard import DashboardWidget
|
||||
from app.ui.widgets.order_detail_dialog import OrderDetailDialog
|
||||
from app.ui.widgets.return_label_dialog import ReturnLabelDialog
|
||||
from app.workers import (
|
||||
FetchOrdersWorker,
|
||||
SendToShipStationWorker,
|
||||
CreateReturnLabelWorker,
|
||||
load_orders_by_view,
|
||||
get_dashboard_stats,
|
||||
mark_shipstation_sent,
|
||||
@@ -52,6 +55,7 @@ class MainWindow(QMainWindow):
|
||||
self._workers: dict[str, FetchOrdersWorker] = {}
|
||||
self._import_actions: dict[str, QAction] = {}
|
||||
self._send_worker: SendToShipStationWorker | None = None
|
||||
self._return_label_worker: CreateReturnLabelWorker | None = None
|
||||
|
||||
self._build_ui()
|
||||
self._refresh_everything()
|
||||
@@ -106,6 +110,13 @@ class MainWindow(QMainWindow):
|
||||
emergency_action.triggered.connect(self._on_emergency_send_clicked)
|
||||
toolbar.addAction(emergency_action)
|
||||
|
||||
return_label_action = QAction("Create Return Label", self)
|
||||
return_label_action.setToolTip(
|
||||
"For emailed-return-label tickets (SH007/OK012) - select one in Active Orders first"
|
||||
)
|
||||
return_label_action.triggered.connect(self._on_create_return_label_clicked)
|
||||
toolbar.addAction(return_label_action)
|
||||
|
||||
toolbar.addSeparator()
|
||||
|
||||
settings_action = QAction("Settings", self)
|
||||
@@ -339,6 +350,66 @@ class MainWindow(QMainWindow):
|
||||
"Upload this into ShipStation's Import Orders wizard.",
|
||||
)
|
||||
|
||||
def _on_create_return_label_clicked(self) -> None:
|
||||
order = self.orders_table.selected_order()
|
||||
if order is None:
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"No ticket selected",
|
||||
"Select a ticket in Active Orders first, then click Create Return Label.",
|
||||
)
|
||||
return
|
||||
|
||||
if not is_emailed_label_order(order.skus or []):
|
||||
proceed = QMessageBox.question(
|
||||
self,
|
||||
"Not a return-label ticket",
|
||||
f"This ticket's SKU(s) ({', '.join(order.skus or []) or 'none'}) don't match "
|
||||
"the configured emailed-label SKUs. Continue anyway?",
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
)
|
||||
if proceed != QMessageBox.StandardButton.Yes:
|
||||
return
|
||||
|
||||
dialog = ReturnLabelDialog(order, self)
|
||||
if dialog.exec() != QDialog.DialogCode.Accepted:
|
||||
return
|
||||
|
||||
packages = dialog.get_packages()
|
||||
charge_event = dialog.get_charge_event()
|
||||
if not packages:
|
||||
QMessageBox.warning(self, "No packages", "Add at least one package first.")
|
||||
return
|
||||
|
||||
ticket_number = order.ticket_number or order.external_id
|
||||
self.status_label.setText(f"Creating return label for {ticket_number}...")
|
||||
|
||||
worker = CreateReturnLabelWorker(order, packages, charge_event)
|
||||
worker.finished_ok.connect(lambda result: self._on_return_label_ok(ticket_number, result))
|
||||
worker.failed.connect(self._on_return_label_failed)
|
||||
self._return_label_worker = worker # keep a reference so it isn't garbage collected
|
||||
worker.start()
|
||||
|
||||
def _on_return_label_ok(self, ticket_number: str, result: dict) -> None:
|
||||
mark_shipstation_sent(ticket_number)
|
||||
self._refresh_everything()
|
||||
label_id = result.get("label_id", "?")
|
||||
tracking = result.get("tracking_number", "?")
|
||||
self.status_label.setText(f"Return label created - {label_id}")
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"Return Label Created",
|
||||
f"Label {label_id} created (tracking {tracking}).\n\n"
|
||||
"Next: go to ShipStation's Returns tab, find this label, and use "
|
||||
"Other Actions -> Send Return Label to email it to the customer through "
|
||||
"your branded template.",
|
||||
)
|
||||
|
||||
def _on_return_label_failed(self, message: str) -> None:
|
||||
self.status_label.setText("Return label creation failed.")
|
||||
QMessageBox.critical(self, "Return label creation failed", message)
|
||||
|
||||
def _on_reset_database_clicked(self) -> None:
|
||||
confirm = QMessageBox.warning(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user