I need to generate timesheets report for a given user in a given data range. And I also need to sum the timesheets hours by date so each row in the report has unique date.
I have simple report ready as well as wizard for picking particular user and dates.
But I'm having trouble with actually generating report in Python and passing data to the report. When I click the print button on my wizard I get this error:
ProgrammingError: relation "hr_timesheet_karty_wizard" does not exist
LINE 1: INSERT INTO "hr_timesheet_karty_wizard" ("id", "date_from", ...
What I'm doing wrong?
I'm not really sure what to do with records
. Should I put them in 'doc_ids' or 'docs'?
How to sum the records by dates?
I'm using Odoo 8.
Here is my python code:
# __init__.py
# -*- coding: utf-8 -*-
from . import wizard
# wizard/__init__.py
# -*- coding: utf-8 -*-
from . import wizard_karty
# wizard/wizard_karty.py
from openerp import api, models, fields
from datetime import datetime
class hr_timesheet_karty_wizard(models.AbstractModel):
_name = 'hr.timesheet.karty.wizard'
employee_id = fields.Many2one(comodel_name="hr.employee", required=True)
date_from = fields.Date(default=fields.Datetime.now, required=True)
date_to = fields.Date(default=fields.Datetime.now, required=True)
@api.multi
def print_report(self, data=None):
records = self.env['hr.analytic.timesheet'].search([('employee_id', '=', self.employee_id),('date_from', '>=', self.date_from),('date_to', '<=', self.date_to)])
# sum records hours if date is the same (group by date)
report_obj = self.env['report']
report = report_obj._get_report_from_name('hr_timesheet_karty.template_hr_timesheet_karty')
docargs = {
'doc_ids': self._ids,
'doc_model': report.model,
'docs': records,
}
return report_obj.render('hr_timesheet_karty.template_hr_timesheet_karty', docargs)
Here is my wizard:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_hr_timesheet_karty_wizard" model="ir.ui.view">
<field name="name">hr.timesheet.karty.wizard.form</field>
<field name="model">hr.timesheet.karty.wizard</field>
<field name="arch" type="xml">
<form string="Leaves by Department">
<group>
<field name="employee_id"/>
<field name="date_from"/>
<field name="date_to"/>
</group>
<footer>
<button name="print_report" string="Print" type="object" class="oe_highlight"/> or
<button string="Cancel" special="cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
<record id="action_hr_timesheet_karty_wizard" model="ir.actions.act_window">
<field name="name">Time sheet report</field>
<field name="res_model">hr.timesheet.karty.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_hr_timesheet_karty_wizard"/>
<field name="target">new</field>
</record>
<menuitem id="menu_hr_timesheet_karty_wizard"
name="Time sheet report"
parent="hr.menu_hr_reporting_timesheet"
action="action_hr_timesheet_karty_wizard"
sequence="1"
icon="STOCK_PRINT"/>
</data>
</openerp>
And here is my report:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<report
id="action_hr_timesheet_karty"
string="Time sheet report"
model="hr.analytic.timesheet"
report_type="qweb-pdf"
name="hr_timesheet_karty.template_report_hr_timesheet_karty"
/>
<template id="template_hr_timesheet_karty">
<t t-call="report.html_container">
<t t-call="report.external_layout">
<div class="page">
<table class="table table-condensed">
<thead>
<tr>
<th>User</th>
<th>Date</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr t-foreach="docs" t-as="o">
<td><span t-field="o.user_id.name"/></td>
<td><span t-field="o.date"/></td>
<td class="text-right"><span t-field="o.unit_amount"/> h</td>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</template>
</data>
</openerp>
Please help
Abstract Model super-class for creating an abstract class meant to be inherited by regular models (Models or TransientModels) but not meant to be usable on its own or persisted.
_auto = False
# don't create any database backend for AbstractModels_register = False
# not visible in ORM registry, meant to be python-inherited onlyTransientModel
is used for temporary data, stored in the database but automatically vacuumed every so often.
You need to use TransientModel
instead of AbstractModel
.
class hr_timesheet_karty_wizard(models.TransientModel):
_name = 'hr.timesheet.karty.wizard'
The print_report
method looks like the render_html
method of qweb report parser.
Change print_report
to :
@api.multi
def print_report(self):
self.ensure_one()
datas = {'wizard_id': self.id}
return self.env['report'].get_action(self, 'hr_timesheet_karty.template_hr_timesheet_karty', data=datas)
Add a report parser:
class HrTimesheetKartyReport(models.AbstractModel):
_name = 'report.hr_timesheet_karty.template_hr_timesheet_karty'
@api.multi
def render_html(self, data=None):
hr_analytic_timesheet = self.env['hr.analytic.timesheet']
if data and 'wizard_id' in data:
wizard = self.env['hr.timesheet.karty.wizard'].browse(data['wizard_id'])
records = hr_analytic_timesheet.search([('employee_id', '=', wizard.employee_id.id),
('date_from', '>=', wizard.date_from),
('date_to', '<=', wizard.date_to)])
else:
records = hr_analytic_timesheet.browse(self._ids)
# sum records hours if date is the same (group by date)
report_obj = self.env['report']
report = report_obj._get_report_from_name('hr_timesheet_karty.template_hr_timesheet_karty')
docargs = {
'doc_ids': self._ids,
'doc_model': report.model,
'docs': records,
}
return report_obj.render('hr_timesheet_karty.template_hr_timesheet_karty', docargs)
Change report action name and template id to hr_timesheet_karty.template_hr_timesheet_karty
.
<report
id="action_hr_timesheet_karty"
string="Time sheet report"
model="hr.analytic.timesheet"
report_type="qweb-pdf"
name="hr_timesheet_karty.template_hr_timesheet_karty"
/>
<template id="template_hr_timesheet_karty">