[IMP] hr_expense: improve expense report by grouping by employee-state-currency

This commit is contained in:
Cedric Snauwaert
2016-01-06 10:08:11 +01:00
parent eb8c674d63
commit a81d6121aa
4 changed files with 121 additions and 41 deletions
+1
View File
@@ -2,4 +2,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import models
import report
import wizard
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import hr_expense_report
@@ -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
+56 -41
View File
@@ -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>