[MERGE] forward port branch saas-15 up to 953dfe92c2
closes odoo/odoo#28255
This commit is contained in:
@@ -81,7 +81,7 @@ class HrAttendance(models.Model):
|
|||||||
('employee_id', '=', attendance.employee_id.id),
|
('employee_id', '=', attendance.employee_id.id),
|
||||||
('check_out', '=', False),
|
('check_out', '=', False),
|
||||||
('id', '!=', attendance.id),
|
('id', '!=', attendance.id),
|
||||||
])
|
], order='check_in desc', limit=1)
|
||||||
if no_check_out_attendances:
|
if no_check_out_attendances:
|
||||||
raise exceptions.ValidationError(_("Cannot create new attendance record for %(empl_name)s, the employee hasn't checked out since %(datetime)s") % {
|
raise exceptions.ValidationError(_("Cannot create new attendance record for %(empl_name)s, the employee hasn't checked out since %(datetime)s") % {
|
||||||
'empl_name': attendance.employee_id.name,
|
'empl_name': attendance.employee_id.name,
|
||||||
|
|||||||
@@ -212,6 +212,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<div class="o_thread_message_content">
|
<div class="o_thread_message_content">
|
||||||
|
<t t-raw="message.body"/>
|
||||||
<t t-if="message.tracking_value_ids and message.tracking_value_ids.length > 0">
|
<t t-if="message.tracking_value_ids and message.tracking_value_ids.length > 0">
|
||||||
<t t-if="message.subtype_description">
|
<t t-if="message.subtype_description">
|
||||||
<p><t t-esc="message.subtype_description"/></p>
|
<p><t t-esc="message.subtype_description"/></p>
|
||||||
@@ -219,9 +220,6 @@
|
|||||||
<t t-call="mail.ChatThread.MessageTracking"/>
|
<t t-call="mail.ChatThread.MessageTracking"/>
|
||||||
</t>
|
</t>
|
||||||
<p t-if="options.display_subject and message.display_subject" class="o_mail_subject">Subject: <t t-esc="message.subject"/></p>
|
<p t-if="options.display_subject and message.display_subject" class="o_mail_subject">Subject: <t t-esc="message.subject"/></p>
|
||||||
<t t-if="!(message.tracking_value_ids and message.tracking_value_ids.length > 0)">
|
|
||||||
<t t-raw="message.body"/>
|
|
||||||
</t>
|
|
||||||
<t t-foreach="message.attachment_ids" t-as="attachment">
|
<t t-foreach="message.attachment_ids" t-as="attachment">
|
||||||
<t t-call="mail.Attachment"/>
|
<t t-call="mail.Attachment"/>
|
||||||
</t>
|
</t>
|
||||||
|
|||||||
@@ -2152,6 +2152,19 @@ td {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
.pos .modal-dialog .popup-textinput{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.pos .modal-dialog .popup-textinput .title,
|
||||||
|
.pos .modal-dialog .popup-textinput .footer{
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
.pos .modal-dialog .popup-textinput textarea{
|
||||||
|
resize: none;
|
||||||
|
flex: auto;
|
||||||
|
margin: 0 20px 80px;
|
||||||
|
}
|
||||||
.pos .popup .title {
|
.pos .popup .title {
|
||||||
background: rgba(255,255,255,0.5);
|
background: rgba(255,255,255,0.5);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
@@ -742,6 +742,9 @@ var Chrome = PosBaseWidget.extend({
|
|||||||
if(err.message === 'XmlHttpRequestError '){
|
if(err.message === 'XmlHttpRequestError '){
|
||||||
title = 'Network Failure (XmlHttpRequestError)';
|
title = 'Network Failure (XmlHttpRequestError)';
|
||||||
body = 'The Point of Sale could not be loaded due to a network problem.\n Please check your internet connection.';
|
body = 'The Point of Sale could not be loaded due to a network problem.\n Please check your internet connection.';
|
||||||
|
}else if(err.message === 'TLSError'){
|
||||||
|
title = 'Https connection to IoT Box failed';
|
||||||
|
body = 'Make sure you are using IoT Box v18.10 or higher.\n\n Navigate to ' + err.url + ' to accept the certificate of your IoT Box.';
|
||||||
}else if(err.code === 200){
|
}else if(err.code === 200){
|
||||||
title = err.data.message;
|
title = err.data.message;
|
||||||
body = err.data.debug;
|
body = err.data.debug;
|
||||||
|
|||||||
@@ -192,11 +192,15 @@ var ProxyDevice = core.Class.extend(mixins.PropertiesMixin,{
|
|||||||
// try harder when we remember a good proxy url
|
// try harder when we remember a good proxy url
|
||||||
found_url = this.try_hard_to_connect(localStorage.hw_proxy_url, options)
|
found_url = this.try_hard_to_connect(localStorage.hw_proxy_url, options)
|
||||||
.then(null,function(){
|
.then(null,function(){
|
||||||
return self.find_proxy(options);
|
if (window.location.protocol != 'https:'){
|
||||||
|
return self.find_proxy(options);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
// just find something quick
|
// just find something quick
|
||||||
found_url = this.find_proxy(options);
|
if (window.location.protocol != 'https:'){
|
||||||
|
found_url = this.find_proxy(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
success = found_url.then(function(url){
|
success = found_url.then(function(url){
|
||||||
@@ -248,16 +252,17 @@ var ProxyDevice = core.Class.extend(mixins.PropertiesMixin,{
|
|||||||
// try several time to connect to a known proxy url
|
// try several time to connect to a known proxy url
|
||||||
try_hard_to_connect: function(url,options){
|
try_hard_to_connect: function(url,options){
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var port = ':' + (options.port || '8069');
|
var protocol = window.location.protocol;
|
||||||
|
var port = ( !options.port && protocol == "https:") ? ':443' : ':' + (options.port || '8069');
|
||||||
|
|
||||||
this.set_connection_status('connecting');
|
this.set_connection_status('connecting');
|
||||||
|
|
||||||
if(url.indexOf('//') < 0){
|
if(url.indexOf('//') < 0){
|
||||||
url = 'http://'+url;
|
url = protocol + '//' + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(url.indexOf(':',5) < 0){
|
if(url.indexOf(':',5) < 0){
|
||||||
url = url+port;
|
url = url + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try real hard to connect to url, with a 1sec timeout and up to 'retries' retries
|
// try real hard to connect to url, with a 1sec timeout and up to 'retries' retries
|
||||||
@@ -273,11 +278,11 @@ var ProxyDevice = core.Class.extend(mixins.PropertiesMixin,{
|
|||||||
.done(function(){
|
.done(function(){
|
||||||
done.resolve(url);
|
done.resolve(url);
|
||||||
})
|
})
|
||||||
.fail(function(){
|
.fail(function(resp){
|
||||||
if(retries > 0){
|
if(retries > 0){
|
||||||
try_real_hard_to_connect(url,retries-1,done);
|
try_real_hard_to_connect(url,retries-1,done);
|
||||||
}else{
|
}else{
|
||||||
done.reject();
|
done.reject(resp.statusText, url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return done;
|
return done;
|
||||||
|
|||||||
@@ -126,13 +126,21 @@ exports.PosModel = Backbone.Model.extend({
|
|||||||
progress: function(prog){
|
progress: function(prog){
|
||||||
self.chrome.loading_progress(prog);
|
self.chrome.loading_progress(prog);
|
||||||
},
|
},
|
||||||
}).then(function(){
|
}).then(
|
||||||
if(self.config.iface_scan_via_proxy){
|
function(){
|
||||||
self.barcode_reader.connect_to_proxy();
|
if(self.config.iface_scan_via_proxy){
|
||||||
}
|
self.barcode_reader.connect_to_proxy();
|
||||||
}).always(function(){
|
}
|
||||||
done.resolve();
|
done.resolve();
|
||||||
});
|
},
|
||||||
|
function(statusText, url){
|
||||||
|
if (statusText == 'error' && window.location.protocol == 'https:') {
|
||||||
|
var error = {message: 'TLSError', url: url};
|
||||||
|
self.chrome.loading_error(error);
|
||||||
|
} else {
|
||||||
|
done.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
return done;
|
return done;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1117,7 +1117,7 @@
|
|||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="popup popup-textinput">
|
<div class="popup popup-textinput">
|
||||||
<p class="title"><t t-esc=" widget.options.title || '' " /></p>
|
<p class="title"><t t-esc=" widget.options.title || '' " /></p>
|
||||||
<textarea rows="10" cols="40"><t t-esc="widget.options.value" /></textarea>
|
<textarea><t t-esc="widget.options.value" /></textarea>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="button confirm">
|
<div class="button confirm">
|
||||||
Ok
|
Ok
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ var base = require('web_editor.base');
|
|||||||
|
|
||||||
var qweb = core.qweb;
|
var qweb = core.qweb;
|
||||||
var _t = core._t;
|
var _t = core._t;
|
||||||
var ZeroClipboard = window.ZeroClipboard;
|
|
||||||
|
|
||||||
var exports = {};
|
var exports = {};
|
||||||
|
|
||||||
@@ -108,7 +107,8 @@ if (!$('.o_website_links_create_tracked_url').length) {
|
|||||||
this.animating_copy = false;
|
this.animating_copy = false;
|
||||||
},
|
},
|
||||||
start: function () {
|
start: function () {
|
||||||
new ZeroClipboard(this.$('.btn_shorten_url_clipboard'));
|
// DO NOT FORWARD PORT ABOVE V11
|
||||||
|
new Clipboard(this.$('.btn_shorten_url_clipboard')[0]);
|
||||||
},
|
},
|
||||||
toggle_copy_button: function () {
|
toggle_copy_button: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -258,8 +258,6 @@ if (!$('.o_website_links_create_tracked_url').length) {
|
|||||||
|
|
||||||
base.ready().done(function () {
|
base.ready().done(function () {
|
||||||
|
|
||||||
ZeroClipboard.config({swfPath: window.location.origin + "/website_links/static/lib/zeroclipboard/ZeroClipboard.swf" });
|
|
||||||
|
|
||||||
// UTMS selects widgets
|
// UTMS selects widgets
|
||||||
var campaign_select = new SelectBox('utm.campaign');
|
var campaign_select = new SelectBox('utm.campaign');
|
||||||
campaign_select.start($("#campaign-select"), _t('e.g. Promotion of June, Winter Newsletter, ..'));
|
campaign_select.start($("#campaign-select"), _t('e.g. Promotion of June, Winter Newsletter, ..'));
|
||||||
@@ -291,7 +289,7 @@ if (!$('.o_website_links_create_tracked_url').length) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Clipboard Library
|
// Clipboard Library
|
||||||
new ZeroClipboard($("#btn_shorten_url"));
|
new Clipboard($("#btn_shorten_url")[0]);
|
||||||
|
|
||||||
$("#generated_tracked_link a").click(function () {
|
$("#generated_tracked_link a").click(function () {
|
||||||
$("#generated_tracked_link a").text("Copied").removeClass("btn-primary").addClass("btn-success");
|
$("#generated_tracked_link a").text("Copied").removeClass("btn-primary").addClass("btn-success");
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
<template id="assets_website_links" inherit_id="website.assets_frontend">
|
<template id="assets_website_links" inherit_id="website.assets_frontend">
|
||||||
<xpath expr="." position="inside">
|
<xpath expr="." position="inside">
|
||||||
<script type="text/javascript" src="/website_links/static/lib/zeroclipboard/ZeroClipboard.js"/>
|
|
||||||
<script type="text/javascript" src="/website_links/static/src/js/website_links.js"/>
|
<script type="text/javascript" src="/website_links/static/src/js/website_links.js"/>
|
||||||
<script type="text/javascript" src="/website_links/static/src/js/website_links_code_editor.js"/>
|
<script type="text/javascript" src="/website_links/static/src/js/website_links_code_editor.js"/>
|
||||||
<script type="text/javascript" src="/website_links/static/src/js/website_links_charts.js"/>
|
<script type="text/javascript" src="/website_links/static/src/js/website_links_charts.js"/>
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ class BootstrapTranslator(nodes.NodeVisitor, object):
|
|||||||
else:
|
else:
|
||||||
opts = {}
|
opts = {}
|
||||||
|
|
||||||
def warner(msg):
|
def warner(msg, **kw):
|
||||||
self.builder.warn(msg, (self.builder.current_docname, node.line))
|
self.builder.warn(msg, (self.builder.current_docname, node.line))
|
||||||
highlighted = self.builder.highlighter.highlight_block(
|
highlighted = self.builder.highlighter.highlight_block(
|
||||||
node.rawsource, lang, opts=opts, warn=warner, linenos=linenos,
|
node.rawsource, lang, opts=opts, warn=warner, linenos=linenos,
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
India, 17, Sept - 2018
|
||||||
|
|
||||||
|
I hereby agree to the terms of the Odoo Individual Contributor License
|
||||||
|
Agreement v1.0.
|
||||||
|
|
||||||
|
I declare that I am authorized and able to make this agreement and sign this
|
||||||
|
declaration.
|
||||||
|
|
||||||
|
Signed,
|
||||||
|
|
||||||
|
Anil Kesariya anil.r.kesariya@gmail.com https://github.com/AnilKesariya
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Mexico, 2018-10-24
|
||||||
|
|
||||||
|
I hereby agree to the terms of the Odoo Individual Contributor License
|
||||||
|
Agreement v1.0.
|
||||||
|
|
||||||
|
I declare that I am authorized and able to make this agreement and sign this
|
||||||
|
declaration.
|
||||||
|
|
||||||
|
Signed,
|
||||||
|
|
||||||
|
Luis Guzman ark@switnet.org https://github.com/ark74
|
||||||
@@ -701,11 +701,10 @@ class Module(models.Model):
|
|||||||
mod.write(updated_values)
|
mod.write(updated_values)
|
||||||
else:
|
else:
|
||||||
mod_path = modules.get_module_path(mod_name)
|
mod_path = modules.get_module_path(mod_name)
|
||||||
if not mod_path:
|
if not mod_path or not terp:
|
||||||
continue
|
continue
|
||||||
if not terp or not terp.get('installable', True):
|
state = "uninstalled" if terp.get('installable', True) else "uninstallable"
|
||||||
continue
|
mod = self.create(dict(name=mod_name, state=state, **values))
|
||||||
mod = self.create(dict(name=mod_name, state='uninstalled', **values))
|
|
||||||
res[1] += 1
|
res[1] += 1
|
||||||
|
|
||||||
mod._update_dependencies(terp.get('depends', []))
|
mod._update_dependencies(terp.get('depends', []))
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
'website': "http://www.yourcompany.com",
|
'website': "http://www.yourcompany.com",
|
||||||
|
|
||||||
# Categories can be used to filter modules in modules listing
|
# Categories can be used to filter modules in modules listing
|
||||||
# Check https://github.com/odoo/odoo/blob/master/odoo/addons/base/module/module_data.xml
|
# Check https://github.com/odoo/odoo/blob/11.0/odoo/addons/base/module/module_data.xml
|
||||||
# for the full list
|
# for the full list
|
||||||
'category': 'Uncategorized',
|
'category': 'Uncategorized',
|
||||||
'version': '0.1',
|
'version': '0.1',
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ class MigrationManager(object):
|
|||||||
function. Theses files must respect a directory tree structure: A 'migrations' folder
|
function. Theses files must respect a directory tree structure: A 'migrations' folder
|
||||||
which containt a folder by version. Version can be 'module' version or 'server.module'
|
which containt a folder by version. Version can be 'module' version or 'server.module'
|
||||||
version (in this case, the files will only be processed by this version of the server).
|
version (in this case, the files will only be processed by this version of the server).
|
||||||
Python file names must start by `pre` or `post` and will be executed, respectively,
|
Python file names must start by `pre-` or `post-` and will be executed, respectively,
|
||||||
before and after the module initialisation. `end` scripts are run after all modules have
|
before and after the module initialisation. `end-` scripts are run after all modules have
|
||||||
been updated.
|
been updated.
|
||||||
Example:
|
Example:
|
||||||
<moduledir>
|
<moduledir>
|
||||||
|
|||||||
Reference in New Issue
Block a user