# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) """Phase C — fire 'shipment_labeled' notification when tracking_number lands on a fusion.shipment for the first time. Triggers regardless of how tracking got set: live API call or manual fallback wizard. Customer gets the tracking link as soon as the label is generated, not after the package physically ships (that's the existing 'shipped' event on fp.delivery).""" import logging from odoo import models _logger = logging.getLogger(__name__) class FusionShipment(models.Model): _inherit = 'fusion.shipment' def write(self, vals): # Identify shipments that gain a tracking number for the first # time. Done BEFORE super().write so we can compare before/after. will_fire = self.browse() if 'tracking_number' in vals and vals.get('tracking_number'): will_fire = self.filtered(lambda s: not s.tracking_number) res = super().write(vals) if not will_fire: return res Dispatch = self.env.get('fp.notification.template') if Dispatch is None: return res for ship in will_fire: partner = ( ship.sale_order_id.partner_id if ship.sale_order_id else False ) if not partner: continue try: Dispatch._dispatch( 'shipment_labeled', ship, partner, sale_order=ship.sale_order_id or False, ) except Exception as e: _logger.warning( 'Shipment %s: shipment_labeled dispatch failed: %s', ship.name, e, ) return res