diff --git a/fusion_shipping/__manifest__.py b/fusion_shipping/__manifest__.py index f128c2c6..a521e739 100644 --- a/fusion_shipping/__manifest__.py +++ b/fusion_shipping/__manifest__.py @@ -1,6 +1,6 @@ { "name": "Fusion Shipping", - "version": "19.0.1.6.0", + "version": "19.0.1.7.0", "category": "Inventory/Delivery", "summary": "All-in-one shipping integration — Canada Post, UPS, FedEx, DHL Express. " "Live pricing, label generation, shipment tracking, and multi-package support.", diff --git a/fusion_shipping/models/stock_picking.py b/fusion_shipping/models/stock_picking.py index 11ca46f5..cf338752 100644 --- a/fusion_shipping/models/stock_picking.py +++ b/fusion_shipping/models/stock_picking.py @@ -1,4 +1,4 @@ -from odoo import models, fields +from odoo import models, fields, api, _ class StockPicking(models.Model): @@ -8,6 +8,20 @@ class StockPicking(models.Model): string='Shipments', compute='_compute_fusion_shipment_count', ) + fusion_shipping_label_attachment_id = fields.Many2one( + 'ir.attachment', + string='Shipping Label', + compute='_compute_fusion_shipping_docs', + help='Most recent shipping label generated for this delivery ' + '(any carrier).', + ) + fusion_commercial_invoice_attachment_id = fields.Many2one( + 'ir.attachment', + string='Commercial Invoice', + compute='_compute_fusion_shipping_docs', + help='Most recent commercial (customs) invoice generated for this ' + 'delivery (any carrier).', + ) def _compute_fusion_shipment_count(self): Shipment = self.env['fusion.shipment'] @@ -16,6 +30,68 @@ class StockPicking(models.Model): [('picking_id', '=', picking.id)] ) + @api.depends('message_ids.attachment_ids') + def _compute_fusion_shipping_docs(self): + """Find the latest shipping label + commercial invoice that the + carrier posted to this delivery's chatter, so they can be opened + from a smart button. + + Naming is carrier-agnostic (see the carriers' send_shipping): + - labels contain 'Label' (Label-, LabelUPS, LabelShipping-...) + - invoices contain 'CommercialInvoice' (UPS/Canada Post) or start + with 'ShippingDoc-' (FedEx/DHL, via _get_delivery_doc_prefix). + """ + Attachment = self.env['ir.attachment'] + for picking in self: + invoice = label = Attachment + if isinstance(picking.id, int): + atts = Attachment.search( + [('res_model', '=', 'stock.picking'), + ('res_id', '=', picking.id)], + order='id desc') + for att in atts: + name = att.name or '' + norm = name.lower().replace(' ', '').replace('-', '') + if 'commercialinvoice' in norm or name.startswith('ShippingDoc'): + invoice = invoice or att + elif 'label' in name.lower() and 'return' not in name.lower(): + label = label or att + if invoice and label: + break + picking.fusion_commercial_invoice_attachment_id = invoice.id + picking.fusion_shipping_label_attachment_id = label.id + + def _fusion_open_attachment(self, attachment): + """Open a shipping document for the operator. + + Routes PDFs through ir.attachment.action_fusion_preview (preview + dialog) when fusion_pdf_preview is installed, else opens the file + in a new tab. Mirrors fusion.shipment._action_open_attachment. + See CLAUDE.md "PDF Preview". + """ + self.ensure_one() + if not attachment: + return False + if hasattr(attachment, 'action_fusion_preview'): + return attachment.action_fusion_preview( + title=attachment.name or _('Shipping Document'), + model_name=self._name, + record_ids=self.id, + ) + return { + 'type': 'ir.actions.act_url', + 'url': '/web/content/%s?download=false' % attachment.id, + 'target': 'new', + } + + def action_view_fusion_shipping_label(self): + return self._fusion_open_attachment( + self.fusion_shipping_label_attachment_id) + + def action_view_fusion_commercial_invoice(self): + return self._fusion_open_attachment( + self.fusion_commercial_invoice_attachment_id) + def action_view_fusion_shipments(self): self.ensure_one() shipments = self.env['fusion.shipment'].search( diff --git a/fusion_shipping/views/stock_picking_views.xml b/fusion_shipping/views/stock_picking_views.xml index eb9f1739..9092e874 100644 --- a/fusion_shipping/views/stock_picking_views.xml +++ b/fusion_shipping/views/stock_picking_views.xml @@ -6,12 +6,28 @@ + + + +