+
-
+
diff --git a/addons/payment_authorize/models/payment.py b/addons/payment_authorize/models/payment.py
index 01f7fc3f9b9..2f5e8027f91 100644
--- a/addons/payment_authorize/models/payment.py
+++ b/addons/payment_authorize/models/payment.py
@@ -126,7 +126,7 @@ class PaymentAcquirerAuthorize(models.Model):
for field_name in mandatory_fields:
if not data.get(field_name):
error[field_name] = 'missing'
- if data['cc_expiry'] and datetime.now().strftime('%y%M') > datetime.strptime(data['cc_expiry'], '%M / %y').strftime('%y%M'):
+ if data['cc_expiry'] and datetime.now().strftime('%y%m') > datetime.strptime(data['cc_expiry'], '%m / %y').strftime('%y%m'):
return False
return False if error else True
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py
index 60accc2d713..65756125982 100644
--- a/addons/purchase/models/purchase.py
+++ b/addons/purchase/models/purchase.py
@@ -760,10 +760,10 @@ class PurchaseOrderLine(models.Model):
self.product_uom = self.product_id.uom_po_id or self.product_id.uom_id
result['domain'] = {'product_uom': [('category_id', '=', self.product_id.uom_id.category_id.id)]}
- product_lang = self.product_id.with_context({
- 'lang': self.partner_id.lang,
- 'partner_id': self.partner_id.id,
- })
+ product_lang = self.product_id.with_context(
+ lang=self.partner_id.lang,
+ partner_id=self.partner_id.id,
+ )
self.name = product_lang.display_name
if product_lang.description_purchase:
self.name += '\n' + product_lang.description_purchase
diff --git a/addons/web_editor/static/src/js/rte.js b/addons/web_editor/static/src/js/rte.js
index e177846c0fd..9ce1e5fb255 100644
--- a/addons/web_editor/static/src/js/rte.js
+++ b/addons/web_editor/static/src/js/rte.js
@@ -271,10 +271,11 @@ var RTE = Widget.extend({
* @param {DOM} target where the dom is changed is editable zone
*/
historyRecordUndo: function ($target, event, internal_history) {
+ $target = $($target);
var rng = range.create();
var $editable = $(rng && rng.sc).closest(".o_editable");
if (!rng || !$editable.length) {
- $editable = $($target).closest(".o_editable");
+ $editable = $target.closest(".o_editable");
rng = range.create($target.closest("*")[0],0);
} else {
rng = $editable.data('range') || rng;
diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js
index e439f52824a..35e49346ee0 100644
--- a/addons/web_editor/static/src/js/summernote.js
+++ b/addons/web_editor/static/src/js/summernote.js
@@ -886,37 +886,67 @@ range.WrappedRange.prototype.reRange = function (keep_end, isNotBreakable) {
return new range.WrappedRange(sc, so, ec, eo);
};
-// isOnImg: judge whether range is an image node or not
+/**
+ * Returns the image the range is in or matches (if any, false otherwise).
+ *
+ * @todo this implementation may not cover all corner cases but should do the
+ * trick for all reproductible ones
+ * @returns {DOMElement|boolean}
+ */
range.WrappedRange.prototype.isOnImg = function () {
+ // If not a selection but a cursor position, just check if a point's
+ // ancestor is an image or not
+ if (this.sc === this.ec && this.so === this.eo) {
+ return dom.ancestor(this.sc, dom.isImg);
+ }
+
+ var startPoint = {node: this.sc, offset: this.so};
+ var endPoint = {node: this.ec, offset: this.eo};
+
var nb = 0;
var image;
- var startPoint = {node: this.sc.childNodes.length && this.sc.childNodes[this.so] || this.sc};
- startPoint.offset = startPoint.node === this.sc ? this.so : 0;
- var endPoint = {node: this.ec.childNodes.length && this.ec.childNodes[this.eo] || this.ec};
- endPoint.offset = endPoint.node === this.ec ? this.eo : 0;
-
- if (dom.isImg(startPoint.node)) {
- nb ++;
- image = startPoint.node;
- }
+ var textNode;
dom.walkPoint(startPoint, endPoint, function (point) {
- if (!dom.isText(endPoint.node) && point.node === endPoint.node && point.offset === endPoint.offset) {
+ // If the element has children (not a text node and not empty node),
+ // the element cannot be considered as selected (these children will
+ // be processed to determine that)
+ if (dom.hasChildren(point.node)) {
return;
}
- var node = point.node.childNodes.length && point.node.childNodes[point.offset] || point.node;
- var offset = node === point.node ? point.offset : 0;
- var isImg = dom.ancestor(node, dom.isImg);
- if (!isImg && ((!dom.isBR(node) && !dom.isText(node)) || (offset && node.textContent.length !== offset && node.textContent.match(/\S|\u00A0/)))) {
+
+ // Check if an ancestor of the current point is an image
+ var pointImg = dom.ancestor(point.node, dom.isImg);
+ var isText = dom.isText(point.node);
+
+ // Check if a visible element is selected, i.e.
+ // - If an ancestor of the current is an image we did not see yet
+ // - If the point is not in a br or a text (so a node with no children)
+ // - If the point is in a non empty text node we already saw
+ if (pointImg ?
+ (image !== pointImg) :
+ ((!dom.isBR(point.node) && !isText) || (textNode === point.node && point.node.textContent.match(/\S|\u00A0/)))) {
nb++;
}
- if (isImg && image !== isImg) {
- image = isImg;
- nb ++;
+
+ // If an ancestor of the current point is an image, then save it as the
+ // image we are looking for
+ if (pointImg) {
+ image = pointImg;
+ }
+ // If the current point is a text node save it as the last text node
+ // seen (if we see it again, this might mean it is selected)
+ if (isText) {
+ textNode = point.node;
}
});
+
return nb === 1 && image;
};
range.WrappedRange.prototype.deleteContents = function (towrite) {
+ if (this.sc === this.ec && this.so === this.eo) {
+ return this;
+ }
+
var prevBP = dom.removeBetween(this.sc, this.so, this.ec, this.eo, towrite);
$(dom.node(prevBP.sc)).trigger("click"); // trigger click to disable and reanable editor and image handler
diff --git a/doc/cla/corporate/bas-solutions.md b/doc/cla/corporate/bas-solutions.md
deleted file mode 100644
index f0d49c7facf..00000000000
--- a/doc/cla/corporate/bas-solutions.md
+++ /dev/null
@@ -1,16 +0,0 @@
-Netherlands, 8-2-2015
-
-BAS Solutions agrees to the terms of the Odoo Corporate Contributor License
-Agreement v1.0.
-
-I declare that I am authorized and able to make this agreement and sign this
-declaration.
-
-Signed,
-
-Erwin van der Ploeg erwin@bas-solutions.nl https://github.com/erwin-bas-solutions
-
-List of contributors:
-
-Erwin van der Ploeg erwin@bas-solutions.nl https://github.com/erwin-bas-solutions
-Ruchir Shukla ruchir@bas-solutions.nl https://github.com/ruchir-bas-solutions
\ No newline at end of file
diff --git a/doc/cla/corporate/odooexperts.md b/doc/cla/corporate/odooexperts.md
new file mode 100644
index 00000000000..3a73e799b87
--- /dev/null
+++ b/doc/cla/corporate/odooexperts.md
@@ -0,0 +1,16 @@
+Netherlands, 18-1-2018
+
+Odoo Experts agrees to the terms of the Odoo Corporate Contributor License
+Agreement v1.0.
+
+I declare that I am authorized and able to make this agreement and sign this
+declaration.
+
+Signed,
+
+Erwin van der Ploeg erwin@bas-solutions.nl https://github.com/erwin-bas-solutions
+
+List of contributors:
+
+Erwin van der Ploeg erwin@odooexperts.nl https://github.com/ploegvde
+Yenthe Van Ginneken yenthe@odooexperts.nl https://github.com/Yenthe666