diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py
index 211bf774f1f..39b90ce9f31 100644
--- a/addons/account/models/chart_template.py
+++ b/addons/account/models/chart_template.py
@@ -38,8 +38,7 @@ def migrate_tags_on_taxes(cr, registry):
('type_tax_use', '=', tax_template.type_tax_use),
('description', '=', tax_template.description)
])
- if len(tax_id.ids) == 1:
- tax_id.sudo().write({'tag_ids': [(6, 0, tax_template.tag_ids.ids)]})
+ tax_id.sudo().write({'tag_ids': [(6, 0, tax_template.tag_ids.ids)]})
def preserve_existing_tags_on_taxes(cr, registry, module):
''' This is a utility function used to preserve existing previous tags during upgrade of the module.'''
diff --git a/addons/l10n_fr_certification/models/account.py b/addons/l10n_fr_certification/models/account.py
index 07d5fc04e41..94db3c46273 100644
--- a/addons/l10n_fr_certification/models/account.py
+++ b/addons/l10n_fr_certification/models/account.py
@@ -144,8 +144,9 @@ class AccountJournal(models.Model):
@api.multi
def write(self, vals):
# restrict the operation in case we are trying to write a forbidden field
- if self.company_id.country_id.code == 'FR' and vals.get('update_posted'):
- raise UserError(ERR_MSG % (self._name, 'update_posted'))
+ for rec in self:
+ if rec.company_id.country_id.code == 'FR' and vals.get('update_posted'):
+ raise UserError(ERR_MSG % (self._name, 'update_posted'))
return super(AccountJournal, self).write(vals)
@api.model
diff --git a/addons/payment_authorize/models/authorize_request.py b/addons/payment_authorize/models/authorize_request.py
index 1ae0e71b6ed..6e0987b2de6 100644
--- a/addons/payment_authorize/models/authorize_request.py
+++ b/addons/payment_authorize/models/authorize_request.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from lxml import etree, objectify
+import logging
from urllib2 import urlopen, Request
from StringIO import StringIO
import xml.etree.ElementTree as ET
@@ -11,6 +12,8 @@ from odoo import _
XMLNS = 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'
+_logger = logging.getLogger(__name__)
+
def strip_ns(xml, ns):
"""Strip the provided name from tag names.
@@ -58,11 +61,13 @@ class AuthorizeAPI():
:param etree._Element data: etree data to process
"""
- data = etree.tostring(data, xml_declaration=True, encoding='utf-8')
- request = Request(self.url, data)
+ data_tree = etree.tostring(data, xml_declaration=True, encoding='utf-8')
+ request = Request(self.url, data_tree)
request.add_header('Content-Type', 'text/xml')
+ _logger.debug('Authorize.net request sent: \n%s', etree.tostring(data, pretty_print=True))
response = urlopen(request).read()
response = strip_ns(response, XMLNS)
+ _logger.debug('Authorize.net response: \n%s', etree.tostring(response, pretty_print=True))
if response.find('messages/resultCode').text == 'Error':
messages = map(lambda m: m.text, response.findall('messages/message/text'))
raise ValidationError(_('Authorize.net Error Message(s):\n %s') % '\n'.join(messages))
diff --git a/addons/purchase/security/purchase_security.xml b/addons/purchase/security/purchase_security.xml
index 1416745a8bb..4c409175bb4 100644
--- a/addons/purchase/security/purchase_security.xml
+++ b/addons/purchase/security/purchase_security.xml
@@ -51,5 +51,12 @@
['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
+
+ Purchase Order Report multi-company
+
+
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
+
+
diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js
index b84cd0f58f8..014a9becc16 100644
--- a/addons/web/static/src/js/boot.js
+++ b/addons/web/static/src/js/boot.js
@@ -10,7 +10,7 @@
* only when the deferred is resolved, and its value is equal to the resolved value.
* The module can be rejected (unloaded). This will be logged in the console as info.
*
- * logs:
+ * logs:
* Missing dependencies:
* These modules do not appear in the page. It is possible that the
* JavaScript file is not in the page or that the module name is wrong
@@ -180,16 +180,27 @@
var failed = odoo.__DEBUG__.get_failed_jobs();
var unloaded = _.filter(debug_jobs, function (job) { return job.missing; });
- var log = [(_.isEmpty(failed) ? (_.isEmpty(unloaded) ? 'info' : 'warning' ) : 'error') + ':', 'Some modules could not be started'];
- if (missing.length) log.push('\nMissing dependencies: ', missing);
- if (!_.isEmpty(failed)) log.push('\nFailed modules: ', _.pluck(failed, 'name'));
- if (!_.isEmpty(rejected)) log.push('\nRejected modules: ', rejected);
- if (!_.isEmpty(rejected_linked))log.push('\nRejected linked modules:', rejected_linked);
- if (!_.isEmpty(unloaded)) log.push('\nNon loaded modules: ', _.pluck(unloaded, 'name'));
- if (odoo.debug && !_.isEmpty(debug_jobs)) log.push('\nDebug: ', debug_jobs);
-
if (odoo.debug || !_.isEmpty(failed) || !_.isEmpty(unloaded)) {
- console[_.isEmpty(failed) || _.isEmpty(unloaded) ? 'info' : 'error'].apply(console, log);
+ var log = console[_.isEmpty(failed) || _.isEmpty(unloaded) ? 'info' : 'error'].bind(console);
+ log((_.isEmpty(failed) ? (_.isEmpty(unloaded) ? 'info' : 'warning') : 'error') + ': Some modules could not be started');
+ if (missing.length) {
+ log('Missing dependencies: ', missing);
+ }
+ if (!_.isEmpty(failed)) {
+ log('Failed modules: ', _.pluck(failed, 'name'));
+ }
+ if (!_.isEmpty(rejected)) {
+ log('Rejected modules: ', rejected);
+ }
+ if (!_.isEmpty(rejected_linked)) {
+ log('Rejected linked modules: ', rejected_linked);
+ }
+ if (!_.isEmpty(unloaded)) {
+ log('Non loaded modules: ', _.pluck(unloaded, 'name'));
+ }
+ if (odoo.debug && !_.isEmpty(debug_jobs)) {
+ log('Debug: ', debug_jobs);
+ }
}
}
},
diff --git a/addons/web_editor/static/src/js/widgets.js b/addons/web_editor/static/src/js/widgets.js
index eb34bd152ca..91025773cb4 100644
--- a/addons/web_editor/static/src/js/widgets.js
+++ b/addons/web_editor/static/src/js/widgets.js
@@ -617,7 +617,7 @@ var fontIconsDialog = Widget.extend({
e.stopPropagation();
this.$('#fa-icon').val(e.target.getAttribute('data-id'));
- $(".font-icons-icon").removeClass("o_selected");
+ this.$(".font-icons-icon").removeClass("o_selected");
$(e.target).addClass("o_selected");
},
'dblclick .font-icons-icon': function () {
@@ -743,7 +743,7 @@ var fontIconsDialog = Widget.extend({
continue;
case '': continue;
default:
- $(".font-icons-icon").removeClass("o_selected").filter("[data-alias*=',"+cls+",']").addClass("o_selected");
+ this.$(".font-icons-icon").removeClass("o_selected").filter("[data-alias*=',"+cls+",']").addClass("o_selected");
if (this.alias.indexOf(cls) !== -1) {
this.$('#fa-icon').val(cls);
}
diff --git a/addons/website_portal_sale/models/payment.py b/addons/website_portal_sale/models/payment.py
index 3302ac87967..176f041847a 100644
--- a/addons/website_portal_sale/models/payment.py
+++ b/addons/website_portal_sale/models/payment.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
-from odoo import api, fields, models
+from odoo import _, api, fields, models
from odoo.tools import float_compare
_logger = logging.getLogger(__name__)
@@ -81,4 +81,16 @@ class PaymentTransaction(models.Model):
_logger.info('<%s> transaction pending/to confirm manually, sending quote email for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id)
tx.sale_order_id.force_quotation_send()
else:
- _logger.warning('<%s> transaction MISMATCH for order %s (ID %s)', acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id)
+ _logger.warning(
+ '<%s> transaction AMOUNT MISMATCH for order %s (ID %s): expected %r, got %r',
+ acquirer_name, tx.sale_order_id.name, tx.sale_order_id.id,
+ tx.sale_order_id.amount_total, tx.amount,
+ )
+ tx.sale_order_id.message_post(
+ subject=_("Amount Mismatch (%s)") % acquirer_name,
+ body=_("The sale order was not confirmed despite response from the acquirer (%s): SO amount is %r but acquirer replied with %r.") % (
+ acquirer_name,
+ tx.sale_order_id.amount_total,
+ tx.amount,
+ )
+ )
diff --git a/doc/cla/individual/elgow.md b/doc/cla/individual/elgow.md
new file mode 100644
index 00000000000..930d08bcec9
--- /dev/null
+++ b/doc/cla/individual/elgow.md
@@ -0,0 +1,11 @@
+USA, 16 Nov 2017
+
+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,
+
+Edward Gow elgow@users.noreply.github.com https://github.com/elgow
diff --git a/requirements.txt b/requirements.txt
index b079a99745c..faa6eecffa9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,7 +17,7 @@ passlib==1.6.5
Pillow==3.4.1
psutil==4.3.1
psycogreen==1.0
-psycopg2==2.7.3
+psycopg2==2.7.3.1
pydot==1.2.3
pyparsing==2.1.10
pyPdf==1.13