A portal user is a user who typically belongs outside of the company, such as a customer or client. We can grant those users access to the Odoo portal so they can access information pertinent to them.
This blog explains how to create a report in portal view.
Now let's see how to create a detailed Maintenance report in the maintenance module. The report includes the details like a subject, team, schedule date, serial No, kanban state, request date, employee, technician, category, stage, and the company of the maintenance request on the given period.
Before that, we can create a button in the portal view for redirects to the maintenance report.
For that, we can create a view file(maintenance.xml) for the button.
Also defined the path of the report like (href=”/maintenance/report”)
XML File: maintenance_button.xml
<odoo>
<template id="maintenance_request" name="Maintenance Request" inherit_id="portal.portal_my_home">
<xpath expr="//div[hasclass('o_portal_docs')]" position="before">
<a id="maintenance_report" role="button"
href="/maintenance/report" style="width: 539px;"
class="btn btn-primary btn-block">
<i class="fa fa-ticket"/>
Maintenance Report
</a>
</xpath>
</template>
</odoo>
After executing the code we can view the button in the portal view.
Now, we can create a model for the report. In the model, we have to define the fields that are included in the report.
Python File: maintenance_report.py
from odoo import models, fields, tools, api, _
class MaintenanceReport(models.Model):
_name = 'portal.maintenance.report'
_auto = False
id = fields.Integer("ID")
subject = fields.Char("Subject")
maintenance_id = fields.Char("Maintenance ID")
serial_no = fields.Char("Serial No:")
stage = fields.Char("Stage")
company = fields.Char("Company")
schedule_date = fields.Char("Schedule Date")
kanban_state = fields.Char("Kanban State")
request_date = fields.Char("Request Date")
created_by = fields.Char("Created By")
technician = fields.Char("Technician")
category = fields.Char("Category")
team = fields.Char("Team")
department = fields.Char("Department")
For the Maintenance report in the created model, we have to create a SQL query defined in the init function.
def init(self):
tools.drop_view_if_exists(self.env.cr, 'portal_maintenance_report')
self.env.cr.execute('''
CREATE OR REPLACE VIEW portal_maintenance_report AS (
select row_number() OVER() AS id,res_partner.name as technician,hr_department.name as department,
l.id as maintenance_id,l.name as subject,l.maintenance_team_id,l.x_studio_serial_no as serial_no,
l.stage_id,maintenance_stage.name as stage,l.company_id,res_company.name as company,
l.schedule_date as schedule_date,l.kanban_state as kanban_state,l.request_date as request_date,
l.employee_id,l.user_id,
maintenance_equipment_category.name as category,
hr_employee.name as created_by,maintenance_team.name as team from maintenance_request as l
left join hr_employee on l.employee_id = hr_employee.id
left join maintenance_team on l.maintenance_team_id = maintenance_team.id
left join maintenance_equipment_category on l.category_id = maintenance_equipment_category.id
left join maintenance_stage on l.stage_id = maintenance_stage.id
left join res_company on l.company_id = res_company.id left join res_users on l.user_id = res_users.id
left join res_partner on res_users.partner_id = res_partner.id
left join maintenance_equipment on l.equipment_id = maintenance_equipment.id
left join hr_department on maintenance_equipment.department_id = hr_department.id)''')
After creating the model we can create the view file of the Maintenance report. First of all, I have created a template (maintenance_report_page).
In the maintenance_report_page template, we can define the table header and call the fields that were created using the SQL query.
XML File: maintenance_report.xml
<template id="maintenance_report_page" name="Maintenance Report">
<t t-call="website.layout">
<t t-set="breadcrumbs_searchbar" t-value="True"/>
<form>
<div id="wrap_maintenance">
<div>
<center>
<h1 style="margin: 20px;">
<b>Maintenance Request Report</b>
</h1>
</center>
</div>
<table class="table table-sm table-reports" style="border:1px solid black;">
<thead>
<tr>
<th colspan="6" class="text-left">Subject</th>
<th colspan="6" class="text-center">Team</th>
<th colspan="6" class="text-center">Scheduled Date</th>
<th colspan="6" class="text-left">Serial No:</th>
<th colspan="6" class="text-center">Kanban State</th>
<th colspan="6" class="text-center">Request Date</th>
<th colspan="6" class="text-center">Employee</th>
<th colspan="6" class="text-center">Technician</th>
<th colspan="6" class="text-center">Category</th>
<th colspan="6" class="text-center">Stage</th>
<th colspan="6" class="text-center">Company</th>
</tr>
</thead>
<tbody class="text-left">
<t>
<tr class="maintenance_table" t-foreach="datas" t-as="main">
<input id="main_id" type="hidden" t-att-value="main.maintenance_id"/>
<td colspan="6">
<span id="main_subject" t-esc="main['subject']"/>
</td>
<td colspan="6">
<span id="main_team" t-esc="main['team']"/>
</td>
<td colspan="6">
<span id="main_schedule_date" t-esc="main['schedule_date']"/>
</td>
<td colspan="6">
<span id="main_serial_no" t-esc="main['serial_no']"/>
</td>
<td colspan="6">
<span id="main_kanban_state" t-esc="main['kanban_state']"/>
</td>
<td colspan="6">
<span id="main_request_date" t-esc="main['request_date']"/>
</td>
<td colspan="6">
<span id="main_created_by" t-esc="main['created_by']"/>
</td>
<td colspan="6">
<span id="main_technician" t-esc="main['technician']"/>
</td>
<td colspan="6">
<span id="main_category" t-esc="main['category']"/>
</td>
<td colspan="6">
<span id="main_stage" t-esc="main['stage']"/>
</td>
<td colspan="6">
<span id="main_company" t-esc="main['company']"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</form>
</t>
</template>
In the maintenance_button XML file, the path ‘/maintenance/report’ is directed to controllers. So next, we have to create a python file for the controller.
Controller: main.py
from odoo import http
from odoo.http import request
class MaintenanceRequest(http.Controller):
@http.route(['/maintenance/report'], type="http", auth="public", website=True)
def maintenance_report(self, **kw):
report = request.env['portal.maintenance.report'].sudo().search([])
values = {
'datas': report,}
return request.render("portal_users.maintenance_report_page", values)
After that, when clicking the Maintenance button, the controller redirects the template “maintenance_report_page”
The output will look like the one below.
Additionally, we can add additional filters to this report and handle the associated data by altering the controller function