This commit is contained in:
gsinghpal
2026-05-10 10:25:12 -04:00
parent 6c6a59ceef
commit 6b7b44264a
59 changed files with 2461 additions and 324 deletions

View File

@@ -183,7 +183,60 @@ class FpDelivery(models.Model):
# ==========================================================================
# Actions
# ==========================================================================
def _fp_check_account_hold(self, action_label):
"""Block shipping when the customer is on account hold.
Enforces the third leg of the SO banner promise ("SO confirmation,
invoicing AND SHIPPING are blocked"). Resolved through
``commercial_partner_id`` so a hold on the parent company applies
even when the delivery is addressed to a child contact.
Manager bypass: ``fp_skip_account_hold=True`` in context (matches
the pattern used in fp_direct_order_wizard and the SO action_confirm
manager-override). Non-managers can't bypass.
``getattr`` is defensive — the hold field lives in
``fusion_plating_invoicing``; this module doesn't dep on it.
"""
for rec in self:
partner = rec.partner_id.commercial_partner_id
if not getattr(partner, 'x_fc_account_hold', False):
continue
if self.env.context.get('fp_skip_account_hold'):
rec.message_post(body=_(
'Account-hold check bypassed via context flag for '
'%(action)s. Customer "%(name)s" is on hold (reason: '
'%(reason)s).'
) % {
'action': action_label,
'name': partner.name,
'reason': getattr(partner, 'x_fc_account_hold_reason', '') or 'N/A',
})
continue
is_manager = self.env['res.partner']._fp_user_can_override_account_hold()
if not is_manager:
raise UserError(_(
'Cannot %(action)s delivery "%(name)s" — customer "%(partner)s" '
'is on account hold.\n'
'Reason: %(reason)s\n\n'
'Contact a manager to override.'
) % {
'action': action_label,
'name': rec.name or rec.display_name,
'partner': partner.name,
'reason': getattr(partner, 'x_fc_account_hold_reason', '') or 'No reason specified',
})
rec.message_post(body=_(
'Warning: Customer "%(name)s" is on account hold (reason: '
'%(reason)s). Delivery %(action)s by manager override.'
) % {
'name': partner.name,
'reason': getattr(partner, 'x_fc_account_hold_reason', '') or 'N/A',
'action': action_label,
})
def action_schedule(self):
self._fp_check_account_hold(_('schedule'))
self.write({'state': 'scheduled'})
def action_start_route(self):
@@ -194,6 +247,7 @@ class FpDelivery(models.Model):
is non-negotiable — without it the chain-of-custody hand-off
has no signed party and the POD can't be linked to a person.
"""
self._fp_check_account_hold(_('dispatch'))
for rec in self:
if not rec.assigned_driver_id:
raise UserError(_(