diff options
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/hr_expense/__init__.py | 1 | ||||
| -rw-r--r-- | addons/hr_expense/report/__init__.py | 4 | ||||
| -rw-r--r-- | addons/hr_expense/report/hr_expense_report.py | 60 | ||||
| -rw-r--r-- | addons/hr_expense/views/report_expense.xml | 97 |
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> |
