folder rename
This commit is contained in:
5
fusion_plating/fusion_plating_reports/__init__.py
Normal file
5
fusion_plating/fusion_plating_reports/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from . import models
|
||||
38
fusion_plating/fusion_plating_reports/__manifest__.py
Normal file
38
fusion_plating/fusion_plating_reports/__manifest__.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
{
|
||||
'name': 'Fusion Plating — Reports',
|
||||
'version': '19.0.1.0.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'PDF reports for all Fusion Plating models: CoC, NCR, CAPA, bath logs, calibration, and more.',
|
||||
'depends': [
|
||||
'mrp',
|
||||
'fusion_plating',
|
||||
'fusion_plating_quality',
|
||||
'fusion_plating_compliance',
|
||||
'fusion_plating_safety',
|
||||
'fusion_plating_portal',
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'report/report_base_styles.xml',
|
||||
'report/report_actions.xml',
|
||||
'report/report_coc.xml',
|
||||
'report/report_ncr.xml',
|
||||
'report/report_capa.xml',
|
||||
'report/report_bath_chemistry_log.xml',
|
||||
'report/report_calibration_cert.xml',
|
||||
'report/report_fair.xml',
|
||||
'report/report_audit.xml',
|
||||
'report/report_incident.xml',
|
||||
'report/report_spill.xml',
|
||||
'report/report_waste_manifest.xml',
|
||||
'report/report_discharge_sample.xml',
|
||||
'report/report_wo_margin.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
'auto_install': False,
|
||||
'license': 'OPL-1',
|
||||
}
|
||||
6
fusion_plating/fusion_plating_reports/models/__init__.py
Normal file
6
fusion_plating/fusion_plating_reports/models/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
from . import report_wo_margin
|
||||
165
fusion_plating/fusion_plating_reports/models/report_wo_margin.py
Normal file
165
fusion_plating/fusion_plating_reports/models/report_wo_margin.py
Normal file
@@ -0,0 +1,165 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class ReportWoMargin(models.AbstractModel):
|
||||
"""Work Order Margin Report Data.
|
||||
|
||||
Computes cost, revenue, and margin breakdowns for manufacturing orders
|
||||
so the QWeb template can render a Steelhead-style margin report.
|
||||
"""
|
||||
_name = 'report.fusion_plating_reports.report_wo_margin'
|
||||
_description = 'WO Margin Report Data'
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# helpers
|
||||
# ------------------------------------------------------------------
|
||||
def _get_station_costs(self, mo):
|
||||
"""Return a list of dicts with per-station cost breakdown."""
|
||||
station_costs = []
|
||||
for wo in mo.workorder_ids:
|
||||
wc = wo.workcenter_id
|
||||
labour_rate = wc.costs_hour if wc else 0.0
|
||||
# Sum tracked time from productivity records (minutes)
|
||||
time_minutes = sum(wo.time_ids.mapped('duration'))
|
||||
time_hours = time_minutes / 60.0
|
||||
labour_cost = time_hours * labour_rate
|
||||
|
||||
# Operation cost uses the same rate & dwell for now
|
||||
operation_rate = labour_rate
|
||||
dwell_minutes = time_minutes
|
||||
dwell_hours = dwell_minutes / 60.0
|
||||
operation_cost = dwell_hours * operation_rate
|
||||
|
||||
total = labour_cost + operation_cost
|
||||
station_costs.append({
|
||||
'station': wc.name if wc else 'Unknown',
|
||||
'labour_rate': labour_rate,
|
||||
'labour_time': time_minutes,
|
||||
'labour_hours': time_hours,
|
||||
'labour_cost': labour_cost,
|
||||
'operation_rate': operation_rate,
|
||||
'dwell_time': dwell_minutes,
|
||||
'dwell_hours': dwell_hours,
|
||||
'operation_cost': operation_cost,
|
||||
'total_cost': total,
|
||||
})
|
||||
return station_costs
|
||||
|
||||
def _get_part_margins(self, mo, revenue):
|
||||
"""Return margin breakdown per unique product (part number)."""
|
||||
parts = {}
|
||||
for wo in mo.workorder_ids:
|
||||
product = wo.product_id or mo.product_id
|
||||
key = product.id
|
||||
if key not in parts:
|
||||
parts[key] = {
|
||||
'product': product,
|
||||
'part_number': product.default_code or product.name,
|
||||
'count': 0,
|
||||
'labour_cost': 0.0,
|
||||
'station_labour_cost': 0.0,
|
||||
'station_operation_cost': 0.0,
|
||||
'outsourcing_cost': 0.0,
|
||||
}
|
||||
entry = parts[key]
|
||||
entry['count'] += 1
|
||||
time_hours = sum(wo.time_ids.mapped('duration')) / 60.0
|
||||
rate = wo.workcenter_id.costs_hour if wo.workcenter_id else 0.0
|
||||
cost = time_hours * rate
|
||||
entry['labour_cost'] += cost
|
||||
entry['station_labour_cost'] += cost
|
||||
entry['station_operation_cost'] += cost
|
||||
|
||||
# Distribute revenue equally across parts for per-part metrics
|
||||
part_list = list(parts.values())
|
||||
total_parts = sum(p['count'] for p in part_list) or 1
|
||||
for p in part_list:
|
||||
p['so_total'] = revenue * (p['count'] / total_parts)
|
||||
p['so_per_part'] = p['so_total'] / p['count'] if p['count'] else 0
|
||||
p['unit_labour'] = p['labour_cost'] / p['count'] if p['count'] else 0
|
||||
total_cost = (
|
||||
p['labour_cost'] + p['station_labour_cost']
|
||||
+ p['station_operation_cost'] + p['outsourcing_cost']
|
||||
)
|
||||
p['margin_pct'] = (
|
||||
(p['so_total'] - total_cost) / p['so_total'] * 100
|
||||
) if p['so_total'] else 0
|
||||
return part_list
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Report entry point
|
||||
# ------------------------------------------------------------------
|
||||
@api.model
|
||||
def _get_report_values(self, docids, data=None):
|
||||
productions = self.env['mrp.production'].browse(docids)
|
||||
docs = []
|
||||
for mo in productions:
|
||||
# Revenue from linked sale order
|
||||
revenue = 0.0
|
||||
if hasattr(mo, 'sale_order_id') and mo.sale_order_id:
|
||||
revenue = sum(
|
||||
mo.sale_order_id.order_line.mapped('price_subtotal')
|
||||
)
|
||||
|
||||
# Station costs
|
||||
station_costs = self._get_station_costs(mo)
|
||||
part_labour_cost = sum(s['labour_cost'] for s in station_costs)
|
||||
station_labour_cost = part_labour_cost # same pool
|
||||
station_operation_cost = sum(
|
||||
s['operation_cost'] for s in station_costs
|
||||
)
|
||||
|
||||
# Inventory cost (raw materials)
|
||||
inventory_cost = sum(
|
||||
m.product_id.standard_price * m.quantity
|
||||
for m in mo.move_raw_ids
|
||||
)
|
||||
|
||||
# Outsourcing cost placeholder
|
||||
outsourcing_cost = 0.0
|
||||
|
||||
total_cost = (
|
||||
part_labour_cost + station_labour_cost
|
||||
+ station_operation_cost + inventory_cost
|
||||
+ outsourcing_cost
|
||||
)
|
||||
gross_profit = revenue - total_cost
|
||||
margin_pct = (
|
||||
(gross_profit / revenue * 100) if revenue else 0.0
|
||||
)
|
||||
|
||||
# Station cost percentages
|
||||
total_station_cost = sum(s['total_cost'] for s in station_costs)
|
||||
for s in station_costs:
|
||||
s['percentage'] = (
|
||||
(s['total_cost'] / total_station_cost * 100)
|
||||
if total_station_cost else 0
|
||||
)
|
||||
|
||||
# Part margins
|
||||
part_margins = self._get_part_margins(mo, revenue)
|
||||
|
||||
docs.append({
|
||||
'mo': mo,
|
||||
'revenue': revenue,
|
||||
'part_labour_cost': part_labour_cost,
|
||||
'station_labour_cost': station_labour_cost,
|
||||
'station_operation_cost': station_operation_cost,
|
||||
'inventory_cost': inventory_cost,
|
||||
'outsourcing_cost': outsourcing_cost,
|
||||
'total_cost': total_cost,
|
||||
'gross_profit': gross_profit,
|
||||
'margin_pct': margin_pct,
|
||||
'station_costs': station_costs,
|
||||
'part_margins': part_margins,
|
||||
})
|
||||
|
||||
return {
|
||||
'doc_ids': docids,
|
||||
'docs': docs,
|
||||
}
|
||||
205
fusion_plating/fusion_plating_reports/report/report_actions.xml
Normal file
205
fusion_plating/fusion_plating_reports/report/report_actions.xml
Normal file
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
Paper format + report actions for all Fusion Plating reports.
|
||||
-->
|
||||
<odoo>
|
||||
<!-- ============================================================= -->
|
||||
<!-- Landscape Paper Format -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="paperformat_fp_a4_landscape" model="report.paperformat">
|
||||
<field name="name">A4 Landscape (Fusion Plating)</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="format">A4</field>
|
||||
<field name="orientation">Landscape</field>
|
||||
<field name="margin_top">20</field>
|
||||
<field name="margin_bottom">20</field>
|
||||
<field name="margin_left">7</field>
|
||||
<field name="margin_right">7</field>
|
||||
<field name="header_line" eval="False"/>
|
||||
<field name="header_spacing">20</field>
|
||||
<field name="dpi">90</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 1. Certificate of Conformance (Portal Job) -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_coc" model="ir.actions.report">
|
||||
<field name="name">Certificate of Conformance</field>
|
||||
<field name="model">fusion.plating.portal.job</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_coc</field>
|
||||
<field name="report_file">fusion_plating_reports.report_coc</field>
|
||||
<field name="print_report_name">'CoC - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_portal.model_fusion_plating_portal_job"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 2. Non-Conformance Report -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_ncr" model="ir.actions.report">
|
||||
<field name="name">Non-Conformance Report</field>
|
||||
<field name="model">fusion.plating.ncr</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_ncr</field>
|
||||
<field name="report_file">fusion_plating_reports.report_ncr</field>
|
||||
<field name="print_report_name">'NCR - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_quality.model_fusion_plating_ncr"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 3. Corrective / Preventive Action -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_capa" model="ir.actions.report">
|
||||
<field name="name">CAPA Report</field>
|
||||
<field name="model">fusion.plating.capa</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_capa</field>
|
||||
<field name="report_file">fusion_plating_reports.report_capa</field>
|
||||
<field name="print_report_name">'CAPA - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_quality.model_fusion_plating_capa"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 4. Bath Chemistry Log -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_bath_log" model="ir.actions.report">
|
||||
<field name="name">Bath Chemistry Log</field>
|
||||
<field name="model">fusion.plating.bath.log</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_bath_chemistry_log</field>
|
||||
<field name="report_file">fusion_plating_reports.report_bath_chemistry_log</field>
|
||||
<field name="print_report_name">'Bath Log - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating.model_fusion_plating_bath_log"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 5. Calibration Certificate -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_calibration" model="ir.actions.report">
|
||||
<field name="name">Calibration Certificate</field>
|
||||
<field name="model">fusion.plating.calibration.equipment</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_calibration_cert</field>
|
||||
<field name="report_file">fusion_plating_reports.report_calibration_cert</field>
|
||||
<field name="print_report_name">'Calibration - %s' % object.code</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_quality.model_fusion_plating_calibration_equipment"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 6. First Article Inspection Report -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_fair" model="ir.actions.report">
|
||||
<field name="name">FAIR Report</field>
|
||||
<field name="model">fusion.plating.fair</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_fair</field>
|
||||
<field name="report_file">fusion_plating_reports.report_fair</field>
|
||||
<field name="print_report_name">'FAIR - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_quality.model_fusion_plating_fair"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 7. Audit Report -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_audit" model="ir.actions.report">
|
||||
<field name="name">Audit Report</field>
|
||||
<field name="model">fusion.plating.audit</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_audit</field>
|
||||
<field name="report_file">fusion_plating_reports.report_audit</field>
|
||||
<field name="print_report_name">'Audit - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_quality.model_fusion_plating_audit"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 8. Incident Report -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_incident" model="ir.actions.report">
|
||||
<field name="name">Incident Report</field>
|
||||
<field name="model">fusion.plating.incident</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_incident</field>
|
||||
<field name="report_file">fusion_plating_reports.report_incident</field>
|
||||
<field name="print_report_name">'Incident - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_safety.model_fusion_plating_incident"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 9. Spill Register -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_spill" model="ir.actions.report">
|
||||
<field name="name">Spill Report</field>
|
||||
<field name="model">fusion.plating.spill.register</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_spill</field>
|
||||
<field name="report_file">fusion_plating_reports.report_spill</field>
|
||||
<field name="print_report_name">'Spill - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_compliance.model_fusion_plating_spill_register"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 10. Waste Manifest -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_waste_manifest" model="ir.actions.report">
|
||||
<field name="name">Waste Manifest</field>
|
||||
<field name="model">fusion.plating.waste.manifest</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_waste_manifest</field>
|
||||
<field name="report_file">fusion_plating_reports.report_waste_manifest</field>
|
||||
<field name="print_report_name">'Waste Manifest - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_compliance.model_fusion_plating_waste_manifest"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 11. Discharge Sample -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_discharge_sample" model="ir.actions.report">
|
||||
<field name="name">Discharge Sample Report</field>
|
||||
<field name="model">fusion.plating.discharge.sample</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_discharge_sample</field>
|
||||
<field name="report_file">fusion_plating_reports.report_discharge_sample</field>
|
||||
<field name="print_report_name">'Discharge - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_compliance.model_fusion_plating_discharge_sample"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 12. Work Order Margin Report -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="action_report_wo_margin" model="ir.actions.report">
|
||||
<field name="name">Work Order Margin Report</field>
|
||||
<field name="model">mrp.production</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_wo_margin</field>
|
||||
<field name="report_file">fusion_plating_reports.report_wo_margin</field>
|
||||
<field name="print_report_name">'Margin Report - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="mrp.model_mrp_production"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_landscape"/>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Audit Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_audit">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Audit Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>AUDIT #</th>
|
||||
<th>TYPE</th>
|
||||
<th>SCOPE</th>
|
||||
<th>FACILITY</th>
|
||||
<th>AUDIT DATE</th>
|
||||
<th>STATUS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.audit_type"/></td>
|
||||
<td class="text-center"><span t-field="doc.scope"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.audit_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Auditors & Stats -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>AUDITORS</th>
|
||||
<th># FINDINGS</th>
|
||||
<th>LINKED CAPAs</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center">
|
||||
<t t-foreach="doc.auditor_ids" t-as="aud">
|
||||
<span t-out="aud.name"/>
|
||||
<t t-if="not aud_last">, </t>
|
||||
</t>
|
||||
</td>
|
||||
<td class="text-center"><span t-field="doc.findings_count"/></td>
|
||||
<td class="text-center"><span t-field="doc.capa_count"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Findings -->
|
||||
<t t-if="doc.findings_html">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>FINDINGS</td></tr>
|
||||
<tr><td><t t-out="doc.findings_html"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Linked CAPAs Table -->
|
||||
<t t-if="doc.capa_ids">
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>CAPA #</th>
|
||||
<th>TYPE</th>
|
||||
<th>STATUS</th>
|
||||
<th>OWNER</th>
|
||||
<th>DUE DATE</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="doc.capa_ids" t-as="capa">
|
||||
<tr>
|
||||
<td><span t-field="capa.name"/></td>
|
||||
<td class="text-center"><span t-field="capa.type"/></td>
|
||||
<td class="text-center"><span t-field="capa.state"/></td>
|
||||
<td class="text-center"><span t-field="capa.owner_id"/></td>
|
||||
<td class="text-center"><span t-field="capa.due_date" t-options="{'widget': 'date'}"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Part of the Fusion Plating product family.
|
||||
Shared landscape CSS for all Fusion Plating reports.
|
||||
-->
|
||||
<odoo>
|
||||
<template id="fp_landscape_styles">
|
||||
<style>
|
||||
.fp-landscape { font-family: Arial, sans-serif; font-size: 11pt; }
|
||||
.fp-landscape table { width: 100%; border-collapse: collapse; margin-bottom: 12px; }
|
||||
.fp-landscape table.bordered, .fp-landscape table.bordered th, .fp-landscape table.bordered td { border: 1px solid #000; }
|
||||
.fp-landscape th { background-color: #0066a1; color: white; padding: 8px 10px; font-weight: bold; font-size: 10pt; }
|
||||
.fp-landscape td { padding: 6px 8px; vertical-align: top; font-size: 10pt; }
|
||||
.fp-landscape .text-center { text-align: center; }
|
||||
.fp-landscape .text-end { text-align: right; }
|
||||
.fp-landscape .text-start { text-align: left; }
|
||||
.fp-landscape .adp-bg { background-color: #e3f2fd; }
|
||||
.fp-landscape .client-bg { background-color: #fff3e0; }
|
||||
.fp-landscape .section-row { background-color: #f0f0f0; font-weight: bold; }
|
||||
.fp-landscape .note-row { font-style: italic; }
|
||||
.fp-landscape h2 { color: #0066a1; margin: 10px 0; font-size: 18pt; }
|
||||
.fp-landscape .info-table td { padding: 8px 12px; font-size: 11pt; }
|
||||
.fp-landscape .info-table th { background-color: #f5f5f5; color: #333; font-size: 10pt; padding: 6px 12px; }
|
||||
.fp-landscape .totals-table { border: 1px solid #000; }
|
||||
.fp-landscape .totals-table td { border: 1px solid #000; padding: 8px 12px; font-size: 11pt; }
|
||||
.fp-landscape .status-ok { color: #2e7d32; font-weight: bold; }
|
||||
.fp-landscape .status-warning { color: #f57f17; font-weight: bold; }
|
||||
.fp-landscape .status-fail { color: #c62828; font-weight: bold; }
|
||||
</style>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Bath Chemistry Log Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_bath_chemistry_log">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Bath Chemistry Log
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>LOG REF</th>
|
||||
<th>BATH</th>
|
||||
<th>TANK</th>
|
||||
<th>PROCESS TYPE</th>
|
||||
<th>LOGGED AT</th>
|
||||
<th>OPERATOR</th>
|
||||
<th>SHIFT</th>
|
||||
<th>STATUS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.bath_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.tank_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.process_type_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.log_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.operator_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.shift"/></td>
|
||||
<td class="text-center">
|
||||
<span t-if="doc.status == 'ok'" class="status-ok">OK</span>
|
||||
<span t-if="doc.status == 'warning'" class="status-warning">Warning</span>
|
||||
<span t-if="doc.status == 'out_of_spec'" class="status-fail">Out of Spec</span>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Readings Table -->
|
||||
<t t-if="doc.line_ids">
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>PARAMETER</th>
|
||||
<th>VALUE</th>
|
||||
<th>TARGET MIN</th>
|
||||
<th>TARGET MAX</th>
|
||||
<th>UoM</th>
|
||||
<th>STATUS</th>
|
||||
<th>NOTES</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="doc.line_ids" t-as="line">
|
||||
<tr>
|
||||
<td><span t-field="line.parameter_id"/></td>
|
||||
<td class="text-center"><span t-field="line.value"/></td>
|
||||
<td class="text-center"><span t-field="line.target_min"/></td>
|
||||
<td class="text-center"><span t-field="line.target_max"/></td>
|
||||
<td class="text-center"><span t-field="line.uom"/></td>
|
||||
<td class="text-center">
|
||||
<span t-if="line.status == 'ok'" class="status-ok">OK</span>
|
||||
<span t-if="line.status == 'warning'" class="status-warning">Warning</span>
|
||||
<span t-if="line.status == 'out_of_spec'" class="status-fail">Out of Spec</span>
|
||||
</td>
|
||||
<td><span t-field="line.notes"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Notes -->
|
||||
<t t-if="doc.notes">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>NOTES</td></tr>
|
||||
<tr><td><span t-field="doc.notes"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Calibration Certificate Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_calibration_cert">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Calibration Certificate
|
||||
<span t-field="doc.code"/>
|
||||
</h2>
|
||||
|
||||
<!-- Equipment Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>EQUIPMENT</th>
|
||||
<th>ASSET CODE</th>
|
||||
<th>TYPE</th>
|
||||
<th>NIST TRACEABLE</th>
|
||||
<th>STATUS</th>
|
||||
<th>FACILITY</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.code"/></td>
|
||||
<td class="text-center"><span t-field="doc.equipment_type"/></td>
|
||||
<td class="text-center">
|
||||
<t t-if="doc.nist_traceable">Yes</t>
|
||||
<t t-else="">No</t>
|
||||
</td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Calibration Dates -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>LAST CALIBRATION</th>
|
||||
<th>NEXT CALIBRATION</th>
|
||||
<th>INTERVAL (DAYS)</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.last_cal_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.next_cal_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.calibration_interval_days"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Event History -->
|
||||
<t t-if="doc.event_ids">
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>CALIBRATION DATE</th>
|
||||
<th>PERFORMED BY</th>
|
||||
<th>EXTERNAL LAB</th>
|
||||
<th>RESULT</th>
|
||||
<th>CERTIFICATE #</th>
|
||||
<th>AS-FOUND</th>
|
||||
<th>AS-LEFT</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="doc.event_ids" t-as="evt">
|
||||
<tr>
|
||||
<td class="text-center"><span t-field="evt.cal_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="evt.performed_by_id"/></td>
|
||||
<td class="text-center"><span t-field="evt.performed_by_external"/></td>
|
||||
<td class="text-center"><span t-field="evt.result"/></td>
|
||||
<td class="text-center"><span t-field="evt.certificate_ref"/></td>
|
||||
<td><span t-field="evt.as_found_notes"/></td>
|
||||
<td><span t-field="evt.as_left_notes"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
94
fusion_plating/fusion_plating_reports/report/report_capa.xml
Normal file
94
fusion_plating/fusion_plating_reports/report/report_capa.xml
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Corrective / Preventive Action Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_capa">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
CAPA Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>CAPA #</th>
|
||||
<th>TYPE</th>
|
||||
<th>STATUS</th>
|
||||
<th>SOURCE NCR</th>
|
||||
<th>OWNER</th>
|
||||
<th>DUE DATE</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.type"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
<td class="text-center"><span t-field="doc.ncr_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.owner_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.due_date" t-options="{'widget': 'date'}"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Facility -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>FACILITY</th>
|
||||
<th>VERIFIED BY</th>
|
||||
<th>VERIFICATION DATE</th>
|
||||
<th>EFFECTIVE</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.verification_by_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.verification_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center">
|
||||
<t t-if="doc.is_effective">Yes</t>
|
||||
<t t-else="">No</t>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Description -->
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>DESCRIPTION</td></tr>
|
||||
<tr><td><t t-out="doc.description"/></td></tr>
|
||||
</table>
|
||||
|
||||
<!-- Root Cause Analysis -->
|
||||
<t t-if="doc.root_cause_analysis">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>ROOT CAUSE ANALYSIS</td></tr>
|
||||
<tr><td><t t-out="doc.root_cause_analysis"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Action Plan -->
|
||||
<t t-if="doc.action_plan">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>ACTION PLAN</td></tr>
|
||||
<tr><td><t t-out="doc.action_plan"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Effectiveness Notes -->
|
||||
<t t-if="doc.effectiveness_notes">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>EFFECTIVENESS NOTES</td></tr>
|
||||
<tr><td><t t-out="doc.effectiveness_notes"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
114
fusion_plating/fusion_plating_reports/report/report_coc.xml
Normal file
114
fusion_plating/fusion_plating_reports/report/report_coc.xml
Normal file
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Certificate of Conformance — Portal Job
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_coc">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Certificate of Conformance
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Job Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>JOB REF</th>
|
||||
<th>CUSTOMER</th>
|
||||
<th>QUANTITY</th>
|
||||
<th>RECEIVED</th>
|
||||
<th>SHIP DATE</th>
|
||||
<th>TRACKING REF</th>
|
||||
<th>STATUS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td><span t-field="doc.partner_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.quantity"/></td>
|
||||
<td class="text-center"><span t-field="doc.received_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.actual_ship_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.tracking_ref"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Customer Address -->
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th colspan="2">CUSTOMER DETAILS</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:30%; font-weight:bold;">Name</td>
|
||||
<td><span t-field="doc.partner_id.name"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight:bold;">Address</td>
|
||||
<td>
|
||||
<span t-field="doc.partner_id" t-options="{'widget': 'contact', 'fields': ['address'], 'no_marker': True}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Processes -->
|
||||
<table class="bordered" t-if="doc.process_type_ids">
|
||||
<thead><tr>
|
||||
<th>PROCESSES APPLIED</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td>
|
||||
<t t-foreach="doc.process_type_ids" t-as="pt">
|
||||
<span t-out="pt.name"/>
|
||||
<t t-if="not pt_last">, </t>
|
||||
</t>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Certification Statement -->
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>CERTIFICATION</td></tr>
|
||||
<tr><td style="padding: 16px 12px; font-size: 11pt;">
|
||||
This certifies that the above items were processed in accordance
|
||||
with applicable specifications and meet all requirements as stated
|
||||
in the purchase order. All work was performed in compliance with
|
||||
the quality management system.
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
<!-- Notes -->
|
||||
<t t-if="doc.notes">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>NOTES</td></tr>
|
||||
<tr><td><t t-out="doc.notes"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Signature Block -->
|
||||
<table class="bordered" style="margin-top: 30px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:50%; height: 60px; vertical-align: bottom; font-weight: bold;">
|
||||
Quality Manager Signature: ___________________________
|
||||
</td>
|
||||
<td style="width:50%; height: 60px; vertical-align: bottom; font-weight: bold;">
|
||||
Date: ___________________________
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Discharge Sample Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_discharge_sample">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Discharge Sample Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>SAMPLE #</th>
|
||||
<th>SAMPLE DATE</th>
|
||||
<th>FACILITY</th>
|
||||
<th>SAMPLE POINT</th>
|
||||
<th>STATUS</th>
|
||||
<th>WORST RESULT</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.sample_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.sample_point"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
<td class="text-center">
|
||||
<span t-if="doc.worst_status == 'ok'" class="status-ok">OK</span>
|
||||
<span t-if="doc.worst_status == 'warning'" class="status-warning">Warning</span>
|
||||
<span t-if="doc.worst_status == 'out_of_spec'" class="status-fail">Out of Spec</span>
|
||||
<span t-if="doc.worst_status == 'pending'" style="color: #666;">Pending</span>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Lab Details -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>COLLECTED BY</th>
|
||||
<th>CHAIN OF CUSTODY #</th>
|
||||
<th>LAB</th>
|
||||
<th>LAB REPORT #</th>
|
||||
<th>RESULTS RECEIVED</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.collected_by_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.chain_of_custody_ref"/></td>
|
||||
<td class="text-center"><span t-field="doc.lab_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.lab_report_ref"/></td>
|
||||
<td class="text-center"><span t-field="doc.received_date" t-options="{'widget': 'date'}"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Parameter Lines -->
|
||||
<t t-if="doc.line_ids">
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>PARAMETER</th>
|
||||
<th>RESULT</th>
|
||||
<th>UoM</th>
|
||||
<th>STATUS</th>
|
||||
<th>NOTE</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="doc.line_ids" t-as="line">
|
||||
<tr>
|
||||
<td><span t-field="line.parameter"/></td>
|
||||
<td class="text-center"><span t-field="line.value"/></td>
|
||||
<td class="text-center"><span t-field="line.uom"/></td>
|
||||
<td class="text-center">
|
||||
<span t-if="line.status == 'ok'" class="status-ok">OK</span>
|
||||
<span t-if="line.status == 'warning'" class="status-warning">Warning</span>
|
||||
<span t-if="line.status == 'out_of_spec'" class="status-fail">Out of Spec</span>
|
||||
<span t-if="line.status == 'pending'" style="color: #666;">Pending</span>
|
||||
</td>
|
||||
<td><span t-field="line.notes"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Notes -->
|
||||
<t t-if="doc.notes">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>NOTES</td></tr>
|
||||
<tr><td><t t-out="doc.notes"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
76
fusion_plating/fusion_plating_reports/report/report_fair.xml
Normal file
76
fusion_plating/fusion_plating_reports/report/report_fair.xml
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
First Article Inspection Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_fair">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
First Article Inspection Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>FAIR #</th>
|
||||
<th>PART NUMBER</th>
|
||||
<th>REVISION</th>
|
||||
<th>CUSTOMER</th>
|
||||
<th>RESULT</th>
|
||||
<th>STATUS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.part_number"/></td>
|
||||
<td class="text-center"><span t-field="doc.part_revision"/></td>
|
||||
<td class="text-center"><span t-field="doc.customer_id"/></td>
|
||||
<td class="text-center">
|
||||
<span t-if="doc.result == 'pass'" class="status-ok">Pass</span>
|
||||
<span t-if="doc.result == 'fail'" class="status-fail">Fail</span>
|
||||
<span t-if="doc.result == 'conditional'" class="status-warning">Conditional</span>
|
||||
</td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Inspection Details -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>INSPECTION DATE</th>
|
||||
<th>INSPECTOR</th>
|
||||
<th>PROCESSES</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.performed_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.performed_by_id"/></td>
|
||||
<td class="text-center">
|
||||
<t t-foreach="doc.process_type_ids" t-as="pt">
|
||||
<span t-out="pt.name"/>
|
||||
<t t-if="not pt_last">, </t>
|
||||
</t>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Notes / Findings -->
|
||||
<t t-if="doc.notes">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>FINDINGS / NOTES</td></tr>
|
||||
<tr><td><t t-out="doc.notes"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
107
fusion_plating/fusion_plating_reports/report/report_incident.xml
Normal file
107
fusion_plating/fusion_plating_reports/report/report_incident.xml
Normal file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Incident Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_incident">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Incident Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>INCIDENT #</th>
|
||||
<th>DATE</th>
|
||||
<th>FACILITY</th>
|
||||
<th>TYPE</th>
|
||||
<th>STATUS</th>
|
||||
<th>REPORTED BY</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.incident_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.incident_type"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
<td class="text-center"><span t-field="doc.reported_by_id"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Employee / Location / WSIB -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>EMPLOYEE INVOLVED</th>
|
||||
<th>LOCATION</th>
|
||||
<th>WSIB REPORTABLE</th>
|
||||
<th>WSIB FORM 7 SUBMITTED</th>
|
||||
<th>LOST-TIME DAYS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.employee_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.location"/></td>
|
||||
<td class="text-center">
|
||||
<t t-if="doc.wsib_reportable">Yes</t>
|
||||
<t t-else="">No</t>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<t t-if="doc.wsib_form_7_submitted">Yes</t>
|
||||
<t t-else="">No</t>
|
||||
</td>
|
||||
<td class="text-center"><span t-field="doc.lost_time_days"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Description -->
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>DESCRIPTION</td></tr>
|
||||
<tr><td><t t-out="doc.description"/></td></tr>
|
||||
</table>
|
||||
|
||||
<!-- Immediate Action -->
|
||||
<t t-if="doc.immediate_action">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>IMMEDIATE ACTION</td></tr>
|
||||
<tr><td><t t-out="doc.immediate_action"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Investigation -->
|
||||
<t t-if="doc.investigation">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>INVESTIGATION</td></tr>
|
||||
<tr><td><t t-out="doc.investigation"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Root Cause -->
|
||||
<t t-if="doc.root_cause">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>ROOT CAUSE</td></tr>
|
||||
<tr><td><t t-out="doc.root_cause"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Corrective Action -->
|
||||
<t t-if="doc.corrective_action">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>CORRECTIVE ACTION</td></tr>
|
||||
<tr><td><t t-out="doc.corrective_action"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
121
fusion_plating/fusion_plating_reports/report/report_ncr.xml
Normal file
121
fusion_plating/fusion_plating_reports/report/report_ncr.xml
Normal file
@@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Non-Conformance Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_ncr">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Non-Conformance Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>NCR #</th>
|
||||
<th>STATUS</th>
|
||||
<th>FACILITY</th>
|
||||
<th>SEVERITY</th>
|
||||
<th>SOURCE</th>
|
||||
<th>REPORTED</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.severity"/></td>
|
||||
<td class="text-center"><span t-field="doc.source"/></td>
|
||||
<td class="text-center"><span t-field="doc.reported_date" t-options="{'widget': 'date'}"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Secondary Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>REPORTED BY</th>
|
||||
<th>PART / LOT</th>
|
||||
<th>QTY AFFECTED</th>
|
||||
<th>BATH</th>
|
||||
<th>CUSTOMER</th>
|
||||
<th>DISPOSITION</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.reported_by_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.part_ref"/></td>
|
||||
<td class="text-center"><span t-field="doc.quantity_affected"/></td>
|
||||
<td class="text-center"><span t-field="doc.bath_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.customer_partner_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.disposition"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Description -->
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>DESCRIPTION</td></tr>
|
||||
<tr><td><t t-out="doc.description"/></td></tr>
|
||||
</table>
|
||||
|
||||
<!-- Root Cause -->
|
||||
<t t-if="doc.root_cause">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>ROOT CAUSE</td></tr>
|
||||
<tr><td><t t-out="doc.root_cause"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Containment -->
|
||||
<t t-if="doc.containment">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>CONTAINMENT ACTIONS</td></tr>
|
||||
<tr><td><t t-out="doc.containment"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Linked CAPAs -->
|
||||
<t t-if="doc.capa_ids">
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>LINKED CAPA</th>
|
||||
<th>TYPE</th>
|
||||
<th>STATUS</th>
|
||||
<th>OWNER</th>
|
||||
<th>DUE DATE</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="doc.capa_ids" t-as="capa">
|
||||
<tr>
|
||||
<td><span t-field="capa.name"/></td>
|
||||
<td class="text-center"><span t-field="capa.type"/></td>
|
||||
<td class="text-center"><span t-field="capa.state"/></td>
|
||||
<td class="text-center"><span t-field="capa.owner_id"/></td>
|
||||
<td class="text-center"><span t-field="capa.due_date" t-options="{'widget': 'date'}"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Closed Date -->
|
||||
<t t-if="doc.closed_date">
|
||||
<table class="bordered info-table">
|
||||
<thead><tr><th>CLOSED ON</th></tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.closed_date" t-options="{'widget': 'date'}"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Spill Register Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_spill">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Spill Report
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>SPILL #</th>
|
||||
<th>DATE</th>
|
||||
<th>FACILITY</th>
|
||||
<th>SUBSTANCE</th>
|
||||
<th>QUANTITY</th>
|
||||
<th>UoM</th>
|
||||
<th>STATUS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.spill_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.substance"/></td>
|
||||
<td class="text-center"><span t-field="doc.quantity"/></td>
|
||||
<td class="text-center"><span t-field="doc.uom"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Location & Notification -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>LOCATION</th>
|
||||
<th>REPORTED BY</th>
|
||||
<th>REGULATOR NOTIFIED</th>
|
||||
<th>NOTIFICATION DATE</th>
|
||||
<th>CAPA REF</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.location"/></td>
|
||||
<td class="text-center"><span t-field="doc.reported_by_id"/></td>
|
||||
<td class="text-center">
|
||||
<t t-if="doc.regulator_notified">Yes</t>
|
||||
<t t-else="">No</t>
|
||||
</td>
|
||||
<td class="text-center"><span t-field="doc.regulator_notification_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.capa_ref"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Containment Action -->
|
||||
<t t-if="doc.containment_action">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>CONTAINMENT ACTION</td></tr>
|
||||
<tr><td><span t-field="doc.containment_action"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Root Cause -->
|
||||
<t t-if="doc.root_cause">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>ROOT CAUSE</td></tr>
|
||||
<tr><td><span t-field="doc.root_cause"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<!-- Corrective Action -->
|
||||
<t t-if="doc.corrective_action">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>CORRECTIVE ACTION</td></tr>
|
||||
<tr><td><span t-field="doc.corrective_action"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Waste Manifest Report
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_waste_manifest">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<h2 style="text-align: left;">
|
||||
Waste Manifest
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
<!-- Header Info -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>MANIFEST REF</th>
|
||||
<th>WASTE STREAM</th>
|
||||
<th>FACILITY</th>
|
||||
<th>SHIP DATE</th>
|
||||
<th>STATUS</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.name"/></td>
|
||||
<td class="text-center"><span t-field="doc.waste_stream_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.facility_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.ship_date" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-center"><span t-field="doc.state"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Shipment Details -->
|
||||
<table class="bordered info-table">
|
||||
<thead><tr>
|
||||
<th>QUANTITY</th>
|
||||
<th>UoM</th>
|
||||
<th>CARRIER</th>
|
||||
<th>RECEIVER</th>
|
||||
<th>MANIFEST #</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><span t-field="doc.quantity"/></td>
|
||||
<td class="text-center"><span t-field="doc.uom"/></td>
|
||||
<td class="text-center"><span t-field="doc.carrier_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.receiver_id"/></td>
|
||||
<td class="text-center"><span t-field="doc.manifest_number"/></td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Notes -->
|
||||
<t t-if="doc.notes">
|
||||
<table class="bordered">
|
||||
<tr class="section-row"><td>NOTES</td></tr>
|
||||
<tr><td><t t-out="doc.notes"/></td></tr>
|
||||
</table>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,229 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2026 Nexa Systems Inc.
|
||||
License OPL-1 (Odoo Proprietary License v1.0)
|
||||
Work Order Margin Report — Manufacturing Order
|
||||
-->
|
||||
<odoo>
|
||||
<template id="report_wo_margin">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="d">
|
||||
<t t-call="web.external_layout">
|
||||
<t t-call="fusion_plating_reports.fp_landscape_styles"/>
|
||||
<div class="fp-landscape">
|
||||
<div class="page">
|
||||
<!-- Extra styles for margin report -->
|
||||
<style>
|
||||
.fp-margin-header { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
|
||||
.fp-margin-box {
|
||||
border: 1px solid #ccc; border-radius: 4px;
|
||||
padding: 8px 14px; text-align: center; min-width: 110px;
|
||||
flex: 1;
|
||||
}
|
||||
.fp-margin-box .label { font-size: 8pt; color: #666; text-transform: uppercase; margin-bottom: 2px; }
|
||||
.fp-margin-box .amount { font-size: 13pt; font-weight: bold; }
|
||||
.fp-margin-green { color: #2e7d32; }
|
||||
.fp-margin-yellow { color: #f57f17; }
|
||||
.fp-margin-red { color: #c62828; }
|
||||
</style>
|
||||
|
||||
<h2>
|
||||
Work Order Margin Report
|
||||
<span style="font-size: 14pt; color: #333;">
|
||||
— <t t-out="d['mo'].name"/>
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
<!-- MO Info Line -->
|
||||
<table class="bordered info-table" style="margin-bottom: 14px;">
|
||||
<thead><tr>
|
||||
<th>MO REF</th>
|
||||
<th>PRODUCT</th>
|
||||
<th>QUANTITY</th>
|
||||
<th>STATE</th>
|
||||
<th>SALE ORDER</th>
|
||||
<th>DATE PLANNED</th>
|
||||
</tr></thead>
|
||||
<tbody><tr>
|
||||
<td class="text-center"><t t-out="d['mo'].name"/></td>
|
||||
<td><t t-out="d['mo'].product_id.display_name"/></td>
|
||||
<td class="text-center">
|
||||
<t t-out="'%.2f' % d['mo'].product_qty"/>
|
||||
<t t-out="d['mo'].product_uom_id.name"/>
|
||||
</td>
|
||||
<td class="text-center"><t t-out="d['mo'].state"/></td>
|
||||
<td class="text-center">
|
||||
<t t-if="d['mo'].sale_order_id">
|
||||
<t t-out="d['mo'].sale_order_id.name"/>
|
||||
</t>
|
||||
<t t-else="">—</t>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<t t-if="d['mo'].date_start">
|
||||
<t t-out="d['mo'].date_start" t-options="{'widget': 'date'}"/>
|
||||
</t>
|
||||
<t t-else="">—</t>
|
||||
</td>
|
||||
</tr></tbody>
|
||||
</table>
|
||||
|
||||
<!-- ============================================= -->
|
||||
<!-- HEADER SUMMARY BOXES -->
|
||||
<!-- ============================================= -->
|
||||
<div class="fp-margin-header">
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Revenue</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['revenue']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Part Labour Cost</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['part_labour_cost']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Station Labour Cost</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['station_labour_cost']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Station Operation Cost</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['station_operation_cost']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Inventory Cost</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['inventory_cost']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Outsourcing Cost</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['outsourcing_cost']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Total Cost</div>
|
||||
<div class="amount">$ <t t-out="'%.2f' % d['total_cost']"/></div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Gross Profit</div>
|
||||
<div class="amount"
|
||||
t-attf-style="color: {{ 'green' if d['gross_profit'] >= 0 else 'red' }};">
|
||||
$ <t t-out="'%.2f' % d['gross_profit']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fp-margin-box">
|
||||
<div class="label">Margin %</div>
|
||||
<div t-attf-class="amount {{ 'fp-margin-green' if d['margin_pct'] > 15 else ('fp-margin-red' if d['margin_pct'] < 5 else 'fp-margin-yellow') }}">
|
||||
<t t-out="'%.1f' % d['margin_pct']"/> %
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============================================= -->
|
||||
<!-- MARGIN PER PART NUMBER -->
|
||||
<!-- ============================================= -->
|
||||
<h2 style="font-size: 14pt; margin-top: 20px;">Margin Per Part Number</h2>
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>Part Number</th>
|
||||
<th class="text-center">Count</th>
|
||||
<th class="text-end">SO Total $</th>
|
||||
<th class="text-end">SO $/Part</th>
|
||||
<th class="text-end">Unit Labour Cost</th>
|
||||
<th class="text-end">Part Labour Cost</th>
|
||||
<th class="text-end">Station Labour Cost</th>
|
||||
<th class="text-end">Station Op Cost</th>
|
||||
<th class="text-end">Outsourcing Cost</th>
|
||||
<th class="text-center">Margin %</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="d['part_margins']" t-as="pm">
|
||||
<tr>
|
||||
<td><t t-out="pm['part_number']"/></td>
|
||||
<td class="text-center"><t t-out="pm['count']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['so_total']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['so_per_part']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['unit_labour']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['labour_cost']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['station_labour_cost']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['station_operation_cost']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % pm['outsourcing_cost']"/></td>
|
||||
<td class="text-center"
|
||||
t-attf-style="color: {{ 'green' if pm['margin_pct'] > 15 else ('red' if pm['margin_pct'] < 5 else '#f57f17') }}; font-weight: bold;">
|
||||
<t t-out="'%.1f' % pm['margin_pct']"/> %
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-if="not d['part_margins']">
|
||||
<tr><td colspan="10" class="text-center" style="font-style: italic;">No work order data available.</td></tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- ============================================= -->
|
||||
<!-- COST PER STATION -->
|
||||
<!-- ============================================= -->
|
||||
<h2 style="font-size: 14pt; margin-top: 20px;">Cost Per Station</h2>
|
||||
<table class="bordered">
|
||||
<thead><tr>
|
||||
<th>Station</th>
|
||||
<th class="text-end">Labour Rate ($/hr)</th>
|
||||
<th class="text-end">Part Labour Time</th>
|
||||
<th class="text-end">Part Labour Cost</th>
|
||||
<th class="text-end">Station Labour Cost</th>
|
||||
<th class="text-end">Op Rate ($/hr)</th>
|
||||
<th class="text-end">Station Dwell Time</th>
|
||||
<th class="text-end">Operation Cost</th>
|
||||
<th class="text-end">Total Cost</th>
|
||||
<th class="text-center">Percentage</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<t t-foreach="d['station_costs']" t-as="sc">
|
||||
<tr>
|
||||
<td><t t-out="sc['station']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % sc['labour_rate']"/></td>
|
||||
<td class="text-end">
|
||||
<t t-out="'%.0f' % sc['labour_time']"/> min
|
||||
(<t t-out="'%.2f' % sc['labour_hours']"/> hr)
|
||||
</td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % sc['labour_cost']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % sc['labour_cost']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % sc['operation_rate']"/></td>
|
||||
<td class="text-end">
|
||||
<t t-out="'%.0f' % sc['dwell_time']"/> min
|
||||
(<t t-out="'%.2f' % sc['dwell_hours']"/> hr)
|
||||
</td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % sc['operation_cost']"/></td>
|
||||
<td class="text-end">$ <t t-out="'%.2f' % sc['total_cost']"/></td>
|
||||
<td class="text-center" style="font-weight: bold;">
|
||||
<t t-out="'%.1f' % sc['percentage']"/> %
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-if="not d['station_costs']">
|
||||
<tr><td colspan="10" class="text-center" style="font-style: italic;">No station data available.</td></tr>
|
||||
</t>
|
||||
</tbody>
|
||||
<!-- Totals Row -->
|
||||
<tfoot t-if="d['station_costs']">
|
||||
<tr class="section-row">
|
||||
<td><strong>TOTAL</strong></td>
|
||||
<td/>
|
||||
<td/>
|
||||
<td class="text-end"><strong>$ <t t-out="'%.2f' % sum(s['labour_cost'] for s in d['station_costs'])"/></strong></td>
|
||||
<td class="text-end"><strong>$ <t t-out="'%.2f' % sum(s['labour_cost'] for s in d['station_costs'])"/></strong></td>
|
||||
<td/>
|
||||
<td/>
|
||||
<td class="text-end"><strong>$ <t t-out="'%.2f' % sum(s['operation_cost'] for s in d['station_costs'])"/></strong></td>
|
||||
<td class="text-end"><strong>$ <t t-out="'%.2f' % sum(s['total_cost'] for s in d['station_costs'])"/></strong></td>
|
||||
<td class="text-center"><strong>100 %</strong></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<!-- Report Footer -->
|
||||
<p style="font-size: 8pt; color: #888; margin-top: 20px; text-align: right;">
|
||||
Generated by Fusion Plating — Nexa Systems Inc.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_report_wo_margin_operator,report.wo.margin.operator,model_report_fusion_plating_reports_report_wo_margin,fusion_plating.group_fusion_plating_operator,1,0,0,0
|
||||
|
Reference in New Issue
Block a user