summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/hr_expense/__init__.py1
-rw-r--r--addons/hr_expense/report/__init__.py4
-rw-r--r--addons/hr_expense/report/hr_expense_report.py60
-rw-r--r--addons/hr_expense/views/report_expense.xml97
4 files changed, 121 insertions, 41 deletions
diff --git a/addons/hr_expense/__init__.py b/addons/hr_expense/__init__.py
index 11529f98733..d84fb182e8f 100644
--- a/addons/hr_expense/__init__.py
+++ b/addons/hr_expense/__init__.py
@@ -2,4 +2,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import models
+import report
import wizard
diff --git a/addons/hr_expense/report/__init__.py b/addons/hr_expense/report/__init__.py
new file mode 100644
index 00000000000..7f74fc905a4
--- /dev/null
+++ b/addons/hr_expense/report/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import hr_expense_report \ No newline at end of file
diff --git a/addons/hr_expense/report/hr_expense_report.py b/addons/hr_expense/report/hr_expense_report.py
new file mode 100644
index 00000000000..1422abf9aa5
--- /dev/null
+++ b/addons/hr_expense/report/hr_expense_report.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import time
+from openerp.osv import osv
+from openerp.tools.misc import formatLang
+from openerp.tools.translate import _
+from openerp.report import report_sxw
+from openerp.exceptions import UserError
+
+
+class report_expense(report_sxw.rml_parse):
+
+ def set_context(self, objects, data, ids, report_type=None):
+ res = super(report_expense, self).set_context(objects, data, ids, report_type=report_type)
+
+ hr_expense_obj = self.pool.get('hr.expense')
+
+ context = {'lang': self.pool.get('res.users').browse(self.cr, self.uid, self.uid).lang}
+ state_field = hr_expense_obj.fields_get(self.cr, self.uid, 'state', context=context)['state']['selection']
+ state_dict = {}
+ for state_tuple in state_field:
+ state_dict[state_tuple[0]] = state_tuple[1]
+
+ expenses_info = {}
+ expenses = hr_expense_obj.search(self.cr, self.uid, [('id', 'in', ids)], order="employee_id, currency_id, state, date")
+ for expense in hr_expense_obj.browse(self.cr, self.uid, expenses):
+ key = expense.employee_id.name + '-' + expense.currency_id.name + '-' + expense.state
+ if expenses_info.get(key):
+ expenses_info[key]['lines'] += expense
+ expenses_info[key]['total_amount'] += expense.total_amount
+ else:
+ expenses_info[key] = {
+ 'employee_name': expense.employee_id.name,
+ 'total_amount': expense.total_amount,
+ 'lines': expense,
+ 'currency': expense.currency_id,
+ 'validator_name': expense.employee_id.parent_id.name,
+ 'notes': [],
+ 'notes_index': {},
+ 'state': state_dict[expense.state],
+ }
+ if expense.description:
+ index = len(expenses_info[key]['notes']) + 1
+ expenses_info[key]['notes'].append({'description': expense.description, 'index':index})
+ expenses_info[key]['notes_index'][expense.id] = index
+
+ # Qweb for-each do not work on dict, so we send a list and we sort it by the name of the employee
+ # that way if we have two sheet for the same employee they will follow in the report
+ self.localcontext.update({
+ 'get_expenses': lambda : [v for k,v in sorted(expenses_info.items())],
+ })
+ return res
+
+
+class report_hr_expense(osv.AbstractModel):
+ _name = 'report.hr_expense.report_expense'
+ _inherit = 'report.abstract_report'
+ _template = 'hr_expense.report_expense'
+ _wrapped_report_class = report_expense
diff --git a/addons/hr_expense/views/report_expense.xml b/addons/hr_expense/views/report_expense.xml
index 27927d6d15c..78a0402a2ad 100644
--- a/addons/hr_expense/views/report_expense.xml
+++ b/addons/hr_expense/views/report_expense.xml
@@ -2,7 +2,7 @@
<odoo>
<template id="report_expense">
<t t-call="report.html_container">
- <t t-foreach="docs" t-as="o">
+ <t t-foreach="get_expenses()" t-as="o">
<t t-call="report.external_layout">
<div class="page">
<h2>HR Expenses</h2>
@@ -10,25 +10,26 @@
<div class="row mt32 mb32">
<div class="col-xs-3">
<strong>Employee:</strong>
- <p t-field="o.employee_id.name"/>
+ <p t-esc="o['employee_name']"/>
</div>
<div class="col-xs-3">
- <strong>Date:</strong>
- <p t-field="o.date"/>
+ <strong>Manager:</strong>
+ <p t-esc="o['validator_name']"/>
</div>
<div class="col-xs-3">
- <strong>Description:</strong>
- <p t-field="o.name"/>
+ <strong>Status:</strong>
+ <p t-esc="o['state']"/>
</div>
<div class="col-xs-3">
- <strong>Validated By:</strong>
- <p t-field="o.employee_id.parent_id.name"/>
+ <strong>Currency:</strong>
+ <p t-field="o['currency'].name"/>
</div>
</div>
<table class="table table-condensed">
<thead>
<tr>
+ <th>Date</th>
<th>Name</th>
<th>Unit Price</th>
<th class="text-center">Qty</th>
@@ -38,35 +39,46 @@
</tr>
</thead>
<tbody>
- <tr>
- <td>
- <span t-field="o.name"/>
- <span t-field="o.analytic_account_id.name"/>
- </td>
- <td>
- <span t-field="o.unit_amount"/>
- </td>
- <td class="text-center">
- <span t-field="o.quantity"/>
- </td>
- <td groups="product.group_uom">
- <span t-field="o.product_uom_id"/>
- </td>
- <td>
- <t t-foreach="o.tax_ids" t-as="tax">
- <t t-if="tax.description">
- <span t-field="tax.description"/>
- </t>
- <t t-if="not tax.description">
- <span t-field="tax.name"/>
- </t>
- </t>
- </td>
- <td class="text-right">
- <span t-field="o.total_amount"
- t-field-options='{"widget": "monetary", "display_currency":"o.currency_id"}'/>
- </td>
- </tr>
+ <t t-foreach="o['lines']" t-as="line">
+ <tr>
+ <td>
+ <span t-field='line.date'/>
+ <t t-if="line.description">
+ <sup><span t-esc="o['notes_index'][line.id]"/></sup>
+ </t>
+ </td>
+ <td>
+ <span t-field="line.name"/>
+ <t t-if="line.analytic_account_id.name">
+ (<span t-field="line.analytic_account_id.name"/>)
+ </t>
+ </td>
+ <td>
+ <span t-field="line.unit_amount"
+ t-field-options='{"widget": "monetary", "display_currency":"line.currency_id"}'/>
+ </td>
+ <td class="text-center">
+ <span t-field="line.quantity"/>
+ </td>
+ <td groups="product.group_uom">
+ <span t-field="line.product_uom_id"/>
+ </td>
+ <td>
+ <t t-foreach="line.tax_ids" t-as="tax">
+ <t t-if="tax.description">
+ <span t-field="tax.description"/>
+ </t>
+ <t t-if="not tax.description">
+ <span t-field="tax.name"/>
+ </t>
+ </t>
+ </td>
+ <td class="text-right">
+ <span t-field="line.total_amount"
+ t-field-options='{"widget": "monetary", "display_currency":"line.currency_id"}'/>
+ </td>
+ </tr>
+ </t>
</tbody>
</table>
@@ -76,15 +88,18 @@
<tr class="border-black">
<td><strong>Total</strong></td>
<td class="text-right">
- <span t-field="o.total_amount"
- t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
+ <span t-esc="formatLang(o['total_amount'], currency_obj=o['currency'])"/>
</td>
</tr>
</table>
</div>
</div>
-
- <p t-field="o.description"/>
+ <t t-foreach="o['notes']" t-as="note">
+ <span t-esc="note['index']"/>. <span t-esc="note['description']"/>
+ <br/>
+ </t>
+ <br/>
+ <br/>
<p>Certified honest and conform,<br/>(Date and signature).<br/><br/></p>
<p>This document must be dated and signed for reimbursement.</p>
</div>