Add Project Status Report to project module for tracking project progress
This commit is contained in:
parent
e0e4ad45a1
commit
aa68fd6c3c
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from . import models
|
from . import models
|
||||||
from . import wizard
|
from . import wizard
|
||||||
|
from .import report
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,3 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import project_status_report
|
||||||
|
|
@ -1,167 +1,454 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<template id="project_detail_qweb_report" name="project_detail_qweb_report">
|
<template id="project_detail_qweb_report" name="project_detail_qweb_report">
|
||||||
<t t-call="web.html_container">
|
<t t-call="web.html_container">
|
||||||
<t t-foreach="docs" t-as="e">
|
<t t-foreach="docs" t-as="e">
|
||||||
<t t-call="web.external_layout">
|
<t t-call="web.external_layout">
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<form>
|
<form>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<tr class="text-center">
|
<tr class="text-center">
|
||||||
<th>
|
<th>
|
||||||
<t t-if="e.name">
|
<t t-if="e.name">
|
||||||
<h2 class="text-center">
|
<h2 class="text-center">
|
||||||
<b>
|
<b>
|
||||||
<span t-field="e.project_no"/>
|
<span t-field="e.project_no"/>
|
||||||
</b>
|
</b>
|
||||||
-
|
-
|
||||||
<b>
|
<b>
|
||||||
<span t-field="e.name"/>
|
<span t-field="e.name"/>
|
||||||
</b>
|
</b>
|
||||||
</h2>
|
</h2>
|
||||||
</t>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<table class="table table-borderless">
|
|
||||||
<tr>
|
|
||||||
<td colspan="4" class="text-muted"><h4>Project Info</h4></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Sale Order</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span t-field="e.sale_order_id.name"/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<b>Project Manager</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span t-field="e.user_id.name"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Customer</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div t-field="e.partner_id" t-options="{"widget": "contact", "fields": ["address", "name"], "no_marker": True}"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<h2>
|
|
||||||
<b>
|
|
||||||
<td colspan="4" class="text-muted"><h4>Project Location Info</h4></td>
|
|
||||||
</b>
|
|
||||||
</h2>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Country</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span t-field="e.country_id.name"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Project Category</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<t t-if="e.category_id">
|
|
||||||
<span t-field="e.category_id.name"/>
|
|
||||||
</t>
|
</t>
|
||||||
</td>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<table class="table table-borderless">
|
||||||
<h2>
|
|
||||||
<b>
|
|
||||||
<td colspan="4" class="text-muted"><h4>Project Schedule Duration</h4></td>
|
|
||||||
</b>
|
|
||||||
</h2>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Start Date</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span t-field="e.start"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Finish Date</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span t-field="e.date"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<b>Kick-Off Date</b>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span t-field="e.launch_date"/>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<p style="page-break-before:always;"> </p>
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<tr>
|
|
||||||
<h2>
|
|
||||||
<b>
|
|
||||||
<td colspan="4" class="text-muted"><h4>Project Stages</h4></td>
|
|
||||||
</b>
|
|
||||||
</h2>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<b>#</b>
|
|
||||||
</td>
|
|
||||||
<td colspan="2">
|
|
||||||
<b>stage</b>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<t t-set="counter" t-value="0"/>
|
|
||||||
<t t-foreach="e.project_phase_ids" t-as="p">
|
|
||||||
<t t-set="counter" t-value="counter + 1"/>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="4" class="text-muted">
|
||||||
<span t-esc="counter"/>
|
<h4>Project Info</h4>
|
||||||
</td>
|
|
||||||
<td colspan="2">
|
|
||||||
<span t-esc="p.name"/>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Sale Order</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span t-field="e.sale_order_id.name"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<b>Project Manager</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span t-field="e.user_id.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Customer</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div t-field="e.partner_id"
|
||||||
|
t-options="{"widget": "contact", "fields": ["address", "name"], "no_marker": True}"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<h2>
|
||||||
|
<b>
|
||||||
|
<td colspan="4" class="text-muted">
|
||||||
|
<h4>Project Location Info</h4>
|
||||||
|
</td>
|
||||||
|
</b>
|
||||||
|
</h2>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Country</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span t-field="e.country_id.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Project Category</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<t t-if="e.category_id">
|
||||||
|
<span t-field="e.category_id.name"/>
|
||||||
|
</t>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<h2>
|
||||||
|
<b>
|
||||||
|
<td colspan="4" class="text-muted">
|
||||||
|
<h4>Project Schedule Duration</h4>
|
||||||
|
</td>
|
||||||
|
</b>
|
||||||
|
</h2>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Start Date</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span t-field="e.start"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Finish Date</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span t-field="e.date"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<b>Kick-Off Date</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span t-field="e.launch_date"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p style="page-break-before:always;"></p>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<h2>
|
||||||
|
<b>
|
||||||
|
<td colspan="4" class="text-muted">
|
||||||
|
<h4>Project Stages</h4>
|
||||||
|
</td>
|
||||||
|
</b>
|
||||||
|
</h2>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<b>#</b>
|
||||||
|
</td>
|
||||||
|
<td colspan="2">
|
||||||
|
<b>stage</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<t t-set="counter" t-value="0"/>
|
||||||
|
<t t-foreach="e.project_phase_ids" t-as="p">
|
||||||
|
<t t-set="counter" t-value="counter + 1"/>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<span t-esc="counter"/>
|
||||||
|
</td>
|
||||||
|
<td colspan="2">
|
||||||
|
<span t-esc="p.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</table>
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<h2>
|
||||||
|
<b>
|
||||||
|
<td colspan="4" class="text-muted">
|
||||||
|
<h4>Description</h4>
|
||||||
|
</td>
|
||||||
|
</b>
|
||||||
|
</h2>
|
||||||
|
</tr>
|
||||||
|
<tr rowspan="4">
|
||||||
|
<td colspan="4">
|
||||||
|
<span t-field="e.description"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="project_status_qweb_report" name="project_status_qweb_report">
|
||||||
|
<t t-call="web.html_container">
|
||||||
|
<t t-foreach="docs" t-as="e">
|
||||||
|
<t t-call="web.external_layout">
|
||||||
|
<t t-set="e" t-value="e.with_context(lang= e.env.lang)"/>
|
||||||
|
<style type="text/css">
|
||||||
|
.report-section {
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 15px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="page" style="font-family:'Sakkal Majalla'!important;font-size:15pt">
|
||||||
|
<h2>
|
||||||
|
<strong>Project Status Report:
|
||||||
|
<span t-field="e.project_no"/>
|
||||||
|
</strong>
|
||||||
|
</h2>
|
||||||
|
<div class="row" style="display: flex; margin-top: 20px;">
|
||||||
|
<div style="width: 55%; padding-right: 15px;">
|
||||||
|
<table class="table table-condensed table-bordered"
|
||||||
|
style="width: 100%; margin-top: 20px;page-break-inside: avoid;border: 2px solid black; border-collapse: collapse;">
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Project Name</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Project Category</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.category_id.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Department</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.department_id.display_name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Project Manager</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.user_id.name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Executive Department</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.department_execute_id.display_name"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Project Start Date</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.start"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Project End Date</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-field="e.date"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Completion Percentage</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<t t-esc="e.progress"/>%
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="width: 45%; display: flex; align-items: center; justify-content: center; flex-direction: column;">
|
||||||
|
<t t-if="not chart_map.get(e.id)">
|
||||||
|
<p style="color: red;">No chart image available</p>
|
||||||
</t>
|
</t>
|
||||||
|
<img t-if="chart_map.get(e.id)"
|
||||||
|
t-att-src="'data:image/png;base64,%s' % to_text(chart_map.get(e.id))"
|
||||||
|
style="max-width: 400px;"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="report-section">
|
||||||
|
|
||||||
|
<h4>
|
||||||
|
<strong>Project Stages</strong>
|
||||||
|
</h4>
|
||||||
|
<table class="table table-condensed table-bordered"
|
||||||
|
style="width: 100%; margin-top: 20px;page-break-inside: avoid;border: 2px solid black; border-collapse: collapse;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Stage</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Start Date</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">End Date</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Weight</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Completion</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Task</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<t t-foreach="e.project_phase_ids" t-as="phase">
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="phase.phase_id.name"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="phase.start_date"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="phase.end_date"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="phase.weight"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span><t t-esc="phase.progress"/>%
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="phase.task_count"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<table class="table table-borderless">
|
</div>
|
||||||
|
|
||||||
|
<div class="report-section">
|
||||||
|
<h4>
|
||||||
|
<strong>Project Payments</strong>
|
||||||
|
</h4>
|
||||||
|
<table class="table table-condensed table-bordered"
|
||||||
|
style="width: 100%; margin-top: 20px;page-break-inside: avoid;border: 2px solid black; border-collapse: collapse;"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<h2>
|
<td style="border: 1px solid black;">
|
||||||
<b>
|
<span style="font-weight: bold;">Contract Amount</span>
|
||||||
<td colspan="4" class="text-muted"><h4>Description</h4></td>
|
</td>
|
||||||
</b>
|
<td style="border: 1px solid black;">
|
||||||
</h2>
|
<span t-esc="e.contract_value_untaxed"/>
|
||||||
</tr>
|
</td>
|
||||||
<tr rowspan="4">
|
<td style="border: 1px solid black;">
|
||||||
<td colspan="4">
|
<span style="font-weight: bold;">Consultant Fees</span>
|
||||||
<span t-field="e.description"/>
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="e.consultant_cost"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Tax amount</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="e.tax_amount"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Total</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="e.contract_value"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Additional Work Amount</span>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<!-- <span t-esc="(e.total_invoiced_amount or 0) - (e.contract_value or 0) + (e.contract_value or 0)"/>-->
|
||||||
|
|
||||||
|
<t t-set="invoiced" t-value="e.total_invoiced_amount - e.contract_value"/>
|
||||||
|
<t t-set="additional_work" t-value="abs(invoiced + e.consultant_cost)"/>
|
||||||
|
<span t-esc="additional_work"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;"/>
|
||||||
|
<td style="border: 1px solid black;"/>
|
||||||
|
</tr>
|
||||||
|
<tr/>
|
||||||
|
</table>
|
||||||
|
<table class="table table-condensed table-bordered"
|
||||||
|
style="width: 100%; margin-top: 20px;page-break-inside: avoid;border: 2px solid black; border-collapse: collapse;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Payment</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Due Date</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Amount</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Tax</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Total</span>
|
||||||
|
</th>
|
||||||
|
<th style="border: 1px solid black;">
|
||||||
|
<span style="font-weight: bold;">Payment Status</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<t t-foreach="e.invoice_ids" t-as="invoice">
|
||||||
|
<tr>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="invoice.name"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="invoice.plan_date"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<t t-set="subtotal" t-value="0"/>
|
||||||
|
<t t-foreach="invoice.project_invline_ids" t-as="line">
|
||||||
|
<t t-set="subtotal" t-value="subtotal + line.price_subtotal"/>
|
||||||
|
</t>
|
||||||
|
<span t-esc="subtotal"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<t t-set="tax_total" t-value="0"/>
|
||||||
|
<t t-foreach="invoice.project_invline_ids" t-as="line">
|
||||||
|
<t t-set="tax_total" t-value="tax_total + line.price_tax"/>
|
||||||
|
</t>
|
||||||
|
<span t-esc="tax_total"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="invoice.amount"/>
|
||||||
|
</td>
|
||||||
|
<td style="border: 1px solid black;">
|
||||||
|
<span t-esc="invoice.payment_state"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="report-section">
|
||||||
|
<h4>
|
||||||
|
<strong>Project Details</strong>
|
||||||
|
</h4>
|
||||||
|
<span t-field="e.description"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</t>
|
||||||
</div>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</template>
|
||||||
</t>
|
|
||||||
</template>
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@
|
||||||
file="project_base.project_detail_qweb_report"
|
file="project_base.project_detail_qweb_report"
|
||||||
string="Project Charter"/>
|
string="Project Charter"/>
|
||||||
|
|
||||||
|
<report id="report_project_status"
|
||||||
|
model="project.project"
|
||||||
|
report_type="qweb-pdf"
|
||||||
|
name="project_base.project_status_qweb_report"
|
||||||
|
file="project_base.project_status_qweb_report"
|
||||||
|
string="Project Status Report"/>
|
||||||
|
|
||||||
<record id="paperformat_project_invoice" model="report.paperformat">
|
<record id="paperformat_project_invoice" model="report.paperformat">
|
||||||
<field name="name">A4 for E-Invoice</field>
|
<field name="name">A4 for E-Invoice</field>
|
||||||
<field name="default" eval="False"/>
|
<field name="default" eval="False"/>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import UserError, ValidationError, Warning
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import io
|
||||||
|
import base64
|
||||||
|
import matplotlib
|
||||||
|
matplotlib.use('Agg')
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import os
|
||||||
|
import arabic_reshaper
|
||||||
|
from bidi.algorithm import get_display
|
||||||
|
from odoo.modules.module import get_module_resource
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ReportProjectStatus(models.AbstractModel):
|
||||||
|
_name = 'report.project_base.project_status_qweb_report'
|
||||||
|
_description = 'Project Status QWeb Report'
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _get_report_values(self, docids, data=None):
|
||||||
|
projects = self.env['project.project'].browse(docids)
|
||||||
|
chart_map = {}
|
||||||
|
|
||||||
|
for project in projects:
|
||||||
|
try:
|
||||||
|
chart = self._get_chart_image(project)
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error(f"Chart error for project {project.id}: {str(e)}")
|
||||||
|
chart = False
|
||||||
|
|
||||||
|
chart_map[project.id] = chart
|
||||||
|
|
||||||
|
return {
|
||||||
|
'doc_ids': docids,
|
||||||
|
'doc_model': 'project.project',
|
||||||
|
'docs': projects,
|
||||||
|
'chart_map': chart_map,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _get_chart_image(self, project):
|
||||||
|
_logger.info(
|
||||||
|
f"Task counts - New: {project.task_count_new}, In Progress: {project.task_count_inprogress}, Done: {project.task_count_finished}")
|
||||||
|
|
||||||
|
task_data = {
|
||||||
|
'new': project.task_count_new or 0,
|
||||||
|
'in_progress': project.task_count_inprogress or 0,
|
||||||
|
'done': project.task_count_finished or 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if sum(task_data.values()) == 0:
|
||||||
|
_logger.warning("All task counts are zero, using dummy data")
|
||||||
|
task_data = {'new': 1, 'in_progress': 1, 'done': 1}
|
||||||
|
|
||||||
|
font_path = os.path.join(os.path.dirname(__file__), 'img', 'amiri-regular.ttf')
|
||||||
|
if not os.path.exists(font_path):
|
||||||
|
font_path = get_module_resource('project_base', 'static/fonts', 'amiri-regular.ttf')
|
||||||
|
if not font_path:
|
||||||
|
_logger.warning("Arabic font not found. Using default font.")
|
||||||
|
font_path = None
|
||||||
|
|
||||||
|
if font_path:
|
||||||
|
prop = matplotlib.font_manager.FontProperties(fname=font_path)
|
||||||
|
else:
|
||||||
|
prop = None
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(5, 4))
|
||||||
|
|
||||||
|
def format_arabic(text):
|
||||||
|
reshaped_text = arabic_reshaper.reshape(text)
|
||||||
|
bidi_text = get_display(reshaped_text)
|
||||||
|
return bidi_text
|
||||||
|
|
||||||
|
arabicLabels = ['جديد', 'قيد التنفيذ', 'تم']
|
||||||
|
labels = [format_arabic(label) for label in arabicLabels]
|
||||||
|
sizes = [task_data['new'], task_data['in_progress'], task_data['done']]
|
||||||
|
colors = ['#f0312e', '#add8e6', '#90ee90']
|
||||||
|
|
||||||
|
plt.pie(sizes, labels=labels, autopct='%1.1f%%', colors=colors, startangle=90,
|
||||||
|
textprops={'fontproperties': prop, 'fontsize': 16} if prop else {'fontsize': 16})
|
||||||
|
plt.axis('equal')
|
||||||
|
plt.rcParams['font.size'] = 18
|
||||||
|
title_text = format_arabic('احصائيات المهام')
|
||||||
|
plt.title(title_text, fontproperties=prop if prop else None)
|
||||||
|
|
||||||
|
buffer = io.BytesIO()
|
||||||
|
plt.savefig(buffer, format='png', bbox_inches='tight', dpi=300)
|
||||||
|
plt.close('all')
|
||||||
|
|
||||||
|
chart_image = base64.b64encode(buffer.getvalue()).decode('utf-8')
|
||||||
|
buffer.close()
|
||||||
|
|
||||||
|
_logger.info(f"Generated chart image with base64 length: {len(chart_image)}")
|
||||||
|
|
||||||
|
return chart_image
|
||||||
Binary file not shown.
Loading…
Reference in New Issue