diff --git a/addons/hr/models/hr_employee.py b/addons/hr/models/hr_employee.py index 09c7f656f6..8c678de7d5 100644 --- a/addons/hr/models/hr_employee.py +++ b/addons/hr/models/hr_employee.py @@ -230,7 +230,7 @@ class HrEmployeePrivate(models.Model): vals.update(self._sync_user(user, vals.get('image_1920') == self._default_image())) vals['name'] = vals.get('name', user.name) employee = super(HrEmployeePrivate, self).create(vals) - employee.message_subscribe(employee.address_home_id.ids) + employee._message_subscribe(employee.address_home_id.ids) url = '/web#%s' % url_encode({ 'action': 'hr.plan_wizard_action', 'active_id': employee.id, @@ -250,7 +250,8 @@ class HrEmployeePrivate(models.Model): if account_id: self.env['res.partner.bank'].browse(account_id).partner_id = vals['address_home_id'] self.message_unsubscribe(self.address_home_id.ids) - self.message_subscribe([vals['address_home_id']]) + if vals['address_home_id']: + self._message_subscribe([vals['address_home_id']]) if vals.get('user_id'): # Update the profile pictures with user, except if provided vals.update(self._sync_user(self.env['res.users'].browse(vals['user_id']), bool(vals.get('image_1920')))) diff --git a/addons/hr_holidays/models/hr_employee.py b/addons/hr_holidays/models/hr_employee.py index 2400e8a112..9392d49a87 100644 --- a/addons/hr_holidays/models/hr_employee.py +++ b/addons/hr_holidays/models/hr_employee.py @@ -4,7 +4,8 @@ import datetime from dateutil.relativedelta import relativedelta -from flectra import api, fields, models +from flectra import api, fields, models, _ +from flectra.exceptions import UserError from flectra.tools.float_utils import float_round @@ -118,7 +119,7 @@ class HrEmployeeBase(models.AbstractModel): ('employee_id', 'in', self.ids), ('date_from', '<=', fields.Datetime.now()), ('date_to', '>=', fields.Datetime.now()), - ('state', 'not in', ('cancel', 'refuse')) + ('state', '=', 'validate'), ]) leave_data = {} for holiday in holidays: @@ -154,6 +155,8 @@ class HrEmployeeBase(models.AbstractModel): employee.show_leaves = False def _search_absent_employee(self, operator, value): + if operator not in ('=', '!=') or not isinstance(value, bool): + raise UserError(_('Operation not supported')) # This search is only used for the 'Absent Today' filter however # this only returns employees that are absent right now. today_date = datetime.datetime.utcnow().date() @@ -161,11 +164,12 @@ class HrEmployeeBase(models.AbstractModel): today_end = fields.Datetime.to_string(today_date + relativedelta(hours=23, minutes=59, seconds=59)) holidays = self.env['hr.leave'].sudo().search([ ('employee_id', '!=', False), - ('state', 'not in', ['cancel', 'refuse']), + ('state', '=', 'validate1'), ('date_from', '<=', today_end), ('date_to', '>=', today_start), ]) - return [('id', 'in', holidays.mapped('employee_id').ids)] + operator = ['in', 'not in'][(operator == '=') != value] + return [('id', operator, holidays.mapped('employee_id').ids)] @api.model def create(self, values): diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index 2e650e153d..8d478d2882 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. -from datetime import datetime, date +from datetime import datetime, date, timedelta from dateutil.relativedelta import relativedelta from pytz import timezone, UTC @@ -466,3 +466,48 @@ class TestLeaveRequests(TestHrHolidaysCommon): 'date_to': datetime(2022, 3, 11, 23, 59, 59), }) self.assertEqual(leave.number_of_days, 1) + + def test_current_leave_status(self): + types = ('no_validation', 'manager', 'hr', 'both') + employee = self.employee_emp + + def run_validation_flow(leave_validation_type): + LeaveType = self.env['hr.leave.type'].with_user(self.user_hrmanager_id) + leave_type = LeaveType.with_context(tracking_disable=True).create({ + 'name': leave_validation_type.capitalize(), + 'leave_validation_type': leave_validation_type, + 'allocation_type': 'no', + }) + current_leave = self.env['hr.leave'].with_user(self.user_employee_id).create({ + 'name': 'Holiday Request', + 'holiday_type': 'employee', + 'employee_id': employee.id, + 'holiday_status_id': leave_type.id, + 'date_from': datetime.today() - timedelta(days=1), + 'date_to': datetime.today() + timedelta(days=1), + }) + + if leave_validation_type in ('manager', 'both'): + self.assertFalse(employee.is_absent) + self.assertFalse(employee.current_leave_id) + self.assertEqual(employee.filtered_domain([('is_absent', '=', False)]), employee) + self.assertFalse(employee.filtered_domain([('is_absent', '=', True)])) + current_leave.with_user(self.user_hruser_id).action_approve() + + if leave_validation_type in ('hr', 'both'): + self.assertFalse(employee.is_absent) + self.assertFalse(employee.current_leave_id) + self.assertEqual(employee.filtered_domain([('is_absent', '=', False)]), employee) + self.assertFalse(employee.filtered_domain([('is_absent', '=', True)])) + current_leave.with_user(self.user_hrmanager_id).action_validate() + + self.assertTrue(employee.is_absent) + self.assertEqual(employee.current_leave_id, current_leave.holiday_status_id) + self.assertFalse(employee.filtered_domain([('is_absent', '=', False)])) + self.assertEqual(employee.filtered_domain([('is_absent', '=', True)]), employee) + + raise RuntimeError() + + for leave_validation_type in types: + with self.assertRaises(RuntimeError), self.env.cr.savepoint(): + run_validation_flow(leave_validation_type) diff --git a/addons/point_of_sale/tests/test_point_of_sale_flow.py b/addons/point_of_sale/tests/test_point_of_sale_flow.py index 368a717f2e..903a865813 100644 --- a/addons/point_of_sale/tests/test_point_of_sale_flow.py +++ b/addons/point_of_sale/tests/test_point_of_sale_flow.py @@ -1176,7 +1176,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon): [0, 0, {'lot_name': '1001'}], ] })], - 'pricelist_id': 1, + 'pricelist_id': self.pos_config.pricelist_id.id, 'amount_paid': 6.0, 'amount_total': 6.0, 'amount_tax': 0.0, diff --git a/addons/stock/static/src/js/stock_orderpoint_list_controller.js b/addons/stock/static/src/js/stock_orderpoint_list_controller.js index 611f9b677e..81696ef6b3 100644 --- a/addons/stock/static/src/js/stock_orderpoint_list_controller.js +++ b/addons/stock/static/src/js/stock_orderpoint_list_controller.js @@ -46,8 +46,7 @@ var StockOrderpointListController = ListController.extend({ }, _onReplenish: function () { - var records = this.getSelectedRecords(); - this.model.replenish(records); + this.getSelectedIdsWithDomain().then(ids => this.model.replenish((ids))); }, _onSelectionChanged: function (ev) { @@ -64,8 +63,7 @@ var StockOrderpointListController = ListController.extend({ }, _onSnooze: function () { - var records = this.getSelectedRecords(); - this.model.snooze(records); + this.getSelectedIdsWithDomain().then(ids => this.model.snooze((ids))); }, }); diff --git a/addons/stock/static/src/js/stock_orderpoint_list_model.js b/addons/stock/static/src/js/stock_orderpoint_list_model.js index 1b71df1339..f1b1f9fdd8 100644 --- a/addons/stock/static/src/js/stock_orderpoint_list_model.js +++ b/addons/stock/static/src/js/stock_orderpoint_list_model.js @@ -14,23 +14,19 @@ var StockOrderpointListModel = ListModel.extend({ // ------------------------------------------------------------------------- /** */ - replenish: function (records) { + replenish: function (recordResIds) { var self = this; - var model = records[0].model; - var recordResIds = _.pluck(records, 'res_id'); - var context = records[0].getContext(); return this._rpc({ - model: model, + model: this.loadParams.modelName, method: 'action_replenish', args: [recordResIds], - context: context, + context: this.loadParams.context, }).then(function () { return self.do_action('stock.action_replenishment'); }); }, - snooze: function (records) { - var recordResIds = _.pluck(records, 'res_id'); + snooze: function (recordResIds) { var self = this; return this.do_action('stock.action_orderpoint_snooze', { additional_context: { diff --git a/addons/stock/static/tests/stock_orderpoint_tests.js b/addons/stock/static/tests/stock_orderpoint_tests.js new file mode 100644 index 0000000000..54853e18e7 --- /dev/null +++ b/addons/stock/static/tests/stock_orderpoint_tests.js @@ -0,0 +1,96 @@ +flectra.define("stock.orderpoint_tests", function (require) { + "use strict"; + + const { createView, dom, nextTick } = require("web.test_utils"); + const StockOrderpointListView = require("stock.StockOrderpointListView"); + + QUnit.module( + "Views", + { + beforeEach: function () { + this.data = { + person: { + fields: { + name: { string: "Name", type: "char" }, + age: { string: "Age", type: "integer" }, + job: { string: "Profession", type: "char" }, + }, + records: [ + { id: 1, name: "Daniel Fortesque", age: 32, job: "Soldier" }, + { id: 2, name: "Samuel Oak", age: 64, job: "Professor" }, + { id: 3, name: "Leto II Atreides", age: 128, job: "Emperor" }, + ], + }, + }; + }, + }, + () => { + QUnit.module("StockOrderpointListView"); + + QUnit.test( + "domain selection: order should be called on all records", + async function (assert) { + assert.expect(1); + + const view = await createView({ + View: StockOrderpointListView, + model: "person", + data: this.data, + arch: ` + + + `, + mockRPC: function (route, { args, method, model }) { + if (method === "action_replenish") { + assert.deepEqual( + { args, model }, + { args: [[1, 2, 3]], model: "person" } + ); + return Promise.resolve({}); + } + return this._super.apply(this, arguments); + }, + }); + + await dom.click(view.$("thead .o_list_record_selector input")); + await dom.click(view.$(".o_list_selection_box .o_list_select_domain")); + await dom.click(view.$(".o_button_order")); + await nextTick(); + view.destroy(); + } + ); + + QUnit.test( + "domain selection: snooze should be called on all records", + async function (assert) { + assert.expect(1); + + const view = await createView({ + View: StockOrderpointListView, + model: "person", + data: this.data, + arch: ` + + + `, + intercepts: { + do_action: function (event) { + if (event.data.action === "stock.action_orderpoint_snooze") { + assert.deepEqual(event.data.options.additional_context, { + default_orderpoint_ids: [1, 2, 3], + }); + } + }, + }, + }); + + await dom.click(view.$("thead .o_list_record_selector input")); + await dom.click(view.$(".o_list_selection_box .o_list_select_domain")); + await dom.click(view.$(".o_button_snooze")); + await nextTick(); + view.destroy(); + } + ); + } + ); +}); diff --git a/addons/stock/views/stock_template.xml b/addons/stock/views/stock_template.xml index f8e7528c17..aa322e22fb 100644 --- a/addons/stock/views/stock_template.xml +++ b/addons/stock/views/stock_template.xml @@ -31,6 +31,7 @@