feat(portal): redirect 3 legacy URLs to consolidated homes (Sub-A IA)
- /my/fp_invoices -> /my/account_summary - /my/purchase_orders -> /my/orders (Odoo default) - /my/quote_requests/new (GET) -> /my/configurator/new (POST handler preserved for back-compat with the existing RFQ form button; will be removed after the form is fully retired) Thin templates deleted: portal_my_fp_invoices, portal_my_purchase_orders. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -667,44 +667,12 @@ class FpCustomerPortal(CustomerPortal):
|
||||
# ==========================================================================
|
||||
@http.route(
|
||||
['/my/quote_requests/new'],
|
||||
type='http',
|
||||
auth='user',
|
||||
website=True,
|
||||
type='http', auth='user', website=True,
|
||||
methods=['GET'],
|
||||
)
|
||||
def portal_new_quote_request(self, **kw):
|
||||
partner = request.env.user.partner_id
|
||||
commercial = partner.commercial_partner_id
|
||||
|
||||
process_types = request.env['fusion.plating.process.type'].sudo().search(
|
||||
[('active', '=', True)]
|
||||
)
|
||||
|
||||
# Shipping addresses: child contacts of type 'delivery' or 'other'
|
||||
addresses = request.env['res.partner'].sudo().search([
|
||||
('parent_id', '=', commercial.id),
|
||||
('type', 'in', ['delivery', 'other', 'contact']),
|
||||
])
|
||||
|
||||
# Products available for this customer (all saleable products)
|
||||
products = request.env['product.product'].sudo().search([
|
||||
('sale_ok', '=', True),
|
||||
('active', '=', True),
|
||||
], limit=200, order='default_code, name')
|
||||
|
||||
values = {
|
||||
'page_name': 'fp_quote_request_new',
|
||||
'process_types': process_types,
|
||||
'partner': partner,
|
||||
'commercial': commercial,
|
||||
'addresses': addresses,
|
||||
'products': products,
|
||||
'error': kw.get('error'),
|
||||
'form_data': kw,
|
||||
}
|
||||
return request.render(
|
||||
'fusion_plating_portal.portal_new_quote_request_form',
|
||||
values,
|
||||
)
|
||||
"""GET — legacy entry point, redirected to the configurator wizard."""
|
||||
return request.redirect('/my/configurator/new')
|
||||
|
||||
# ==========================================================================
|
||||
# QUOTE REQUESTS -- submit (enhanced for multi-part)
|
||||
@@ -1114,112 +1082,22 @@ class FpCustomerPortal(CustomerPortal):
|
||||
# ==========================================================================
|
||||
@http.route(
|
||||
['/my/purchase_orders', '/my/purchase_orders/page/<int:page>'],
|
||||
type='http',
|
||||
auth='user',
|
||||
website=True,
|
||||
type='http', auth='user', website=True,
|
||||
)
|
||||
def portal_my_purchase_orders(self, page=1, sortby=None, **kw):
|
||||
partner = request.env.user.partner_id
|
||||
commercial = partner.commercial_partner_id
|
||||
SO = request.env['sale.order'].sudo()
|
||||
domain = [
|
||||
('partner_id', 'child_of', commercial.id),
|
||||
('state', '=', 'sale'),
|
||||
]
|
||||
|
||||
searchbar_sortings = {
|
||||
'date': {'label': _('Newest'), 'order': 'date_order desc'},
|
||||
'name': {'label': _('Reference'), 'order': 'name desc'},
|
||||
'amount': {'label': _('Amount'), 'order': 'amount_total desc'},
|
||||
}
|
||||
if not sortby:
|
||||
sortby = 'date'
|
||||
order = searchbar_sortings[sortby]['order']
|
||||
|
||||
total = SO.search_count(domain)
|
||||
pager = portal_pager(
|
||||
url='/my/purchase_orders',
|
||||
url_args={'sortby': sortby},
|
||||
total=total,
|
||||
page=page,
|
||||
step=self._items_per_page,
|
||||
)
|
||||
orders = SO.search(
|
||||
domain,
|
||||
order=order,
|
||||
limit=self._items_per_page,
|
||||
offset=pager['offset'],
|
||||
)
|
||||
|
||||
values = {
|
||||
'orders': orders,
|
||||
'page_name': 'fp_purchase_orders',
|
||||
'pager': pager,
|
||||
'default_url': '/my/purchase_orders',
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'sortby': sortby,
|
||||
}
|
||||
return request.render(
|
||||
'fusion_plating_portal.portal_my_purchase_orders',
|
||||
values,
|
||||
)
|
||||
def portal_my_purchase_orders(self, **kw):
|
||||
"""Legacy URL — redirected to Odoo default /my/orders (Sub-A IA)."""
|
||||
return request.redirect('/my/orders')
|
||||
|
||||
# ==========================================================================
|
||||
# INVOICES -- list
|
||||
# ==========================================================================
|
||||
@http.route(
|
||||
['/my/fp_invoices', '/my/fp_invoices/page/<int:page>'],
|
||||
type='http',
|
||||
auth='user',
|
||||
website=True,
|
||||
type='http', auth='user', website=True,
|
||||
)
|
||||
def portal_my_fp_invoices(self, page=1, sortby=None, **kw):
|
||||
partner = request.env.user.partner_id
|
||||
commercial = partner.commercial_partner_id
|
||||
Invoice = request.env['account.move'].sudo()
|
||||
domain = [
|
||||
('partner_id', 'child_of', commercial.id),
|
||||
('move_type', '=', 'out_invoice'),
|
||||
('state', '=', 'posted'),
|
||||
]
|
||||
|
||||
searchbar_sortings = {
|
||||
'date': {'label': _('Newest'), 'order': 'invoice_date desc'},
|
||||
'name': {'label': _('Reference'), 'order': 'name desc'},
|
||||
'amount': {'label': _('Amount'), 'order': 'amount_total desc'},
|
||||
'due': {'label': _('Due Date'), 'order': 'invoice_date_due asc'},
|
||||
}
|
||||
if not sortby:
|
||||
sortby = 'date'
|
||||
order = searchbar_sortings[sortby]['order']
|
||||
|
||||
total = Invoice.search_count(domain)
|
||||
pager = portal_pager(
|
||||
url='/my/fp_invoices',
|
||||
url_args={'sortby': sortby},
|
||||
total=total,
|
||||
page=page,
|
||||
step=self._items_per_page,
|
||||
)
|
||||
invoices = Invoice.search(
|
||||
domain,
|
||||
order=order,
|
||||
limit=self._items_per_page,
|
||||
offset=pager['offset'],
|
||||
)
|
||||
|
||||
values = {
|
||||
'invoices': invoices,
|
||||
'page_name': 'fp_invoices',
|
||||
'pager': pager,
|
||||
'default_url': '/my/fp_invoices',
|
||||
'searchbar_sortings': searchbar_sortings,
|
||||
'sortby': sortby,
|
||||
}
|
||||
return request.render(
|
||||
'fusion_plating_portal.portal_my_fp_invoices',
|
||||
values,
|
||||
)
|
||||
def portal_my_fp_invoices(self, **kw):
|
||||
"""Legacy URL — redirected to /my/account_summary (Sub-A IA)."""
|
||||
return request.redirect('/my/account_summary')
|
||||
|
||||
# ==========================================================================
|
||||
# SHIPPING / DELIVERIES -- list
|
||||
|
||||
@@ -575,98 +575,6 @@
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- PURCHASE ORDERS — list -->
|
||||
<!-- ================================================================== -->
|
||||
<template id="portal_my_purchase_orders" name="My Purchase Orders">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Purchase Orders</t>
|
||||
</t>
|
||||
|
||||
<t t-if="not orders">
|
||||
<div class="o_fp_portal_card card bg-body-tertiary border-0 p-4 text-center">
|
||||
<p class="text-muted mb-0">No purchase orders found.</p>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="orders" t-call="portal.portal_table">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<th>Order</th>
|
||||
<th>Date</th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="orders" t-as="order">
|
||||
<td t-out="order.name"/>
|
||||
<td>
|
||||
<span t-field="order.date_order" t-options='{"widget": "date"}'/>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span t-field="order.amount_total"
|
||||
t-options='{"widget": "monetary", "display_currency": order.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- INVOICES — list -->
|
||||
<!-- ================================================================== -->
|
||||
<template id="portal_my_fp_invoices" name="My Invoices">
|
||||
<t t-call="portal.portal_layout">
|
||||
<t t-set="breadcrumbs_searchbar" t-value="True"/>
|
||||
<t t-call="portal.portal_searchbar">
|
||||
<t t-set="title">Invoices</t>
|
||||
</t>
|
||||
|
||||
<t t-if="not invoices">
|
||||
<div class="o_fp_portal_card card bg-body-tertiary border-0 p-4 text-center">
|
||||
<p class="text-muted mb-0">No invoices found.</p>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="invoices" t-call="portal.portal_table">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<th>Invoice</th>
|
||||
<th>Date</th>
|
||||
<th>Due Date</th>
|
||||
<th class="text-end">Amount Due</th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="invoices" t-as="inv">
|
||||
<td t-out="inv.name"/>
|
||||
<td>
|
||||
<span t-if="inv.invoice_date"
|
||||
t-field="inv.invoice_date"
|
||||
t-options='{"widget": "date"}'/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-if="inv.invoice_date_due"
|
||||
t-field="inv.invoice_date_due"
|
||||
t-options='{"widget": "date"}'/>
|
||||
<span t-else="" class="text-muted">--</span>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span t-field="inv.amount_residual"
|
||||
t-options='{"widget": "monetary", "display_currency": inv.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span t-field="inv.amount_total"
|
||||
t-options='{"widget": "monetary", "display_currency": inv.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- DELIVERIES / PACKING SLIPS — list -->
|
||||
<!-- ================================================================== -->
|
||||
|
||||
Reference in New Issue
Block a user