feat(portal): rewrite /my/home as jobs-forward dashboard
Welcome strip -> 4-tile KPI row (In-Flight Jobs is the hero) -> Active Work Orders section with 3 most-recent V2 cards -> 3-panel secondary strip (Certs / Packing Slips / Invoices). Uses the new badge/stepper/doc-chip macros. Also fixes a stepper state->step mapping bug that would have shown Inspected as active when state=in_progress (should be Plating active). New state_to_idx dict handles all 6 fp.portal.job states correctly, including 'complete' (all 5 stages done). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,344 +7,187 @@
|
||||
<odoo>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- Portal Home Dashboard — 6-section grid -->
|
||||
<!-- Portal Home Dashboard — jobs-forward layout (v19.0.3.1.0 redesign) -->
|
||||
<!-- ================================================================== -->
|
||||
<template id="fp_portal_home_dashboard" name="Plating Portal Dashboard">
|
||||
<t t-call="portal.portal_layout">
|
||||
<div class="o_fp_dashboard mt-3">
|
||||
<!-- Welcome header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<h3 class="mb-1">
|
||||
|
||||
<!-- Welcome strip -->
|
||||
<div class="o_fp_welcome">
|
||||
<div>
|
||||
<div class="o_fp_welcome_title">
|
||||
Welcome back, <span t-out="partner.name"/>
|
||||
</h3>
|
||||
<p class="text-muted mb-0">
|
||||
Your plating portal dashboard — everything at a glance.
|
||||
</p>
|
||||
</div>
|
||||
<div class="o_fp_welcome_sub">
|
||||
<t t-out="active_job_count"/> active job<t t-if="active_job_count != 1">s</t>
|
||||
<t t-if="awaiting_review_count"> · <t t-out="awaiting_review_count"/> awaiting your review</t>
|
||||
<t t-if="ready_to_ship_count"> · <t t-out="ready_to_ship_count"/> ready to ship</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions bar -->
|
||||
<div class="d-flex flex-wrap gap-2 mb-4">
|
||||
<a href="/my/configurator" class="btn btn-primary">
|
||||
<i class="fa fa-cog me-1"/>Get a Quote
|
||||
</a>
|
||||
<a href="/my/quote_requests/new" class="btn btn-outline-primary">
|
||||
<i class="fa fa-plus me-1"/>Request Quote
|
||||
</a>
|
||||
<a href="/my/quote_requests" class="btn btn-outline-secondary">
|
||||
<i class="fa fa-file-text-o me-1"/>My Quotes
|
||||
</a>
|
||||
<a href="/my/jobs" class="btn btn-outline-secondary">
|
||||
<i class="fa fa-cogs me-1"/>Parts Portal
|
||||
</a>
|
||||
<a href="/my/certifications" class="btn btn-outline-secondary">
|
||||
<i class="fa fa-certificate me-1"/>Certifications
|
||||
<a href="/my/configurator" class="o_fp_btn_primary">
|
||||
<i class="fa fa-plus"/> Get a Quote
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Dashboard Grid -->
|
||||
<div class="row g-4">
|
||||
<!-- KPI tiles -->
|
||||
<div class="o_fp_kpi_row">
|
||||
<div class="o_fp_kpi_tile">
|
||||
<div class="o_fp_kpi_label">Open Quotes</div>
|
||||
<div class="o_fp_kpi_value" t-out="quote_count"/>
|
||||
<a href="/my/quote_requests" class="o_fp_kpi_hint o_fp_hint_action">View quotes →</a>
|
||||
</div>
|
||||
<div class="o_fp_kpi_tile">
|
||||
<div class="o_fp_kpi_label">Active POs</div>
|
||||
<div class="o_fp_kpi_value" t-out="po_count"/>
|
||||
<a href="/my/purchase_orders" class="o_fp_kpi_hint">View POs →</a>
|
||||
</div>
|
||||
<div class="o_fp_kpi_tile o_fp_kpi_hero">
|
||||
<div class="o_fp_kpi_label">In-Flight Jobs</div>
|
||||
<div class="o_fp_kpi_value" t-out="active_job_count"/>
|
||||
<t t-if="ready_to_ship_count">
|
||||
<div class="o_fp_kpi_hint o_fp_hint_success">
|
||||
<t t-out="ready_to_ship_count"/> ready to ship ✓
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_fp_kpi_tile">
|
||||
<div class="o_fp_kpi_label">Invoices</div>
|
||||
<div class="o_fp_kpi_value" t-out="invoice_count"/>
|
||||
<a href="/my/fp_invoices" class="o_fp_kpi_hint">View invoices →</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== QUOTES SECTION ====== -->
|
||||
<div class="col-lg-6">
|
||||
<div class="o_fp_dashboard_card card h-100">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fa fa-file-text-o me-2"/>Quotes
|
||||
<span class="badge text-bg-primary ms-2" t-out="quote_count"/>
|
||||
</h6>
|
||||
<a href="/my/quote_requests" class="btn btn-sm btn-outline-primary">View All</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<t t-if="recent_quotes">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Reference</th>
|
||||
<th>Date</th>
|
||||
<th class="text-end">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="recent_quotes" t-as="qr">
|
||||
<td>
|
||||
<a t-att-href="'/my/quote_requests/%s' % qr.id"
|
||||
t-out="qr.name"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="qr.create_date" t-options='{"widget": "date"}'/>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span t-attf-class="badge #{
|
||||
'text-bg-secondary' if qr.state == 'new' else
|
||||
'text-bg-info' if qr.state == 'under_review' else
|
||||
'text-bg-primary' if qr.state == 'quoted' else
|
||||
'text-bg-success' if qr.state == 'accepted' else
|
||||
'text-bg-danger' if qr.state == 'declined' else
|
||||
'text-bg-warning'}"
|
||||
t-out="dict(qr._fields['state']._description_selection(qr.env)).get(qr.state)"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="p-4 text-center text-muted">
|
||||
<p class="mb-2">No quotes yet.</p>
|
||||
<a href="/my/quote_requests/new" class="btn btn-sm btn-primary">
|
||||
Submit Your First RFQ
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Active jobs hero -->
|
||||
<div class="o_fp_jobs_hero">
|
||||
<div class="o_fp_section_header">
|
||||
<div class="o_fp_section_title">Active Work Orders</div>
|
||||
<a href="/my/jobs" class="o_fp_btn_ghost">All Jobs →</a>
|
||||
</div>
|
||||
|
||||
<!-- ====== PURCHASE ORDERS SECTION ====== -->
|
||||
<div class="col-lg-6">
|
||||
<div class="o_fp_dashboard_card card h-100">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fa fa-shopping-cart me-2"/>Purchase Orders
|
||||
<span class="badge text-bg-primary ms-2" t-out="po_count"/>
|
||||
</h6>
|
||||
<a href="/my/purchase_orders" class="btn btn-sm btn-outline-primary">View All</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<t t-if="recent_pos">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order</th>
|
||||
<th>Date</th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="recent_pos" t-as="po">
|
||||
<td t-out="po.name"/>
|
||||
<td>
|
||||
<span t-field="po.date_order" t-options='{"widget": "date"}'/>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span t-field="po.amount_total"
|
||||
t-options='{"widget": "monetary", "display_currency": po.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="p-4 text-center text-muted">
|
||||
No purchase orders yet.
|
||||
<t t-if="recent_jobs">
|
||||
<t t-foreach="recent_jobs[:3]" t-as="job">
|
||||
<div class="o_fp_job_card">
|
||||
<div class="o_fp_job_header">
|
||||
<div>
|
||||
<a t-att-href="'/my/jobs/%s' % job.id"
|
||||
class="o_fp_job_ref text-decoration-none"
|
||||
t-out="job.name"/>
|
||||
<span class="o_fp_job_meta">
|
||||
<t t-if="job.quantity"><t t-out="job.quantity"/> units</t>
|
||||
<t t-if="job.target_ship_date"> · ETA <span t-field="job.target_ship_date" t-options='{"widget": "date"}'/></t>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<t t-call="fusion_plating_portal.fp_portal_status_badge">
|
||||
<t t-set="state" t-value="job.state"/>
|
||||
<t t-set="label" t-value="dict(job._fields['state']._description_selection(job.env)).get(job.state)"/>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- ====== PARTS PORTAL / JOBS SECTION ====== -->
|
||||
<div class="col-lg-6">
|
||||
<div class="o_fp_dashboard_card card h-100">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fa fa-cogs me-2"/>Parts Portal
|
||||
<span class="badge text-bg-primary ms-2" t-out="job_count"/>
|
||||
</h6>
|
||||
<a href="/my/jobs" class="btn btn-sm btn-outline-primary">View All</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<t t-if="recent_jobs">
|
||||
<div class="p-3">
|
||||
<t t-foreach="recent_jobs" t-as="job">
|
||||
<div class="o_fp_dashboard_job_row mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<a t-att-href="'/my/jobs/%s' % job.id"
|
||||
class="fw-semibold text-decoration-none"
|
||||
t-out="job.name"/>
|
||||
<span t-attf-class="badge #{
|
||||
'text-bg-info' if job.state == 'received' else
|
||||
'text-bg-primary' if job.state == 'in_progress' else
|
||||
'text-bg-warning' if job.state == 'quality_check' else
|
||||
'text-bg-secondary' if job.state == 'ready_to_ship' else
|
||||
'text-bg-success'}"
|
||||
t-out="dict(job._fields['state']._description_selection(job.env)).get(job.state)"/>
|
||||
</div>
|
||||
<!-- Segmented progress bar -->
|
||||
<div class="o_fp_seg_progress d-flex" style="height: 8px; border-radius: 4px; overflow: hidden;">
|
||||
<t t-set="pct" t-value="job._progress_percent()"/>
|
||||
<!-- Receiving segment (green, 0-20%) -->
|
||||
<div t-attf-class="o_fp_seg_receiving"
|
||||
t-attf-style="width: #{min(pct, 20)}%; background-color: var(--bs-success); opacity: #{1 if pct >= 1 else 0.3};"/>
|
||||
<!-- In Progress segment (orange, 20-70%) -->
|
||||
<div t-attf-class="o_fp_seg_progress_mid"
|
||||
t-attf-style="width: #{max(0, min(pct - 20, 50))}%; background-color: var(--bs-warning); opacity: #{1 if pct > 20 else 0.3};"/>
|
||||
<!-- Shipping segment (orange-green, 70-100%) -->
|
||||
<div t-attf-class="o_fp_seg_shipping"
|
||||
t-attf-style="width: #{max(0, min(pct - 70, 30))}%; background-color: var(--bs-info); opacity: #{1 if pct > 70 else 0.3};"/>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mt-1" style="font-size: 0.7rem;">
|
||||
<span class="text-muted">Receiving</span>
|
||||
<span class="text-muted">In Progress</span>
|
||||
<span class="text-muted">Shipping</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- State -> active step index mapping.
|
||||
5 customer-visible stages: Received / Inspected / Plating / QC / Ship.
|
||||
state_idx >= 5 means all done (shipped or complete). -->
|
||||
<t t-set="state_to_idx" t-value="{'received': 0, 'in_progress': 2, 'quality_check': 3, 'ready_to_ship': 4, 'shipped': 5, 'complete': 5}"/>
|
||||
<t t-set="state_idx" t-value="state_to_idx.get(job.state, 0)"/>
|
||||
<t t-set="steps" t-value="[
|
||||
{'label': 'Received', 'status': 'done' if state_idx > 0 else 'active', 'time_label': ''},
|
||||
{'label': 'Inspected', 'status': 'done' if state_idx > 1 else ('active' if state_idx == 1 else 'pending'), 'time_label': ''},
|
||||
{'label': 'Plating', 'status': 'done' if state_idx > 2 else ('active' if state_idx == 2 else 'pending'), 'time_label': ''},
|
||||
{'label': 'QC', 'status': 'done' if state_idx > 3 else ('active' if state_idx == 3 else 'pending'), 'time_label': ''},
|
||||
{'label': 'Ship', 'status': 'done' if state_idx > 4 else ('active' if state_idx == 4 else 'pending'), 'time_label': ''},
|
||||
]"/>
|
||||
<t t-set="active_state" t-value="'warn' if job.state == 'quality_check' else 'normal'"/>
|
||||
<t t-call="fusion_plating_portal.fp_portal_stepper"/>
|
||||
|
||||
<!-- Doc chips: CoC + tracking (V1) -->
|
||||
<div class="o_fp_job_docs">
|
||||
<t t-if="job.coc_attachment_id">
|
||||
<t t-call="fusion_plating_portal.fp_portal_doc_chip">
|
||||
<t t-set="doc" t-value="{'icon': '📑', 'label': 'CoC', 'url': '/my/jobs/%s/coc' % job.id}"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="p-4 text-center text-muted">
|
||||
No active jobs.
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-call="fusion_plating_portal.fp_portal_doc_chip">
|
||||
<t t-set="doc" t-value="{'icon': '📑', 'label': 'CoC', 'pending': True}"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="job.tracking_ref">
|
||||
<span class="o_fp_doc_chip">📦 <span t-out="job.tracking_ref"/></span>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- ====== CERTIFICATIONS & QUALITY SECTION ====== -->
|
||||
<div class="col-lg-6">
|
||||
<div class="o_fp_dashboard_card card h-100">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fa fa-certificate me-2"/>Certifications & Quality
|
||||
<span class="badge text-bg-primary ms-2" t-out="cert_count"/>
|
||||
</h6>
|
||||
<a href="/my/certifications" class="btn btn-sm btn-outline-primary">View All</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<t t-if="recent_certs">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Job</th>
|
||||
<th>Ship Date</th>
|
||||
<th class="text-end">CoC</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="recent_certs" t-as="cj">
|
||||
<td>
|
||||
<a t-att-href="'/my/jobs/%s' % cj.id"
|
||||
t-out="cj.name"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-if="cj.actual_ship_date"
|
||||
t-field="cj.actual_ship_date"
|
||||
t-options='{"widget": "date"}'/>
|
||||
<span t-else="" class="text-muted">--</span>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<a t-att-href="'/my/jobs/%s/coc' % cj.id"
|
||||
class="btn btn-sm btn-outline-success">
|
||||
<i class="fa fa-download me-1"/>Download
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="p-4 text-center text-muted">
|
||||
No certificates available yet.
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="job_count > 3">
|
||||
<div class="o_fp_view_all">
|
||||
<a href="/my/jobs">View all <t t-out="job_count"/> jobs →</a>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="o_fp_card text-center text-muted">
|
||||
<p class="mb-2">No active jobs yet.</p>
|
||||
<a href="/my/configurator" class="o_fp_btn_primary o_fp_btn_sm">+ Get Your First Quote</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- ====== SHIPPING / DELIVERIES SECTION ====== -->
|
||||
<div class="col-lg-6">
|
||||
<div class="o_fp_dashboard_card card h-100">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fa fa-truck me-2"/>Shipping
|
||||
<span class="badge text-bg-primary ms-2" t-out="delivery_count"/>
|
||||
</h6>
|
||||
<a href="/my/deliveries" class="btn btn-sm btn-outline-primary">View All</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<t t-if="recent_deliveries">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Packing Slip</th>
|
||||
<th>Date</th>
|
||||
<th class="text-end">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="recent_deliveries" t-as="dlv">
|
||||
<td t-out="dlv.name"/>
|
||||
<td>
|
||||
<span t-if="dlv.date_done"
|
||||
t-field="dlv.date_done"
|
||||
t-options='{"widget": "date"}'/>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span class="badge text-bg-success">Delivered</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="p-4 text-center text-muted">
|
||||
No deliveries yet.
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<!-- Secondary panels -->
|
||||
<div class="o_fp_secondary_panels">
|
||||
<div class="o_fp_panel">
|
||||
<div class="o_fp_panel_title">
|
||||
<span class="o_fp_panel_icon">📑</span> Recent Certifications
|
||||
</div>
|
||||
<t t-if="recent_certs">
|
||||
<t t-foreach="recent_certs[:3]" t-as="cert">
|
||||
<div class="o_fp_panel_row">
|
||||
<a t-att-href="'/my/jobs/%s' % cert.id" class="text-decoration-none">
|
||||
CoC <span t-out="cert.name"/>
|
||||
</a>
|
||||
<t t-if="cert.actual_ship_date"> · <span t-field="cert.actual_ship_date" t-options='{"widget": "date"}'/></t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="o_fp_panel_row text-muted">No certifications yet.</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
<!-- ====== INVOICES SECTION ====== -->
|
||||
<div class="col-lg-6">
|
||||
<div class="o_fp_dashboard_card card h-100">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fa fa-file-text me-2"/>Invoices
|
||||
<span class="badge text-bg-primary ms-2" t-out="invoice_count"/>
|
||||
</h6>
|
||||
<a href="/my/fp_invoices" class="btn btn-sm btn-outline-primary">View All</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<t t-if="recent_invoices">
|
||||
<table class="table table-sm mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Invoice</th>
|
||||
<th>Due Date</th>
|
||||
<th class="text-end">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="recent_invoices" t-as="inv">
|
||||
<td t-out="inv.name"/>
|
||||
<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_total"
|
||||
t-options='{"widget": "monetary", "display_currency": inv.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="p-4 text-center text-muted">
|
||||
No invoices yet.
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_fp_panel">
|
||||
<div class="o_fp_panel_title">
|
||||
<span class="o_fp_panel_icon">📦</span> Recent Packing Slips
|
||||
</div>
|
||||
<t t-if="recent_deliveries">
|
||||
<t t-foreach="recent_deliveries[:3]" t-as="d">
|
||||
<div class="o_fp_panel_row">
|
||||
<span t-out="d.name"/>
|
||||
<t t-if="d.date_done"> · <span t-field="d.date_done" t-options='{"widget": "date"}'/></t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="o_fp_panel_row text-muted">No deliveries yet.</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_fp_panel">
|
||||
<div class="o_fp_panel_title">
|
||||
<span class="o_fp_panel_icon">💰</span> Recent Invoices
|
||||
</div>
|
||||
<t t-if="recent_invoices">
|
||||
<t t-foreach="recent_invoices[:3]" t-as="inv">
|
||||
<div class="o_fp_panel_row">
|
||||
<a t-att-href="'/my/fp_invoices/%s' % inv.id" class="text-decoration-none" t-out="inv.name"/>
|
||||
<t t-if="inv.amount_total"> · <span t-field="inv.amount_total" t-options='{"widget": "monetary", "display_currency": inv.currency_id}'/></t>
|
||||
<t t-if="inv.payment_state == 'paid'"> · <span class="o_fp_badge o_fp_badge_paid"><span class="o_fp_badge_dot"/>Paid</span></t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="o_fp_panel_row text-muted">No invoices yet.</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /row -->
|
||||
</div><!-- /o_fp_dashboard -->
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user