Merge branch 'master-upstream-patch-16042023' into 'master'

[PATCH] Upstream patch - 16042023

See merge request flectra-hq/flectra!997
This commit is contained in:
Parthiv Patel committed 2023-04-16 09:48:53 +00:00
commit f4b35fc120
11 files changed
+168 -24

No files matched your search

+3 -2
View File
@@ -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'))))
+8 -4
View File
@@ -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):
@@ -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)
@@ -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,
@@ -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)));
},
});
@@ -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: {
@@ -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: `
<tree js_class="stock_orderpoint_list" limit="1">
<field name="name"/>
</tree>`,
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: `
<tree js_class="stock_orderpoint_list" limit="1">
<field name="name"/>
</tree>`,
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();
}
);
}
);
});
+1
View File
@@ -31,6 +31,7 @@
<script type="text/javascript" src="/stock/static/tests/singleton_list_tests.js"/>
<script type="text/javascript" src="/stock/static/tests/popover_widget_tests.js"/>
<script type="text/javascript" src="/stock/static/tests/stock_traceability_report_backend_tests.js"/>
<script type="text/javascript" src="/stock/static/tests/stock_orderpoint_tests.js"/>
</xpath>
</template>
+1 -1
View File
@@ -3,7 +3,7 @@
<record id="transifex_project_url" model="ir.config_parameter">
<field name="key">transifex.project_url</field>
<field name="value">https://www.transifex.com/flectra</field>
<field name="value">https://app.transifex.com/flectra</field>
</record>
</flectra>
@@ -431,9 +431,9 @@ eventHandler.modules.editor.floatMe = function ($editable, sValue) {
var $target = $(getImgTarget($editable));
$editable.data('NoteHistory').recordUndo();
switch (sValue) {
case 'center': $target.toggleClass('d-block mx-auto').removeClass('float-right float-left'); break;
case 'left': $target.toggleClass('float-left').removeClass('float-right d-block mx-auto'); break;
case 'right': $target.toggleClass('float-right').removeClass('float-left d-block mx-auto'); break;
case 'center': $target.toggleClass('d-block mx-auto').removeClass('float-right float-left ml-auto'); break;
case 'left': $target.toggleClass('float-left').removeClass('float-right d-block mx-auto ml-auto'); break;
case 'right': $target.toggleClass('ml-auto float-right').removeClass('float-left d-block mx-auto'); break;
}
};
eventHandler.modules.editor.imageShape = function ($editable, sValue) {
@@ -199,6 +199,9 @@ img.ml-auto, img.mx-auto {
display: block;
text-align: center;
}
.fa.card-img, .fa.card-img-top, .fa.card-img-bottom {
width: auto;
}
div.media_iframe_video {
margin: 0 auto;