odoo18/addons_extensions/user_timelines/models/user_timeline_entry.py

233 lines
9.6 KiB
Python

from odoo import fields, models, tools
ODOO_COLOR_MAP = {
0: "#a2a2a2",
1: "#ee2d2d",
2: "#dc8534",
3: "#e8bb1d",
4: "#5794dd",
5: "#9f628f",
6: "#db8865",
7: "#41a9a2",
8: "#304be0",
9: "#ee2f8a",
10: "#61c36e",
11: "#9872e6",
}
class UserTimelineEntry(models.Model):
_name = "user.timeline.entry"
_description = "User Timeline Entry"
_auto = False
_order = "date_start, employee_id, user_id, id"
_rec_name = "name"
name = fields.Char(readonly=True)
company_id = fields.Many2one("res.company", readonly=True)
employee_id = fields.Many2one("hr.employee", readonly=True)
user_id = fields.Many2one("res.users", readonly=True)
project_id = fields.Many2one("project.project", readonly=True)
task_id = fields.Many2one("project.task", readonly=True)
timeline_id = fields.Integer(readonly=True)
stage_id = fields.Many2one("project.task.type", readonly=True)
leave_id = fields.Many2one("hr.leave", readonly=True)
leave_type_id = fields.Many2one("hr.leave.type", readonly=True)
date_start = fields.Datetime(string="Start", readonly=True)
date_stop = fields.Datetime(string="End", readonly=True)
entry_type = fields.Selection(
[("task", "Task"), ("leave", "Leave")],
string="Timeline Type",
readonly=True,
)
project_color = fields.Integer(readonly=True)
leave_color = fields.Integer(readonly=True)
display_color = fields.Integer(readonly=True)
display_color_hex = fields.Char(readonly=True)
description = fields.Char(readonly=True)
source_label = fields.Char(readonly=True)
state = fields.Char(readonly=True)
is_public_holiday = fields.Boolean(readonly=True)
focus_label = fields.Char(readonly=True)
def _color_case_sql(self, field_name):
return "CASE {field} {cases} ELSE '{default}' END".format(
field=field_name,
cases=" ".join(
f"WHEN {index} THEN '{color}'" for index, color in ODOO_COLOR_MAP.items()
),
default=ODOO_COLOR_MAP[4],
)
def _get_normal_task_select_sql(self):
project_color_case = self._color_case_sql("COALESCE(project.color, 0)")
return f"""
SELECT
CONCAT('task-', task.id::varchar, '-', rel.user_id::varchar) AS source_key,
COALESCE(task.sequence_name, task.name) AS name,
employee.id AS employee_id,
COALESCE(project.company_id, task.company_id, employee.company_id) AS company_id,
rel.user_id AS user_id,
task.project_id AS project_id,
task.id AS task_id,
NULL::integer AS timeline_id,
task.stage_id AS stage_id,
NULL::integer AS leave_id,
NULL::integer AS leave_type_id,
COALESCE(task.date_assign, task.create_date) AS date_start,
GREATEST(
COALESCE(task.date_deadline, task.date_assign, task.create_date),
COALESCE(task.date_assign, task.create_date)
) AS date_stop,
'task'::varchar AS entry_type,
COALESCE(project.color, 0) AS project_color,
NULL::integer AS leave_color,
COALESCE(project.color, 0) AS display_color,
COALESCE(NULLIF(project.timeline_color_hex, ''), {project_color_case}) AS display_color_hex,
task.name::varchar AS description,
'Project Task'::varchar AS source_label,
task.state::varchar AS state,
FALSE AS is_public_holiday,
COALESCE(employee.name, user_partner.name, task.name)::varchar AS focus_label
FROM project_task task
JOIN project_task_user_rel rel
ON rel.task_id = task.id
LEFT JOIN project_project project
ON project.id = task.project_id
LEFT JOIN hr_employee employee
ON employee.user_id = rel.user_id
LEFT JOIN res_users users
ON users.id = rel.user_id
LEFT JOIN res_partner user_partner
ON user_partner.id = users.partner_id
WHERE rel.user_id IS NOT NULL
AND COALESCE(task.date_assign, task.create_date) IS NOT NULL
"""
def _get_leave_select_sql(self):
leave_color_case = self._color_case_sql("COALESCE(leave_type.color, 0)")
return f"""
SELECT
CONCAT('leave-', leave.id::varchar) AS source_key,
CONCAT('Leave - ', leave_type.name) AS name,
leave.employee_id AS employee_id,
leave.company_id AS company_id,
employee.user_id AS user_id,
NULL::integer AS project_id,
NULL::integer AS task_id,
NULL::integer AS timeline_id,
NULL::integer AS stage_id,
leave.id AS leave_id,
leave.holiday_status_id AS leave_type_id,
leave.date_from AS date_start,
leave.date_to AS date_stop,
'leave'::varchar AS entry_type,
NULL::integer AS project_color,
COALESCE(leave_type.color, 0) AS leave_color,
COALESCE(leave_type.color, 0) AS display_color,
{leave_color_case} AS display_color_hex,
leave_type.name::varchar AS description,
'Approved Time Off'::varchar AS source_label,
leave.state::varchar AS state,
FALSE AS is_public_holiday,
employee.name::varchar AS focus_label
FROM hr_leave leave
JOIN hr_employee employee
ON employee.id = leave.employee_id
JOIN hr_leave_type leave_type
ON leave_type.id = leave.holiday_status_id
WHERE leave.state IN ('confirm', 'validate1', 'validate')
AND leave.date_from IS NOT NULL
AND leave.date_to IS NOT NULL
"""
def _get_public_holiday_select_sql(self):
holiday_color_case = self._color_case_sql("3")
return f"""
SELECT
CONCAT('public-holiday-', holiday.id::varchar, '-', employee.id::varchar) AS source_key,
CONCAT('Public Holiday - ', COALESCE(holiday.name, 'Company Holiday')) AS name,
employee.id AS employee_id,
COALESCE(holiday.company_id, employee.company_id) AS company_id,
employee.user_id AS user_id,
NULL::integer AS project_id,
NULL::integer AS task_id,
NULL::integer AS timeline_id,
NULL::integer AS stage_id,
NULL::integer AS leave_id,
NULL::integer AS leave_type_id,
holiday.date_from AS date_start,
holiday.date_to AS date_stop,
'leave'::varchar AS entry_type,
NULL::integer AS project_color,
3 AS leave_color,
3 AS display_color,
{holiday_color_case} AS display_color_hex,
holiday.name::varchar AS description,
'Public Holiday'::varchar AS source_label,
'public_holiday'::varchar AS state,
TRUE AS is_public_holiday,
employee.name::varchar AS focus_label
FROM resource_calendar_leaves holiday
JOIN hr_employee employee
ON employee.active = TRUE
AND (
holiday.company_id IS NULL
OR holiday.company_id = employee.company_id
)
WHERE holiday.resource_id IS NULL
AND holiday.time_type = 'leave'
AND holiday.date_from IS NOT NULL
AND holiday.date_to IS NOT NULL
"""
def _get_source_selects_sql(self):
return [
self._get_normal_task_select_sql(),
self._get_leave_select_sql(),
self._get_public_holiday_select_sql(),
]
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute(
f"""
CREATE OR REPLACE VIEW {self._table} AS (
SELECT
ROW_NUMBER() OVER (
ORDER BY
entry_order.date_start,
entry_order.employee_id,
entry_order.user_id,
entry_order.source_key
) AS id,
entry_order.name,
entry_order.company_id,
entry_order.employee_id,
entry_order.user_id,
entry_order.project_id,
entry_order.task_id,
entry_order.timeline_id,
entry_order.stage_id,
entry_order.leave_id,
entry_order.leave_type_id,
entry_order.date_start,
entry_order.date_stop,
entry_order.entry_type,
entry_order.project_color,
entry_order.leave_color,
entry_order.display_color,
entry_order.display_color_hex,
entry_order.description,
entry_order.source_label,
entry_order.state,
entry_order.is_public_holiday,
entry_order.focus_label
FROM (
{" UNION ALL ".join(self._get_source_selects_sql())}
) entry_order
)
"""
)