[ADD] hr_fleet: Add claim report and cars history per employee

Purpose
=======

When an employee leaves the company, the fleet manager must ask to the insurance company
a claim report for this employee. But in oddo, there is no easy way to have an history
of the drivers.

Specification
=============

1/ On the employee form, add a stat button: "x cars". The button shouldn't be displayed if the count = 0.
   Make a bridge (auto_install: True in the manifest) depending on hr (hr.employee) and fleet (fleet.vehicle.assignation.log)
   - Add a field employee_cars_count (computed) to count the amount of cars the employee drove.
   - Add an method action_open_employee_cars, that return an action (ir.actions.act_window)
     that open on the fleet.vehicle kanban filtered on cars the employee had driven.
2/ In this bridge module, add on the fleet.vehicle.assignation.logs a button (like in expense) to upload
   documents about the car for a particular employee (PV, rapport d'assurance, blabla). On the employee
   form view, add an action button (with groups fleet_manager) to print all the related documents
   (all the attachements on the fleet.vehicle.assignation.logs for the employee).

closes odoo/odoo#28077
This commit is contained in:
jbm-odoo
2018-11-06 13:01:57 +00:00
committed by Yannick Tivisse
parent 564c3867de
commit 22ee6ebbfc
9 changed files with 204 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import controllers
from . import models
+15
View File
@@ -0,0 +1,15 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Fleet History',
'version': '1.0',
'category': 'Human Resources',
'summary': 'Get history of driven cars for employees',
'description': "",
'depends': ['hr', 'fleet'],
'data': [
'views/employee_views.xml',
'views/fleet_vehicle_views.xml',
],
'auto_install': True,
}
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import main
+72
View File
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import io
from odoo import _
from odoo.http import request, route, Controller
from PyPDF2 import PdfFileReader, PdfFileWriter
from reportlab.pdfgen import canvas
class HrFleet(Controller):
@route(["/fleet/print_claim_report/<int:employee_id>"], type='http', auth='user')
def get_claim_report_user(self, employee_id, **post):
if not request.env.user.has_group('fleet.fleet_group_manager'):
return request.not_found()
employee = request.env['hr.employee'].search([('id', '=', employee_id)], limit=1)
partner_id = employee.user_id.partner_id.id
if not employee or not partner_id:
return request.not_found()
car_assignation_logs = request.env['fleet.vehicle.assignation.log'].search([('driver_id', '=', partner_id)])
doc_list = request.env['ir.attachment'].search([
('res_model', '=', 'fleet.vehicle.assignation.log'),
('res_id', 'in', car_assignation_logs.ids)], order='create_date')
writer = PdfFileWriter()
font = "Helvetica"
normal_font_size = 14
for document in doc_list:
car_line_doc = request.env['fleet.vehicle.assignation.log'].browse(document.res_id)
try:
reader = PdfFileReader(io.BytesIO(base64.b64decode(document.datas)), strict=False, overwriteWarnings=False)
except Exception:
continue
width = float(reader.getPage(0).mediaBox.getUpperRight_x())
height = float(reader.getPage(0).mediaBox.getUpperRight_y())
header = io.BytesIO()
can = canvas.Canvas(header)
can.setFont(font, normal_font_size)
can.setFillColorRGB(1, 0, 0)
car_name = car_line_doc.vehicle_id.display_name
date_start = car_line_doc.date_start
date_end = car_line_doc.date_end or '...'
text_to_print = _("%s (driven from: %s to %s)") % (car_name, date_start, date_end)
can.drawCentredString(width / 2, height - normal_font_size, text_to_print)
can.save()
header_pdf = PdfFileReader(header, overwriteWarnings=False)
for page_number in range(0, reader.getNumPages()):
page = reader.getPage(page_number)
page.mergePage(header_pdf.getPage(0))
writer.addPage(page)
_buffer = io.BytesIO()
writer.write(_buffer)
merged_pdf = _buffer.getvalue()
_buffer.close()
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(merged_pdf))]
return request.make_response(merged_pdf, headers=pdfhttpheaders)
+5
View File
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import employee
from . import fleet_vehicle_assignation_log
+39
View File
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class Employee(models.Model):
_inherit = 'hr.employee'
employee_cars_count = fields.Integer(compute="_compute_employee_cars_count", string="Cars", group="fleet_manager")
def action_open_employee_cars(self):
self.ensure_one()
cars = self.env['fleet.vehicle.assignation.log'].search([
('driver_id', '=', self.user_id.partner_id.id)]).mapped('vehicle_id')
return {
"type": "ir.actions.act_window",
"res_model": "fleet.vehicle",
"views": [[False, "kanban"], [False, "form"], [False, "tree"]],
"domain": [("id", "in", cars.ids)],
"name": "History Employee Cars",
}
def _compute_employee_cars_count(self):
driver_ids = self.mapped('user_id.partner_id').ids
fleet_data = self.env['fleet.vehicle.assignation.log'].read_group(
domain=[('driver_id', 'in', driver_ids)], fields=['driver_id'], groupby=['driver_id'])
mapped_data = dict([(m['driver_id'][0], m['driver_id_count']) for m in fleet_data])
for employee in self:
employee.employee_cars_count = mapped_data.get(employee.user_id.partner_id.id, 0)
def action_get_claim_report(self):
self.ensure_one()
return {
'name': 'Claim Report',
'type': 'ir.actions.act_url',
'url': '/fleet/print_claim_report/%(employee_id)s' % {'employee_id': self.id},
}
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class FleetVehicleAssignationLog(models.Model):
_inherit = 'fleet.vehicle.assignation.log'
attachment_number = fields.Integer('Number of Attachments', compute='_compute_attachment_number')
def _compute_attachment_number(self):
attachment_data = self.env['ir.attachment'].read_group([
('res_model', '=', 'fleet.vehicle.assignation.log'),
('res_id', 'in', self.ids)], ['res_id'], ['res_id'])
attachment = dict((data['res_id'], data['res_id_count']) for data in attachment_data)
for doc in self:
doc.attachment_number = attachment.get(doc.id, 0)
def action_get_attachment_view(self):
self.ensure_one()
res = self.env['ir.actions.act_window'].for_xml_id('base', 'action_attachment')
res['domain'] = [('res_model', '=', 'fleet.vehicle.assignation.log'), ('res_id', 'in', self.ids)]
res['context'] = {'default_res_model': 'fleet.vehicle.assignation.log', 'default_res_id': self.id}
return res
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_employee_form" model="ir.ui.view">
<field name="name">hr.employee.form.inherit.hr.fleet</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form" />
<field name="arch" type="xml">
<xpath expr="//sheet" position="before">
<header>
<button name="action_get_claim_report" string="Claim Report"
type="object" groups="fleet.fleet_group_manager"
attrs="{'invisible': [('employee_cars_count','=', 0)]}"
confirm="This report will contain only PDF files. If you want all documents, please go on vehicle page. Do you want to proceed?"/>
</header>
</xpath>
<xpath expr="//button[@name='toggle_active']" position="before">
<button name="action_open_employee_cars" type="object"
class="oe_stat_button" icon="fa-car" groups="fleet.fleet_group_manager"
attrs="{'invisible': [('employee_cars_count','=', 0)]}">
<field name="employee_cars_count" widget="statinfo" />
</button>
</xpath>
</field>
</record>
</odoo>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="fleet_vehicle_assignation_log_view_list" model="ir.ui.view">
<field name="name">fleet.vehicle.assignation.log.view.tree.inherit.hr.fleet</field>
<field name="model">fleet.vehicle.assignation.log</field>
<field name="inherit_id" ref="fleet.fleet_vehicle_assignation_log_view_list" />
<field name="arch" type="xml">
<xpath expr="//field[@name='date_end']" position="after">
<field name="attachment_number" string=" "/>
<button name="action_get_attachment_view" string="View Attachments" type="object" icon="fa-paperclip"/>
</xpath>
</field>
</record>
</odoo>