[MERGE] forward port branch 8.0 up to ecb6055
This commit is contained in:
@@ -805,11 +805,20 @@ class account_invoice(models.Model):
|
||||
|
||||
ctx = dict(self._context, lang=inv.partner_id.lang)
|
||||
|
||||
company_currency = inv.company_id.currency_id
|
||||
if not inv.date_invoice:
|
||||
# FORWARD-PORT UP TO SAAS-6
|
||||
if inv.currency_id != company_currency and inv.tax_line:
|
||||
raise except_orm(
|
||||
_('Warning!'),
|
||||
_('No invoice date!'
|
||||
'\nThe invoice currency is not the same than the company currency.'
|
||||
' An invoice date is required to determine the exchange rate to apply. Do not forget to update the taxes!'
|
||||
)
|
||||
)
|
||||
inv.with_context(ctx).write({'date_invoice': fields.Date.context_today(self)})
|
||||
date_invoice = inv.date_invoice
|
||||
|
||||
company_currency = inv.company_id.currency_id
|
||||
# create the analytical lines, one move line per invoice line
|
||||
iml = inv._get_analytic_lines()
|
||||
# check if taxes are all computed
|
||||
|
||||
@@ -561,7 +561,7 @@
|
||||
<field name="source_id" invisible="1"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="planned_revenue" sum="Expected Revenues"/>
|
||||
<field name="probability" avg="Avg. of Probability"/>
|
||||
<field name="probability" />
|
||||
<field name="team_id" groups="base.group_multi_salesteams"/>
|
||||
<field name="user_id"/>
|
||||
<field name="referred" invisible="1"/>
|
||||
|
||||
@@ -2190,7 +2190,6 @@ instance.web.list.Column = instance.web.Class.extend({
|
||||
id: id,
|
||||
tag: tag
|
||||
});
|
||||
|
||||
this.modifiers = attrs.modifiers ? JSON.parse(attrs.modifiers) : {};
|
||||
delete attrs.modifiers;
|
||||
_.extend(this, attrs);
|
||||
@@ -2217,10 +2216,14 @@ instance.web.list.Column = instance.web.Class.extend({
|
||||
if (this.type !== 'integer' && this.type !== 'float') {
|
||||
return {};
|
||||
}
|
||||
var aggregation_func = this['group_operator'] || 'sum';
|
||||
if (!(aggregation_func in this)) {
|
||||
|
||||
var aggregation_func = (this.sum && 'sum') || (this.avg && 'avg') ||
|
||||
(this.max && 'max') || (this.min && 'min') || this.group_operator;
|
||||
|
||||
if (!aggregation_func) {
|
||||
return {};
|
||||
}
|
||||
|
||||
var C = function (fn, label) {
|
||||
this['function'] = fn;
|
||||
this.label = label;
|
||||
|
||||
@@ -12,6 +12,7 @@ It also will include the feedback tool for the livechat, and web pages to displa
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['website', 'im_livechat'],
|
||||
'installable': True,
|
||||
'auto_install': True,
|
||||
'data': [
|
||||
'views/website_livechat.xml',
|
||||
'views/res_config.xml',
|
||||
|
||||
@@ -145,10 +145,17 @@ class Discussion(models.Model):
|
||||
message_changes = fields.Integer(string='Message changes')
|
||||
important_messages = fields.One2many('test_new_api.message', 'discussion',
|
||||
domain=[('important', '=', True)])
|
||||
very_important_messages = fields.One2many(
|
||||
'test_new_api.message', 'discussion',
|
||||
domain=lambda self: self._domain_very_important())
|
||||
emails = fields.One2many('test_new_api.emailmessage', 'discussion')
|
||||
important_emails = fields.One2many('test_new_api.emailmessage', 'discussion',
|
||||
domain=[('important', '=', True)])
|
||||
|
||||
def _domain_very_important(self):
|
||||
"""Ensure computed O2M domains work as expected."""
|
||||
return [("important", "=", True)]
|
||||
|
||||
@api.onchange('moderator')
|
||||
def _onchange_moderator(self):
|
||||
self.participants |= self.moderator
|
||||
|
||||
@@ -469,6 +469,12 @@ class TestNewFields(common.TransactionCase):
|
||||
message.important = True
|
||||
self.assertIn(message, discussion.important_messages)
|
||||
|
||||
# writing on very_important_messages should call its domain method
|
||||
self.assertIn(message, discussion.very_important_messages)
|
||||
discussion.write({'very_important_messages': [(5,)]})
|
||||
self.assertFalse(discussion.very_important_messages)
|
||||
self.assertFalse(message.exists())
|
||||
|
||||
|
||||
class TestMagicFields(common.TransactionCase):
|
||||
|
||||
|
||||
+3
-1
@@ -1041,6 +1041,7 @@ class Integer(Field):
|
||||
}
|
||||
|
||||
_related_group_operator = property(attrgetter('group_operator'))
|
||||
_description_group_operator = property(attrgetter('group_operator'))
|
||||
_column_group_operator = property(attrgetter('group_operator'))
|
||||
|
||||
def convert_to_cache(self, value, record, validate=True):
|
||||
@@ -1101,6 +1102,7 @@ class Float(Field):
|
||||
_related_group_operator = property(attrgetter('group_operator'))
|
||||
|
||||
_description_digits = property(attrgetter('digits'))
|
||||
_description_group_operator = property(attrgetter('group_operator'))
|
||||
|
||||
_column_digits = property(lambda self: not callable(self._digits) and self._digits)
|
||||
_column_digits_compute = property(lambda self: callable(self._digits) and self._digits)
|
||||
@@ -1129,7 +1131,7 @@ class _String(Field):
|
||||
_column_translate = property(attrgetter('translate'))
|
||||
_related_translate = property(attrgetter('translate'))
|
||||
_description_translate = property(attrgetter('translate'))
|
||||
|
||||
|
||||
|
||||
class Char(_String):
|
||||
""" Basic string field, can be length-limited, usually displayed as a
|
||||
|
||||
@@ -788,6 +788,7 @@ class one2many(_column):
|
||||
context.update(self._context)
|
||||
if not values:
|
||||
return
|
||||
original_obj = obj
|
||||
obj = obj.pool[self._obj]
|
||||
rec = obj.browse(cr, user, [], context=context)
|
||||
with rec.env.norecompute():
|
||||
@@ -819,7 +820,8 @@ class one2many(_column):
|
||||
inverse_field = obj._fields.get(self._fields_id)
|
||||
assert inverse_field, 'Trying to unlink the content of a o2m but the pointed model does not have a m2o'
|
||||
# if the o2m has a static domain we must respect it when unlinking
|
||||
domain = self._domain(obj) if callable(self._domain) else self._domain
|
||||
domain = (self._domain(original_obj)
|
||||
if callable(self._domain) else self._domain)
|
||||
extra_domain = domain or []
|
||||
ids_to_unlink = obj.search(cr, user, [(self._fields_id,'=',id)] + extra_domain, context=context)
|
||||
# If the model has cascade deletion, we delete the rows because it is the intended behavior,
|
||||
|
||||
@@ -446,7 +446,7 @@ class configmanager(object):
|
||||
for x in self.options['addons_path'].split(','))
|
||||
|
||||
self.options['init'] = opt.init and dict.fromkeys(opt.init.split(','), 1) or {}
|
||||
self.options["demo"] = not opt.without_demo and self.options['init'] or {}
|
||||
self.options['demo'] = not opt.without_demo and dict(self.options['init']) or {}
|
||||
self.options['update'] = opt.update and dict.fromkeys(opt.update.split(','), 1) or {}
|
||||
self.options['translate_modules'] = opt.translate_modules and map(lambda m: m.strip(), opt.translate_modules.split(',')) or ['all']
|
||||
self.options['translate_modules'].sort()
|
||||
|
||||
Reference in New Issue
Block a user