[MERGE] forward port branch 11.0 up to 2ca7296000
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
odoo.define('hr_attendance.kiosk_mode', function (require) {
|
||||
"use strict";
|
||||
|
||||
var ajax = require('web.ajax');
|
||||
var core = require('web.core');
|
||||
var Widget = require('web.Widget');
|
||||
var Session = require('web.session');
|
||||
@@ -27,6 +28,8 @@ var KioskMode = Widget.extend({
|
||||
self.$el.html(QWeb.render("HrAttendanceKioskMode", {widget: self}));
|
||||
self.start_clock();
|
||||
});
|
||||
// Make a RPC call every day to keep the session alive
|
||||
self._interval = window.setInterval(this._callServer.bind(this), (60*60*1000*24));
|
||||
return $.when(def, this._super.apply(this, arguments));
|
||||
},
|
||||
|
||||
@@ -55,8 +58,15 @@ var KioskMode = Widget.extend({
|
||||
destroy: function () {
|
||||
core.bus.off('barcode_scanned', this, this._onBarcodeScanned);
|
||||
clearInterval(this.clock_start);
|
||||
clearInterval(this._interval);
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
_callServer: function () {
|
||||
// Make a call to the database to avoid the auto close of the session
|
||||
return ajax.rpc("/web/webclient/version_info", {});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
core.action_registry.add('hr_attendance_kiosk_mode', KioskMode);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
'description': """
|
||||
This module provides standard tools (account model, context manager and helpers) to support In-App purchases inside Odoo.
|
||||
""",
|
||||
'depends': ['web'],
|
||||
'depends': ['web', 'web_settings_dashboard'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'security/ir_rule.xml',
|
||||
|
||||
@@ -88,7 +88,7 @@ class PurchaseReport(models.Model):
|
||||
join res_partner partner on s.partner_id = partner.id
|
||||
left join product_product p on (l.product_id=p.id)
|
||||
left join product_template t on (p.product_tmpl_id=t.id)
|
||||
LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.template,',t.id) AND ip.company_id=s.company_id)
|
||||
LEFT JOIN ir_property ip ON (ip.name='standard_price' AND ip.res_id=CONCAT('product.product,',p.id) AND ip.company_id=s.company_id)
|
||||
left join product_uom u on (u.id=l.product_uom)
|
||||
left join product_uom u2 on (u2.id=t.uom_id)
|
||||
left join stock_picking_type spt on (spt.id=s.picking_type_id)
|
||||
|
||||
@@ -12,6 +12,7 @@ odoo.define('web.AbstractController', function (require) {
|
||||
* reading localstorage, ...) has to go through the controller.
|
||||
*/
|
||||
|
||||
var concurrency = require('web.concurrency');
|
||||
var ControlPanelMixin = require('web.ControlPanelMixin');
|
||||
var core = require('web.core');
|
||||
var Widget = require('web.Widget');
|
||||
@@ -54,6 +55,8 @@ var AbstractController = Widget.extend(ControlPanelMixin, {
|
||||
this.controllerID = params.controllerID;
|
||||
this.initialState = params.initialState;
|
||||
|
||||
// use a DropPrevious to correctly handle concurrent updates
|
||||
this.dp = new concurrency.DropPrevious();
|
||||
// those arguments are temporary, they won't be necessary as soon as the
|
||||
// ControlPanel will be handled by the View
|
||||
this.displayName = params.displayName;
|
||||
@@ -225,11 +228,11 @@ var AbstractController = Widget.extend(ControlPanelMixin, {
|
||||
var self = this;
|
||||
var shouldReload = (options && 'reload' in options) ? options.reload : true;
|
||||
var def = shouldReload ? this.model.reload(this.handle, params) : $.when();
|
||||
return def.then(function (handle) {
|
||||
return this.dp.add(def).then(function (handle) {
|
||||
self.handle = handle || self.handle; // update handle if we reloaded
|
||||
var state = self.model.get(self.handle);
|
||||
var localState = self.renderer.getLocalState();
|
||||
return self.renderer.updateState(state, params).then(function () {
|
||||
return self.dp.add(self.renderer.updateState(state, params)).then(function () {
|
||||
self.renderer.setLocalState(localState);
|
||||
self._update(state);
|
||||
});
|
||||
|
||||
@@ -3309,7 +3309,6 @@ QUnit.module('Views', {
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('basic support for widgets', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
@@ -3415,6 +3414,46 @@ QUnit.module('Views', {
|
||||
testUtils.unpatch(mixins.ParentedMixin);
|
||||
});
|
||||
|
||||
QUnit.test('concurrent reloads finishing in inverse order', function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
var blockSearchRead = false;
|
||||
var def = $.Deferred();
|
||||
var list = createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
arch: '<tree><field name="foo"/></tree>',
|
||||
mockRPC: function (route) {
|
||||
var result = this._super.apply(this, arguments);
|
||||
if (route === '/web/dataset/search_read' && blockSearchRead) {
|
||||
return $.when(def).then(_.constant(result));
|
||||
}
|
||||
return result;
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(list.$('.o_list_view .o_data_row').length, 4,
|
||||
"list view should contain 4 records");
|
||||
|
||||
// reload with a domain (this request is blocked)
|
||||
blockSearchRead = true;
|
||||
list.reload({domain: [['foo', '=', 'yop']]});
|
||||
|
||||
assert.strictEqual(list.$('.o_list_view .o_data_row').length, 4,
|
||||
"list view should still contain 4 records (search_read being blocked)");
|
||||
|
||||
// reload without the domain
|
||||
blockSearchRead = false;
|
||||
list.reload({domain: []});
|
||||
|
||||
// unblock the RPC
|
||||
def.resolve();
|
||||
assert.strictEqual(list.$('.o_list_view .o_data_row').length, 4,
|
||||
"list view should still contain 4 records");
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'website': 'https://www.odoo.com/page/quote-builder',
|
||||
'version': '1.0',
|
||||
'description': "",
|
||||
'depends': ['website', 'sale_management', 'mail', 'payment', 'website_mail'],
|
||||
'depends': ['website', 'sale_management', 'mail', 'payment', 'website_mail', 'sale_payment'],
|
||||
'data': [
|
||||
'data/website_quote_data.xml',
|
||||
'report/sale_order_reports.xml',
|
||||
|
||||
@@ -179,7 +179,9 @@ class Partner(models.Model):
|
||||
[('contact', 'Contact'),
|
||||
('invoice', 'Invoice address'),
|
||||
('delivery', 'Shipping address'),
|
||||
('other', 'Other address')], string='Address Type',
|
||||
('other', 'Other address'),
|
||||
("private", "Private Address"),
|
||||
], string='Address Type',
|
||||
default='contact',
|
||||
help="Used to select automatically the right address according to the context in sales and purchases documents.")
|
||||
street = fields.Char()
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<record id="group_private_addresses" model="res.groups">
|
||||
<field name="name">Access to Private Addresses</field>
|
||||
</record>
|
||||
|
||||
<data noupdate="1">
|
||||
<record model="ir.rule" id="res_users_log_rule">
|
||||
<field name="name">res.users.log per user</field>
|
||||
@@ -69,6 +73,37 @@
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<!-- Security restriction for private addresses -->
|
||||
<record id="res_partner_rule_private_employee" model="ir.rule">
|
||||
<field name="name">res.partner.rule.private.employee</field>
|
||||
<field name="model_id" ref="base.model_res_partner"/>
|
||||
<field name="domain_force">
|
||||
[('type', '!=', 'private')]
|
||||
</field>
|
||||
<field name="groups" eval="[
|
||||
(4, ref('base.group_user')),
|
||||
]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<!-- Relex previous rule for group_private_addresses -->
|
||||
<record id="res_partner_rule_private_group" model="ir.rule">
|
||||
<field name="name">res.partner.rule.private.group</field>
|
||||
<field name="model_id" ref="base.model_res_partner"/>
|
||||
<field name="domain_force">
|
||||
[('type', '=', 'private')]
|
||||
</field>
|
||||
<field name="groups" eval="[
|
||||
(4, ref('base.group_private_addresses'))
|
||||
]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<!-- Restrict modifications on ir.filters to owner only -->
|
||||
<record id="ir_filters_admin_all_rights_rule" model="ir.rule">
|
||||
<field name="name">ir.filters.admin.all.rights</field>
|
||||
|
||||
@@ -390,6 +390,50 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Special restricted view for private address, with limited "named" info that
|
||||
can be traced back to the employee -->
|
||||
<record id="res_partner_view_form_private" model="ir.ui.view">
|
||||
<field name="name">res.partner.view.form.private</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="priority" eval="300"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Private Address Form">
|
||||
<sheet>
|
||||
<field name="type" invisible="1"/>
|
||||
<label for="name" class="oe_editonly"/>
|
||||
<field name="name" required="0"/>
|
||||
<group>
|
||||
<group>
|
||||
<label for="street" string="Address"/>
|
||||
<div>
|
||||
<div class="o_address_format" name="div_address">
|
||||
<field name="street" placeholder="Street..." class="o_address_street"/>
|
||||
<field name="street2" placeholder="Street 2..." class="o_address_street"/>
|
||||
<field name="city" placeholder="City" class="o_address_city"/>
|
||||
<field name="state_id" class="o_address_state" placeholder="State" options='{"no_open": True}' context="{'country_id': country_id, 'zip': zip}"/>
|
||||
<field name="zip" placeholder="ZIP" class="o_address_zip"/>
|
||||
<field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="phone" widget="phone"/>
|
||||
<field name="mobile" widget="phone"/>
|
||||
<field name="email"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Bank Accounts">
|
||||
<field name="bank_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="acc_number"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_res_partner_filter" model="ir.ui.view">
|
||||
<field name="name">res.partner.select</field>
|
||||
<field name="model">res.partner</field>
|
||||
|
||||
Reference in New Issue
Block a user