mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2025-02-25 18:55:21 -06:00
[PATCH] Upstream patch - 16042023
This commit is contained in:
@@ -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'))))
|
||||
|
||||
@@ -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: {
|
||||
|
||||
96
addons/stock/static/tests/stock_orderpoint_tests.js
Normal file
96
addons/stock/static/tests/stock_orderpoint_tests.js
Normal file
@@ -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();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user