summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-02-21 19:17:01 +0100
committerChristophe Simonis <chs@odoo.com>2018-02-21 19:17:01 +0100
commitdbb713c2f836892de516e8d5e313a5dab8919a56 (patch)
tree8e98cbb2b58ef84ba40822da2227fe45589b3edb
parent6ec6d3e8a1a02cb076bfbeb538a0615700d7043f (diff)
parent49f85485571275389372e285882a3c2ec54b55ff (diff)
[MERGE] forward port branch saas-16 up to 49f85485571
-rw-r--r--addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py2
-rw-r--r--addons/mail/i18n/mail.pot6
-rw-r--r--addons/mail/models/mail_channel.py10
-rw-r--r--addons/mail/static/src/js/thread.js4
-rw-r--r--addons/mrp/models/mrp_bom.py5
-rw-r--r--addons/project/models/project.py6
-rw-r--r--addons/sale/models/sale.py2
-rw-r--r--addons/web/static/src/js/core/utils.js17
-rw-r--r--addons/web_editor/static/src/js/widgets/widgets.js13
-rw-r--r--addons/website_quote/models/sale_order.py7
-rw-r--r--addons/website_sale/views/templates.xml11
11 files changed, 66 insertions, 17 deletions
diff --git a/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py b/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py
index 1b7a66cb475..6174699920c 100644
--- a/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py
+++ b/addons/l10n_be_hr_payroll/models/l10n_be_hr_payroll.py
@@ -230,7 +230,7 @@ class HrContract(models.Model):
- 12.0 * contract.internet \
- 12.0 * (contract.mobile + contract.mobile_plus) \
- 12.0 * contract.transport_employer_cost \
- - (1.326 / 1.05 * 12.0) * contract.commission_on_target \
+ - contract.warrants_cost \
- 220.0 * contract.meal_voucher_paid_by_employer
gross = remaining_for_gross / (13.0 + 13.0 * 0.3507 + 0.92)
return gross
diff --git a/addons/mail/i18n/mail.pot b/addons/mail/i18n/mail.pot
index 4bca0810744..acc27f768be 100644
--- a/addons/mail/i18n/mail.pot
+++ b/addons/mail/i18n/mail.pot
@@ -218,6 +218,12 @@ msgid "<br><br>\n"
msgstr ""
#. module: mail
+#: code:addons/mail/models/mail_channel.py:475
+#, python-format
+msgid "<div class=\"o_mail_notification\">%(author)s invited %(new_partner)s to <a href=\"#\" class=\"o_channel_redirect\" data-oe-id=\"%(channel_id)s\">#%(channel_name)s</a></div>"
+msgstr ""
+
+#. module: mail
#: code:addons/mail/models/mail_channel.py:584
#, python-format
msgid "<div class=\"o_mail_notification\">created <a href=\"#\" class=\"o_channel_redirect\" data-oe-id=\"%s\">#%s</a></div>"
diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py
index fc637075c33..e24a3193f97 100644
--- a/addons/mail/models/mail_channel.py
+++ b/addons/mail/models/mail_channel.py
@@ -505,7 +505,15 @@ class Channel(models.Model):
partners_to_add = partners - channel.channel_partner_ids
channel.write({'channel_last_seen_partner_ids': [(0, 0, {'partner_id': partner_id}) for partner_id in partners_to_add.ids]})
for partner in partners_to_add:
- notification = _('<div class="o_mail_notification">joined <a href="#" class="o_channel_redirect" data-oe-id="%s">#%s</a></div>') % (self.id, self.name,)
+ if partner.id != self.env.user.partner_id.id:
+ notification = _('<div class="o_mail_notification">%(author)s invited %(new_partner)s to <a href="#" class="o_channel_redirect" data-oe-id="%(channel_id)s">#%(channel_name)s</a></div>') % {
+ 'author': self.env.user.display_name,
+ 'new_partner': partner.display_name,
+ 'channel_id': channel.id,
+ 'channel_name': channel.name,
+ }
+ else:
+ notification = _('<div class="o_mail_notification">joined <a href="#" class="o_channel_redirect" data-oe-id="%s">#%s</a></div>') % (channel.id, channel.name,)
self.message_post(body=notification, message_type="notification", subtype="mail.mt_comment", author_id=partner.id)
# broadcast the channel header to the added partner
diff --git a/addons/mail/static/src/js/thread.js b/addons/mail/static/src/js/thread.js
index 68a01df2345..f63c7073af9 100644
--- a/addons/mail/static/src/js/thread.js
+++ b/addons/mail/static/src/js/thread.js
@@ -210,6 +210,10 @@ var Thread = Widget.extend({
}
},
on_click_redirect: function (event) {
+ // ignore inherited branding
+ if ($(event.target).data('oe-field') !== undefined) {
+ return;
+ }
var id = $(event.target).data('oe-id');
if (id) {
event.preventDefault();
diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py
index 4d9a0e5bcbe..8e5ce0ad6c8 100644
--- a/addons/mrp/models/mrp_bom.py
+++ b/addons/mrp/models/mrp_bom.py
@@ -81,6 +81,11 @@ class MrpBom(models.Model):
if self.product_tmpl_id:
self.product_uom_id = self.product_tmpl_id.uom_id.id
+ @api.onchange('routing_id')
+ def onchange_routing_id(self):
+ for line in self.bom_line_ids:
+ line.operation_id = False
+
@api.multi
def name_get(self):
return [(bom.id, '%s%s' % (bom.code and '%s: ' % bom.code or '', bom.product_tmpl_id.display_name)) for bom in self]
diff --git a/addons/project/models/project.py b/addons/project/models/project.py
index 31cc324057c..91eeac76cfe 100644
--- a/addons/project/models/project.py
+++ b/addons/project/models/project.py
@@ -519,14 +519,12 @@ class Task(models.Model):
@api.onchange('project_id')
def _onchange_project(self):
- default_partner_id = self.env.context.get('default_partner_id')
- default_partner = self.env['res.partner'].browse(default_partner_id) if default_partner_id else self.env['res.partner']
if self.project_id:
- self.partner_id = self.project_id.partner_id or default_partner
+ if self.project_id.partner_id:
+ self.partner_id = self.project_id.partner_id
if self.project_id not in self.stage_id.project_ids:
self.stage_id = self.stage_find(self.project_id.id, [('fold', '=', False)])
else:
- self.partner_id = default_partner
self.stage_id = False
@api.onchange('user_id')
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index 455ae01be2c..b30743bfe4c 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -130,7 +130,7 @@ class SaleOrder(models.Model):
help="Manually set the expiration date of your quotation (offer), or it will set the date automatically based on the template if online quotation is installed.")
is_expired = fields.Boolean(compute='_compute_is_expired', string="Is expired")
create_date = fields.Datetime(string='Creation Date', readonly=True, index=True, help="Date on which sales order is created.")
- confirmation_date = fields.Datetime(string='Confirmation Date', readonly=True, index=True, help="Date on which the sales order is confirmed.", oldname="date_confirm")
+ confirmation_date = fields.Datetime(string='Confirmation Date', readonly=True, index=True, help="Date on which the sales order is confirmed.", oldname="date_confirm", copy=False)
user_id = fields.Many2one('res.users', string='Salesperson', index=True, track_visibility='onchange', default=lambda self: self.env.user)
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, required=True, change_default=True, index=True, track_visibility='always')
partner_invoice_id = fields.Many2one('res.partner', string='Invoice Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, help="Invoice address for current sales order.")
diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js
index af044b13b5e..496754aedea 100644
--- a/addons/web/static/src/js/core/utils.js
+++ b/addons/web/static/src/js/core/utils.js
@@ -392,6 +392,23 @@ var utils = {
array[i2] = elem1;
array[i1] = elem2;
},
+
+ /**
+ * @param {string} value
+ * @param {boolean} allow_mailto
+ * @returns boolean
+ */
+ is_email: function (value, allow_mailto) {
+ // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
+ var re;
+ if (allow_mailto) {
+ re = /^(mailto:)?(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+ } else {
+ re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+ }
+ return re.test(value);
+ },
+
/**
* @param {any} str
* @param {any} elseValues
diff --git a/addons/web_editor/static/src/js/widgets/widgets.js b/addons/web_editor/static/src/js/widgets/widgets.js
index b5fc34f6ee9..a7046eb11e8 100644
--- a/addons/web_editor/static/src/js/widgets/widgets.js
+++ b/addons/web_editor/static/src/js/widgets/widgets.js
@@ -4,6 +4,7 @@ odoo.define('web_editor.widget', function (require) {
var core = require('web.core');
var Dialog = require('web.Dialog');
var Widget = require('web.Widget');
+var utils = require('web.utils');
var weContext = require("web_editor.context");
var QWeb = core.qweb;
@@ -1208,6 +1209,7 @@ var LinkDialog = Dialog.extend({
if (!$e.length) {
$e = this.$('input.url-source:first');
}
+ $e.closest('.form-group').removeClass('has-error');
var val = $e.val();
var label = this.$('#o_link_dialog_label_input').val() || val;
@@ -1228,8 +1230,7 @@ var LinkDialog = Dialog.extend({
var size = this.$("select.link-style").val() || '';
var classes = (this.data.className || "") + (style && style.length ? " btn " : "") + style + " " + size;
var isNewWindow = this.$('input.window-new').prop('checked');
-
- if ($e.hasClass('email-address') && $e.val().indexOf("@") !== -1) {
+ if ($e.hasClass('email-address') && (_.str.startsWith(val, 'mailto:') || (val.indexOf("@") !== -1 && !_.str.startsWith(val, 'http') && !_.str.startsWith(val, 'www')))) {
self.get_data_buy_mail(def, $e, isNewWindow, label, classes, test);
} else {
self.get_data_buy_url(def, $e, isNewWindow, label, classes, test);
@@ -1238,7 +1239,13 @@ var LinkDialog = Dialog.extend({
},
get_data_buy_mail: function (def, $e, isNewWindow, label, classes, test) {
var val = $e.val();
- def.resolve(val.indexOf("mailto:") === 0 ? val : 'mailto:' + val, isNewWindow, label, classes);
+ if (utils.is_email(val, true)) {
+ def.resolve(val.indexOf("mailto:") === 0 ? val : 'mailto:' + val, isNewWindow, label, classes);
+ } else {
+ $e.closest('.form-group').addClass('has-error');
+ $e.focus();
+ def.reject();
+ }
},
get_data_buy_url: function (def, $e, isNewWindow, label, classes, test) {
def.resolve($e.val(), isNewWindow, label, classes);
diff --git a/addons/website_quote/models/sale_order.py b/addons/website_quote/models/sale_order.py
index a54e8368c24..a798cb01b52 100644
--- a/addons/website_quote/models/sale_order.py
+++ b/addons/website_quote/models/sale_order.py
@@ -70,9 +70,16 @@ class SaleOrder(models.Model):
require_payment = fields.Selection([
(0, 'Online Signature'),
(1, 'Online Payment')], default=_get_default_online_payment, string='Confirmation Mode',
+ compute='_compute_require_payment', store=True,
help="Choose how you want to confirm an order to launch the delivery process. You can either "
"request a digital signature or an upfront payment. With a digital signature, you can "
"request the payment when issuing the invoice.")
+ @api.one
+ @api.depends('template_id')
+ def _compute_require_payment(self):
+ # Do not overwrite if the field is already set
+ if self.template_id and (self.require_payment is None or self.require_payment is False):
+ self.require_payment = self.template_id.require_payment
@api.multi
def copy(self, default=None):
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index 795204cf25e..2fe73d24432 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -600,14 +600,11 @@
<input type="hidden" t-if="len(product.product_variant_ids) == 1" class="product_id" name="product_id" t-att-value="product.product_variant_id.id"/>
<t t-if="len(product.product_variant_ids) &gt; 1">
<label label-default="label-default" class="radio" t-foreach="product.product_variant_ids" t-as="variant_id">
- <input type="radio" name="product_id" class="js_product_change" t-att-checked="'checked' if variant_id_index == 0 else None" t-att-value="variant_id.id" t-att-data-lst_price="variant_id.lst_price" t-att-data-price="variant_id.price"/>
+ <input type="radio" name="product_id" class="js_product_change" t-att-checked="'checked' if variant_id_index == 0 else ''" t-att-value="variant_id.id" t-att-data-lst_price="compute_currency(variant_id.lst_price)" t-att-data-price="variant_id.price"/>
<span t-esc="variant_id.name_get()[0][1]"/>
- <span class="badge" t-if="variant_id.price_extra">
- <t t-esc="variant_id.price_extra > 0 and '+' or ''"/><span t-field="variant_id.price_extra" style="white-space: nowrap;" t-options='{
- "widget": "monetary",
- "from_currency": product.currency_id,
- "display_currency": website.currency_id
- }'/>
+ <t t-set="diff_price" t-value="variant_id.price - variant_id.product_tmpl_id.price"/>
+ <span class="badge" t-if="diff_price != 0">
+ <t t-esc="diff_price > 0 and '+' or '-'"/><span t-esc="abs(diff_price)" t-esc-options='{"widget": "monetary", "display_currency": "website.currency_id"}'/>
</span>
</label>
</t>