This commit is contained in:
gsinghpal
2026-05-18 22:33:23 -04:00
parent 25f568f225
commit 091f98e1f9
76 changed files with 4521 additions and 220 deletions

View File

@@ -15,3 +15,4 @@ from . import account_payment
# fires from fp.job.button_mark_done -> _fp_fire_notification('job_complete').
# from . import mrp_production
from . import fp_delivery
from . import fusion_shipment

View File

@@ -16,6 +16,7 @@ TRIGGER_EVENTS = [
('mo_complete', 'Manufacturing Complete'), # legacy, fired by mrp; kept for back-compat
('job_confirmed', 'Plating Job Confirmed'), # Sub 11 — fp.job lifecycle
('job_complete', 'Plating Job Complete'), # Sub 11 — fp.job.button_mark_done
('shipment_labeled', 'Shipping Label Generated'), # Phase C — fired when tracking_number lands on fusion.shipment
('shipped', 'Shipped / Delivered'),
('invoice_posted', 'Invoice Posted'),
('payment_received', 'Payment Received'),
@@ -36,6 +37,7 @@ FP_TRIGGER_STREAM = {
'mo_complete': 'qc',
'job_confirmed': 'qc',
'job_complete': 'qc',
'shipment_labeled': 'certs',
'shipped': 'certs',
'invoice_posted': 'invoices',
'payment_received': 'invoices',

View File

@@ -0,0 +1,52 @@
# -*- 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