Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions addons/hr/models/hr_employee.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,7 @@ def _compute_split_legal_name(self):
@api.depends('current_version_id')
@api.depends_context('version_id')
def _compute_version_id(self):
context_version_id = self.env.context.get('version_id', False)
context_version = self.env['hr.version'].browse(context_version_id).exists() if context_version_id else self.env['hr.version']
context_version = self.env['hr.version'].browse(self.env.context.get('version_id', False))

for employee in self:
if context_version.employee_id == self:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<t t-name="hr.ButtonNewContract">
<span class="w-100 d-flex justify-content-end">
<button class="btn btn-link p-0 o_field_widget text-end w-auto text-nowrap" t-on-click="this.onClickNewContractBtn"
t-ref="this.datetimePickerTargetRef" t-if="this.props.record.resId and this.props.record.data.contract_date_start">New Contract</button>
t-ref="this.datetimePickerTargetRef" t-if="this.props.record.resId">New Contract</button>
</span>
</t>
</template>
21 changes: 0 additions & 21 deletions addons/hr/tests/test_hr_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,27 +523,6 @@ def test_multi_edit_other_and_contract_date_sync(self):
self.assertEqual(version.job_id.id, jobB.id)
self.assertEqual(version.contract_date_end, date(2020, 9, 30))

def test_delete_version(self):
employee = self.env['hr.employee'].create({
'name': 'John Doe',
'date_version': '2020-01-01',
})
v1 = employee.version_id
v2 = employee.create_version({
'date_version': '2021-01-01',
})
v3 = employee.create_version({
'date_version': '2022-01-01',
})
self.assertEqual(employee.current_version_id, v3)

v3.unlink()
self.assertEqual(employee.current_version_id, v2)
v1.unlink()
self.assertEqual(employee.current_version_id, v2)
with self.assertRaises(ValidationError):
v2.unlink()

def test_multi_edit_multi_employees_no_contract(self):
"""
Test the multi-edit when there is one version per employee, without contract
Expand Down
2 changes: 1 addition & 1 deletion addons/hr/views/hr_employee_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@
<span invisible="not contract_date_start">to</span>
<field name="contract_date_end" string="End Date" placeholder="Indefinite" widget="date_dynamic_min" options="{'min_date_field': 'contract_date_start'}"
class="o_hr_narrow_field ms-3" invisible="not contract_date_start"/>
<widget name="button_new_contract"/>
<widget name="button_new_contract" invisible="not contract_date_start"/>
</div>
<field name="fixed_term" string="Fixed Term" invisible="1"/>
<label for="wage"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}

.o_accrual {
.o_field_accrual, .o_field_selection, .o_field_day_selection, .o_field_filterable_selection {
.o_field_accrual, .o_field_selection, .o_field_filterable_selection {
width: fit-content !important;

&:not(.o_readonly_modifier) > *:first-child {
Expand All @@ -20,7 +20,7 @@
field-sizing: content;
}

&:not(.o_field_selection, .o_field_day_selection, .o_field_filterable_selection) > *:first-child {
&:not(.o_field_selection, .o_field_filterable_selection) > *:first-child {
max-width: 8ch;
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { t, useProps } from "@odoo/owl";
import { registry } from "@web/core/registry";
import {
SelectionField,
selectionField,
selectionFieldProps,
} from "@web/views/fields/selection/selection_field";

export class MonthDaySelectionField extends SelectionField {
props = useProps({
...selectionFieldProps,
month_field: t.string().optional(),
});

get #top() {
const monthValue = this.props.record.data[this.props.month_field]
// 2024 is a leap year
return new Date(2024, parseInt(monthValue ?? 0), 0).getDate();
}

/**
* @override
*/
get options() {
const options = super.options;
const top = this.#top;

return options.filter(option => Number(option[1]) <= top);
}
}

export const monthDaySelectionField = {
...selectionField,
component: MonthDaySelectionField,
supportedOptions: [
{
label: "Month",
name: "month_field",
type: "string",
},
],
extractProps({ options }) {
const props = selectionField.extractProps(...arguments);
props.month_field = options.month_field;
return props;
},
};

registry.category("fields").add("month_day_selection", monthDaySelectionField);
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { registry } from "@web/core/registry";
import { stepUtils } from "@web_tour/tour_utils";

registry.category("web_tour.tours").add("month_selection_for_february_tour", {
steps: () => [
stepUtils.showAppsMenuItem(),
{
content: "Open Time Off App",
trigger: ".o_app[data-menu-xmlid='hr_holidays.menu_hr_holidays_root']",
run: "click",
},
{
content: "Open Configuration menu",
trigger: ".o-dropdown[data-menu-xmlid='hr_holidays.menu_hr_holidays_configuration']",
run: "click",
},
{
content: "Go to Accurals",
trigger: ".o-dropdown-item[data-menu-xmlid='hr_holidays.hr_holidays_accrual_menu_configuration']",
run: "click",
},
{
content: "Click 'New' Button",
trigger: ".o_list_button_add:contains('New')",
run: "click",
},
{
content: "Click select a carryover month",
trigger: ".o_input[id='carryover_month_0']",
run: "click",
},
{
content: "Click February",
trigger: ".o-dropdown-item[role='menuitem']:contains('February')",
run: "click",
},
{
content: "Click select a carryover day",
trigger: ".o_input[id='carryover_day_0']",
run: "click",
},
{
content: "Check if 29 is available",
trigger: ".o_select_menu_menu:has(.o_select_menu_item:contains(29))",
},
{
content: "Check if 30 is not available",
trigger: ".o_select_menu_menu:not(:has(.o_select_menu_item:contains(30)))",
},
{
content: "Select 29",
trigger: ".o_select_menu_menu:has(.o_select_menu_item:contains(29))",
run: "click",
},
{
content: "Discard the form",
trigger: ".o_form_button_cancel",
run: "click",
},
]
});
1 change: 1 addition & 0 deletions addons/hr_holidays/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@
from . import test_timeoff_overview_my_department_tour
from . import test_hr_leave_report
from . import test_member_of_department
from . import test_month_selection_for_february_tour
10 changes: 10 additions & 0 deletions addons/hr_holidays/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ def _take_leave(self, employee, work_entry_type, date_from, date_to):
})
return leave

def _allocate_leave(self, employee, work_entry_type, num_days, valid_from, valid_to=False):
return self.env['hr.leave.allocation'].sudo().create({
'name': 'Alloc',
'employee_id': employee.id,
'work_entry_type_id': work_entry_type.id,
'number_of_days': num_days,
'date_from': valid_from,
'date_to': valid_to,
})

def _create_form_test_accrual_allocation(self, work_entry_type, date_from, employee, accrual_plan, date_to=None, creator_user=None):
allocation = self.env['hr.leave.allocation']
if creator_user:
Expand Down
27 changes: 27 additions & 0 deletions addons/hr_holidays/tests/test_hr_work_entry_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,30 @@ def test_change_count_days_as(self):

with self.assertRaises(ValidationError):
work_entry_type.count_days_as = 'working'

def _get_type(self, name, code):
return self.env['hr.work.entry.type'].sudo().create({
'name': name,
'code': code,
'requires_allocation': True,
'count_days_as': 'working',
'include_public_holidays_in_duration': False,
})

def test_search_virtual_remaining_leaves_works_with_gt(self):
self.env = self.env(user=self.employee_hruser.user_id)
emp = self.employee_hruser

type1 = self._get_type('Type 1', 'T1')
type2 = self._get_type('Type 2', 'T2')
type3 = self._get_type('Type 3', 'T3')

self._allocate_leave(emp, type1, 5, '2026-01-01').action_approve()
self._allocate_leave(emp, type2, 2, '2026-01-01').action_approve()
self._allocate_leave(emp, type3, 5, '2026-01-01').action_approve()

searchedLeaves = self.env["hr.work.entry.type"].search([("virtual_remaining_leaves", ">", 20)])

self.assertIn(type1, searchedLeaves)
self.assertNotIn(type2, searchedLeaves)
self.assertIn(type3, searchedLeaves)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo.tests import HttpCase, tagged


@tagged("post_install", "-at_install")
class TestMonthSelectionForFebruaryTour(HttpCase):

def test_month_selection_for_february_tour(self):
self.start_tour("/odoo", "month_selection_for_february_tour", login="admin")
13 changes: 8 additions & 5 deletions addons/hr_holidays/views/hr_leave_accrual_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,20 @@
</span>
<span name="biyearly" invisible="frequency != 'biyearly'">
on the
<field nolabel="1" name="first_month_day" class="o_hr_narrow_field-3" widget="day_selection" month_field="first_month" placeholder="select a day" required="frequency == 'biyearly'"/>
<field nolabel="1" name="first_month_day" class="o_hr_narrow_field-3" placeholder="select a day" required="frequency == 'biyearly'"
widget="month_day_selection" options="{'month_field': 'first_month'}"/>
of
<field name="first_month" class="o_hr_narrow_field-5" placeholder="select a month" required="frequency == 'biyearly'"/>
and the
<field nolabel="1" name="second_month_day" class="o_hr_narrow_field-3" widget="day_selection" month_field="second_month" placeholder="select a day" required="frequency == 'biyearly'"/>
<field nolabel="1" name="second_month_day" class="o_hr_narrow_field-3" placeholder="select a day" required="frequency == 'biyearly'"
widget="month_day_selection" options="{'month_field': 'second_month'}"/>
of
<field nolabel="1" name="second_month" class="o_hr_narrow_field-5" placeholder="select a month" required="frequency == 'biyearly'"/>
</span>
<span name="yearly" invisible="frequency != 'yearly'">
on the
<field nolabel="1" name="yearly_day" class="o_hr_narrow_field-3" widget="day_selection" month_field="yearly_month" required="frequency == 'yearly'" placeholder="select a day"/>
<field nolabel="1" name="yearly_day" class="o_hr_narrow_field-3" required="frequency == 'yearly'" placeholder="select a day"
widget="month_day_selection" options="{'month_field': 'yearly_month'}"/>
of
<field nolabel="1" name="yearly_month" class="o_hr_narrow_field-5" required="frequency == 'yearly'" placeholder="select a month"/>
</span>
Expand Down Expand Up @@ -204,8 +207,8 @@
options="{'links': {'other': 'carryover_custom_date'}, 'observe': 'carryover'}"/>
<span id="carryover_custom_date">
: the
<field name="carryover_day" widget="day_selection" month_field="carryover_month" placeholder="select a day"
required="carryover_date == 'other'"/>
<field name="carryover_day" placeholder="select a day"
required="carryover_date == 'other'" widget="month_day_selection" options="{'month_field': 'carryover_month'}"/>
of
<field name="carryover_month" placeholder="select a month"
required="carryover_date == 'other'"/>
Expand Down
1 change: 1 addition & 0 deletions addons/hr_skills/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
'data/ir_actions_server_data.xml',
'data/ir_cron_data.xml',
'data/report_paperformat.xml',
'report/hr_employee_certification_report_views.xml',
'report/hr_employee_skill_history_report_views.xml',
'report/hr_employee_skill_report_views.xml',
'report/hr_employee_cv_report.xml',
Expand Down
1 change: 1 addition & 0 deletions addons/hr_skills/report/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import hr_employee_certification_report
from . import hr_employee_cv_report
from . import hr_employee_skill_history_report
from . import hr_employee_skill_report
47 changes: 47 additions & 0 deletions addons/hr_skills/report/hr_employee_certification_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import fields, models, tools


class HrEmployeeCertificationReport(models.BaseModel):
_name = 'hr.employee.certification.report'
_auto = False
_inherit = ["hr.manager.department.report"]
_description = 'Employee Certification Report'
_order = 'employee_id, level_progress desc'

company_id = fields.Many2one('res.company', readonly=True)
department_id = fields.Many2one('hr.department', readonly=True)

skill_id = fields.Many2one('hr.skill', readonly=True)
skill_type_id = fields.Many2one('hr.skill.type', readonly=True)
skill_level = fields.Char(readonly=True)
level_progress = fields.Float(readonly=True, aggregator='avg')
active = fields.Boolean(readonly=False)

def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)

self.env.cr.execute("""
CREATE OR REPLACE VIEW %(table)s AS (
SELECT
row_number() OVER () AS id,
e.id AS employee_id,
e.company_id AS company_id,
v.department_id AS department_id,
s.skill_id AS skill_id,
s.skill_type_id AS skill_type_id,
sl.level_progress / 100.0 AS level_progress,
sl.name AS skill_level,
(s.valid_to IS NULL OR s.valid_to >= '%(date)s') AND s.valid_from <= '%(date)s' AS active
FROM hr_employee e
LEFT JOIN hr_version v ON e.current_version_id = v.id
LEFT OUTER JOIN hr_employee_skill s ON e.id = s.employee_id
LEFT OUTER JOIN hr_skill_level sl ON sl.id = s.skill_level_id
LEFT OUTER JOIN hr_skill_type st ON st.id = sl.skill_type_id
WHERE e.active AND st.active IS True AND st.is_certification IS TRUE
)
""" % {
'table': self._table,
'date': fields.Date.context_today(self)
})
Loading