Initial commit
This commit is contained in:
377
fusion_claims/report/invoice_report_portrait.xml
Normal file
377
fusion_claims/report/invoice_report_portrait.xml
Normal file
@@ -0,0 +1,377 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2024-2025 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Claim Assistant product family.
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_invoice_portrait">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)"/>
|
||||
<t t-set="is_adp" t-value="doc.x_fc_is_adp_invoice"/>
|
||||
|
||||
<style>
|
||||
.fc-report { font-family: Arial, sans-serif; font-size: 10pt; }
|
||||
.fc-report table { width: 100%; border-collapse: collapse; margin-bottom: 10px; }
|
||||
.fc-report table.bordered, .fc-report table.bordered th, .fc-report table.bordered td { border: 1px solid #000; }
|
||||
.fc-report th { background-color: #f0f0f0; padding: 6px 8px; font-weight: bold; text-align: center; }
|
||||
.fc-report td { padding: 6px 8px; vertical-align: top; }
|
||||
.fc-report .text-center { text-align: center; }
|
||||
.fc-report .text-end { text-align: right; }
|
||||
.fc-report .text-start { text-align: left; }
|
||||
.fc-report .adp-bg { background-color: #e3f2fd; }
|
||||
.fc-report .client-bg { background-color: #fff3e0; }
|
||||
.fc-report .section-row { background-color: #f8f8f8; font-weight: bold; }
|
||||
.fc-report .note-row { font-style: italic; }
|
||||
.fc-report h4 { color: #005a83; margin: 0 0 15px 0; }
|
||||
.fc-report .totals-table { border: 1px solid #000; border-collapse: collapse; }
|
||||
.fc-report .totals-table td { border: 1px solid #000; padding: 6px 8px; }
|
||||
</style>
|
||||
|
||||
<div class="fc-report">
|
||||
<div class="page">
|
||||
|
||||
<!-- Document Title -->
|
||||
<h4 style="text-align: left;">
|
||||
<span t-if="doc.move_type == 'out_invoice' and doc.state == 'posted'">Invoice </span>
|
||||
<span t-elif="doc.move_type == 'out_invoice' and doc.state == 'draft'">Draft Invoice </span>
|
||||
<span t-elif="doc.move_type == 'out_refund'">Credit Note </span>
|
||||
<span t-field="doc.name"/>
|
||||
</h4>
|
||||
|
||||
<!-- Address Table -->
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50%;">BILLING ADDRESS</th>
|
||||
<th style="width: 50%;">DELIVERY ADDRESS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="height: 70px; font-size: 11pt;">
|
||||
<div t-field="doc.partner_id"
|
||||
t-options="{'widget': 'contact', 'fields': ['name', 'address'], 'no_marker': True}"/>
|
||||
</td>
|
||||
<td style="height: 70px; font-size: 11pt;">
|
||||
<t t-if="doc.partner_shipping_id">
|
||||
<div t-field="doc.partner_shipping_id"
|
||||
t-options="{'widget': 'contact', 'fields': ['name', 'address'], 'no_marker': True}"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div t-field="doc.partner_id"
|
||||
t-options="{'widget': 'contact', 'fields': ['name', 'address'], 'no_marker': True}"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Invoice Info Table -->
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%;">INVOICE DATE</th>
|
||||
<th style="width: 20%;">DUE DATE</th>
|
||||
<th style="width: 20%;">SOURCE</th>
|
||||
<th style="width: 20%;">SALESPERSON</th>
|
||||
<th style="width: 20%;">
|
||||
<t t-if="is_adp">APPLICATION TYPE</t>
|
||||
<t t-else="">INVOICE TYPE</t>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<span t-field="doc.invoice_date"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-field="doc.invoice_date_due"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-field="doc.invoice_origin"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-field="doc.invoice_user_id"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<t t-if="is_adp">
|
||||
<!-- Get application type from linked sale order -->
|
||||
<t t-set="linked_so" t-value="doc.invoice_line_ids.mapped('sale_line_ids.order_id')[:1]"/>
|
||||
<t t-if="linked_so and linked_so.x_fc_reason_for_application">
|
||||
<t t-set="app_type" t-value="dict(linked_so._fields.get('x_fc_reason_for_application') and linked_so._fields['x_fc_reason_for_application'].selection or []).get(linked_so.x_fc_reason_for_application, '-')"/>
|
||||
<span t-esc="app_type"/>
|
||||
</t>
|
||||
<t t-else="">-</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span t-esc="doc.x_fc_invoice_type or '-'"/>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- ADP Info Table (only for ADP invoices) -->
|
||||
<t t-if="is_adp">
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr class="adp-bg">
|
||||
<th style="width: 25%;">CLAIM NUMBER</th>
|
||||
<th style="width: 25%;">CLIENT TYPE</th>
|
||||
<th style="width: 25%;">DELIVERY DATE</th>
|
||||
<th style="width: 25%;">AUTHORIZER</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="adp-bg">
|
||||
<td class="text-center">
|
||||
<span t-esc="doc.x_fc_claim_number or '-'"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="doc.x_fc_client_type or '-'"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<t t-if="doc.x_fc_adp_delivery_date">
|
||||
<span t-field="doc.x_fc_adp_delivery_date"/>
|
||||
</t>
|
||||
<t t-else="">-</t>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-if="doc.x_fc_authorizer_id" t-field="doc.x_fc_authorizer_id"/>
|
||||
<span t-else="">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Invoice Lines Table -->
|
||||
<table class="bordered" style="font-size: 9pt;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center" style="width: 10%;">ADP CODE</th>
|
||||
<th class="text-start" style="width: 22%;">DESCRIPTION</th>
|
||||
<th class="text-center" style="width: 10%;">SERIAL #</th>
|
||||
<th class="text-center" style="width: 6%;">QTY</th>
|
||||
<th class="text-center" style="width: 9%;">UNIT PRICE</th>
|
||||
<th class="text-center" style="width: 7%;">TAXES</th>
|
||||
<th t-if="is_adp" class="text-center" style="width: 11%; background-color: #1976d2; color: white;">ADP PORTION</th>
|
||||
<th t-if="is_adp" class="text-center" style="width: 11%; background-color: #e65100; color: white;">CLIENT PORTION</th>
|
||||
<th class="text-center" style="width: 11%;">AMOUNT</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="doc.invoice_line_ids" t-as="line">
|
||||
<!-- Section Header -->
|
||||
<t t-if="line.display_type == 'line_section'">
|
||||
<tr class="section-row">
|
||||
<td t-att-colspan="'9' if is_adp else '7'">
|
||||
<span t-field="line.name"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<!-- Note Line -->
|
||||
<t t-elif="line.display_type == 'line_note'">
|
||||
<tr class="note-row">
|
||||
<td t-att-colspan="'9' if is_adp else '7'">
|
||||
<span t-field="line.name"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<!-- Product Line (display_type is False/None/empty for actual products) -->
|
||||
<t t-else="">
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<span t-field="line.product_id.x_fc_adp_device_code"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-if="line.name">
|
||||
<t t-set="clean_name" t-value="line.name"/>
|
||||
<t t-if="'] ' in line.name">
|
||||
<t t-set="clean_name" t-value="line.name.split('] ', 1)[1]"/>
|
||||
</t>
|
||||
<t t-esc="clean_name"/>
|
||||
</t>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="line.x_fc_serial_number or ''"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-field="line.quantity"/>
|
||||
<span t-field="line.product_uom_id" groups="uom.group_uom"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<!-- Show ADP price if available, otherwise unit price -->
|
||||
<t t-if="line.product_id.product_tmpl_id.x_fc_adp_price">
|
||||
<span t-esc="line.product_id.product_tmpl_id.x_fc_adp_price" t-options="{'widget': 'monetary', 'display_currency': doc.currency_id}"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span t-field="line.price_unit"/>
|
||||
</t>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<t t-esc="', '.join([(tax.invoice_label or tax.name) for tax in line.tax_ids]) or 'NO TAX'"/>
|
||||
</td>
|
||||
<td t-if="is_adp" class="text-center adp-bg">
|
||||
<span t-field="line.x_fc_adp_portion"/>
|
||||
</td>
|
||||
<td t-if="is_adp" class="text-center client-bg">
|
||||
<span t-field="line.x_fc_client_portion"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-field="line.price_subtotal"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Payment Terms and Totals Row -->
|
||||
<div class="row" style="margin-top: 15px;">
|
||||
<div class="col-6">
|
||||
<t t-if="doc.invoice_payment_term_id.note">
|
||||
<strong>Payment Terms:</strong><br/>
|
||||
<span t-field="doc.invoice_payment_term_id.note"/>
|
||||
</t>
|
||||
<t t-if="doc.payment_reference">
|
||||
<div style="margin-top: 10px;">
|
||||
<strong>Payment Reference:</strong>
|
||||
<span t-field="doc.payment_reference"/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-6" style="text-align: right;">
|
||||
<!-- Totals Table with borders -->
|
||||
<table class="totals-table" style="width: auto; margin-left: auto;">
|
||||
<tr>
|
||||
<td style="min-width: 140px;">Subtotal</td>
|
||||
<td class="text-end" style="min-width: 100px;"><span t-field="doc.amount_untaxed"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Taxes</td>
|
||||
<td class="text-end"><span t-field="doc.amount_tax"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Total</strong></td>
|
||||
<td class="text-end"><strong><span t-field="doc.amount_total"/></strong></td>
|
||||
</tr>
|
||||
<t t-if="is_adp">
|
||||
<!-- Show actual invoice totals, not calculated portions -->
|
||||
<!-- On ADP invoice (75%): this invoice = ADP portion, sibling = Client portion -->
|
||||
<!-- On Client invoice (25%): this invoice = Client portion, sibling = ADP portion -->
|
||||
<t t-if="doc.x_fc_adp_invoice_portion == 'adp'">
|
||||
<tr class="adp-bg">
|
||||
<td><strong>Total ADP Portion</strong></td>
|
||||
<td class="text-end"><span t-field="doc.amount_total"/></td>
|
||||
</tr>
|
||||
<tr class="client-bg">
|
||||
<td><strong>Total Client Portion</strong></td>
|
||||
<td class="text-end"><span t-field="doc.x_fc_sibling_client_total"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-elif="doc.x_fc_adp_invoice_portion == 'client'">
|
||||
<tr class="adp-bg">
|
||||
<td><strong>Total ADP Portion</strong></td>
|
||||
<td class="text-end"><span t-field="doc.x_fc_sibling_adp_total"/></td>
|
||||
</tr>
|
||||
<tr class="client-bg">
|
||||
<td><strong>Total Client Portion</strong></td>
|
||||
<td class="text-end"><span t-field="doc.amount_total"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<!-- Fallback for full invoices or unknown portion -->
|
||||
<tr class="adp-bg">
|
||||
<td><strong>Total ADP Portion</strong></td>
|
||||
<td class="text-end"><span t-field="doc.x_fc_adp_portion_total"/></td>
|
||||
</tr>
|
||||
<tr class="client-bg">
|
||||
<td><strong>Total Client Portion</strong></td>
|
||||
<td class="text-end"><span t-field="doc.x_fc_client_portion_total"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="doc.amount_residual and doc.amount_residual != doc.amount_total">
|
||||
<tr>
|
||||
<td><strong>Amount Due</strong></td>
|
||||
<td class="text-end"><strong><span t-field="doc.amount_residual"/></strong></td>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Payment Details Section -->
|
||||
<t t-if="doc.payment_state != 'invoicing_legacy'">
|
||||
<t t-set="payments_vals" t-value="doc.sudo().invoice_payments_widget and doc.sudo().invoice_payments_widget.get('content') or []"/>
|
||||
<t t-if="payments_vals or doc.payment_state == 'paid'">
|
||||
<table class="bordered" style="margin-top: 15px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="4" style="background-color: #28a745; color: white;">
|
||||
<t t-if="doc.payment_state == 'paid'">✓ PAYMENT DETAILS - PAID IN FULL</t>
|
||||
<t t-elif="doc.payment_state == 'partial'">PAYMENT DETAILS - PARTIALLY PAID</t>
|
||||
<t t-else="">PAYMENT DETAILS</t>
|
||||
</th>
|
||||
</tr>
|
||||
<tr style="background-color: #f5f5f5;">
|
||||
<th style="width: 25%;">Date</th>
|
||||
<th style="width: 30%;">Payment Method</th>
|
||||
<th style="width: 20%;">Card #</th>
|
||||
<th style="width: 25%;" class="text-end">Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="payments_vals" t-as="payment_vals">
|
||||
<tr t-if="not payment_vals.get('is_exchange')">
|
||||
<td>
|
||||
<t t-if="payment_vals.get('is_refund')">Reversed </t>
|
||||
<span t-out="payment_vals.get('date')" t-options='{"widget": "date"}'/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-out="payment_vals.get('payment_method_name') or '-'"/>
|
||||
</td>
|
||||
<td>
|
||||
<!-- Get card info from payment record -->
|
||||
<t t-set="payment_rec" t-value="doc.env['account.payment'].sudo().browse(payment_vals.get('account_payment_id'))"/>
|
||||
<t t-if="payment_rec and payment_rec.x_fc_card_last_four">
|
||||
****<span t-esc="payment_rec.x_fc_card_last_four"/>
|
||||
</t>
|
||||
<t t-else="">-</t>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<span t-out="payment_vals.get('amount')" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-if="doc.amount_residual and doc.amount_residual > 0 and doc.payment_state != 'paid'">
|
||||
<tr style="background-color: #fff3e0;">
|
||||
<td colspan="3"><strong>Amount Due</strong></td>
|
||||
<td class="text-end"><strong><span t-field="doc.amount_residual"/></strong></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<!-- Notes -->
|
||||
<t t-if="doc.narration">
|
||||
<div style="margin-top: 15px;">
|
||||
<strong>Notes:</strong>
|
||||
<div t-field="doc.narration"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user