fix(plating): UAT-caught UX annoyances + lurking bugs

Five fixes from the end-to-end UAT debrief:

1. Menu discoverability (HIGH)
   Added a prominent "+ New Direct Order" button in the Sale Orders
   list header toolbar (class=btn-primary, display=always). The
   existing menuitem at Plating > Sales > New Direct Order was
   buried in a submenu that didn't always expand; the toolbar
   button is a guaranteed entry point from the most common screen.

2. Escape/X destroys wizard state (HIGH)
   Added a prominent info banner at the top of the wizard form:
   "Changes are not saved until you click Create & Confirm Order.
   Closing this window (Esc or X) discards your entries." The
   Cancel button now has confirm="Discard this order? All header
   data and line items will be lost." so the intentional-cancel
   path also prompts.

3. Shell/cron crash in _fp_auto_create_mo (MEDIUM)
   bridge_mrp/models/sale_order.py:232-264 used _() inside list
   comprehensions to format the internal chatter summary of newly
   created / adopted MOs. _() resolves language from env.context,
   which is empty in odoo-shell and cron contexts — triggering a
   translate.get_text_alias crash AFTER the MOs had been created.
   These strings are internal audit log text, not user-facing UI;
   dropped the _() wrappers so the message builds safely from any
   context. Same for the per-group error-message on savepoint
   rollback.

4. Misleading "100%" margin (MEDIUM)
   x_fc_margin_percent displayed 100% on every SO because the cost
   rollup from fp.coating.config.unit_cost isn't populated yet.
   Added x_fc_margin_available Boolean (True only when at least
   one line's coating has a non-zero unit_cost). The SO Plating
   tab now hides the margin numbers when margin_available=False
   and shows an inline muted note: "Margin n/a — coating cost
   rollup not yet populated on any line's treatment."

5. Account Hold banner too loud (LOW)
   fusion_plating_invoicing was injecting a full-height danger
   alert above every SO header. Slimmed it to a one-line compact
   alert with icon: "Account Hold — SO confirmation, invoicing
   and shipping are blocked for non-managers." Half the vertical
   footprint, less visual competition with the Plating chip bar.

Verified via UAT on S00071.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-20 01:03:26 -04:00
parent 068a654c2b
commit bee5ba4d3f
5 changed files with 73 additions and 25 deletions

View File

@@ -229,35 +229,38 @@ class SaleOrder(models.Model):
self.env.cr.execute('RELEASE SAVEPOINT %s' % savepoint_name)
except Exception as exc:
self.env.cr.execute('ROLLBACK TO SAVEPOINT %s' % savepoint_name)
self.message_post(body=_(
self.message_post(body=(
'Auto-MO group %s failed: %s'
) % (tag or 'single-line', exc))
continue
if created or adopted:
# _() needs a lang in env.context; in shell/cron this may be
# unset. Compose the message with plain format strings — this
# text is an internal chatter log, not user-facing UI.
msg_parts = []
if created:
lines_html = '<br/>'.join([
_('MO <a href="/odoo/manufacturing/%s">%s</a> '
'(%s, %d source line%s)') % (
mo.id, mo.name, tag or 'untagged',
n, 's' if n != 1 else ''
)
'MO <a href="/odoo/manufacturing/%s">%s</a> '
'(%s, %d source line%s)' % (
mo.id, mo.name, tag or 'untagged',
n, 's' if n != 1 else ''
)
for mo, tag, n in created
])
msg_parts.append(
_('%d draft MO(s) auto-created:<br/>%s') % (
'%d draft MO(s) auto-created:<br/>%s' % (
len(created), lines_html,
)
)
if adopted:
adopted_html = '<br/>'.join([
_('MO <a href="/odoo/manufacturing/%s">%s</a> '
'(legacy, now line-linked)') % (mo.id, mo.name)
'MO <a href="/odoo/manufacturing/%s">%s</a> '
'(legacy, now line-linked)' % (mo.id, mo.name)
for mo in adopted
])
msg_parts.append(
_('%d legacy MO(s) adopted:<br/>%s') % (
'%d legacy MO(s) adopted:<br/>%s' % (
len(adopted), adopted_html,
)
)