[MERGE] forward port branch saas-11 up to 321b7dc
This commit is contained in:
@@ -21,8 +21,9 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
#TOCHECK: normal and cash basis taxes shoudn't be mixed together (on the same invoice line for example) as it will
|
||||
#create reporting issues. Not sure of the behavior to implement in that case, though.
|
||||
# amount to write is the current cash_basis amount minus the one before the reconciliation
|
||||
currency_id = line.currency_id or line.company_id.currency_id
|
||||
matched_percentage = value_before_reconciliation[move.id]
|
||||
amount = line.currency_id.round((line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage)
|
||||
amount = currency_id.round((line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage)
|
||||
if not line.tax_exigible:
|
||||
if line.tax_line_id and line.tax_line_id.use_cash_basis:
|
||||
# group by line account
|
||||
@@ -42,16 +43,16 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
for tax in line.tax_ids:
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'debit': line.currency_id.round(line.debit_cash_basis - line.debit * matched_percentage),
|
||||
'credit': line.currency_id.round(line.credit_cash_basis - line.credit * matched_percentage),
|
||||
'debit': currency_id.round(line.debit_cash_basis - line.debit * matched_percentage),
|
||||
'credit': currency_id.round(line.credit_cash_basis - line.credit * matched_percentage),
|
||||
'account_id': line.account_id.id,
|
||||
'tax_ids': [(6, 0, [tax.id])],
|
||||
'tax_exigible': True,
|
||||
}))
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'credit': line.currency_id.round(line.debit_cash_basis - line.debit * matched_percentage),
|
||||
'debit': line.currency_id.round(line.credit_cash_basis - line.credit * matched_percentage),
|
||||
'credit': currency_id.round(line.debit_cash_basis - line.debit * matched_percentage),
|
||||
'debit': currency_id.round(line.credit_cash_basis - line.credit * matched_percentage),
|
||||
'account_id': line.account_id.id,
|
||||
'tax_exigible': True,
|
||||
}))
|
||||
|
||||
@@ -63,8 +63,7 @@ class AuthSignupHome(Home):
|
||||
qcontext['error'] = _("Could not reset your password")
|
||||
_logger.exception('error when resetting password')
|
||||
except Exception, e:
|
||||
qcontext['error'] = e.message
|
||||
|
||||
qcontext['error'] = e.message or e.name
|
||||
|
||||
return request.render('auth_signup.reset_password', qcontext)
|
||||
|
||||
|
||||
@@ -4,6 +4,16 @@ odoo.define('barcodes.BarcodeEvents', function(require) {
|
||||
var core = require('web.core');
|
||||
var mixins = core.mixins;
|
||||
|
||||
|
||||
// For IE >= 9, use this, new CustomEvent(), instead of new Event()
|
||||
function CustomEvent ( event, params ) {
|
||||
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||
var evt = document.createEvent( 'CustomEvent' );
|
||||
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
|
||||
return evt;
|
||||
}
|
||||
CustomEvent.prototype = window.Event.prototype;
|
||||
|
||||
var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
|
||||
timeout: null,
|
||||
key_pressed: {},
|
||||
@@ -63,10 +73,16 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
|
||||
// bug for the longest time that causes keyCode and
|
||||
// charCode to not be set for events created this way:
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=16735
|
||||
new_event = new Event("keypress", {
|
||||
var params = {
|
||||
'bubbles': old_event.bubbles,
|
||||
'cancelable': old_event.cancelable,
|
||||
});
|
||||
};
|
||||
try {
|
||||
new_event = new Event("keypress", params);
|
||||
} catch(error) {
|
||||
// For IE >= 9, use new CustomEvent(), instead of new Event()
|
||||
new_event = new CustomEvent("keypress", params);
|
||||
}
|
||||
|
||||
new_event.viewArg = old_event.viewArg;
|
||||
new_event.ctrl = old_event.ctrl;
|
||||
|
||||
@@ -669,7 +669,7 @@ Andrew</p>]]></field>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Birmingham</field>
|
||||
<field name="zip">B46 3AG</field>
|
||||
<field name="street">81 Academy Avenue</field>
|
||||
<field name="street">Cannon Hill Park</field>
|
||||
<field name="tag_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="next_activity_id" ref="crm_activity_data_meeting"/>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
{
|
||||
"name": "Slovenian - Accounting",
|
||||
"versiom": "1.1",
|
||||
"author": "Mentis d.o.o.",
|
||||
"website": "http://www.mentis.si",
|
||||
'category': 'Localization',
|
||||
|
||||
@@ -96,14 +96,14 @@ code,id,user_type_id/id,name,reconcile,chart_template_id/id
|
||||
155000,gd_acc_155000,account.data_account_type_current_assets,"DRUGE KRATKOROČNE TERJATVE, POVEZANE S FINANČNIMI PRIHODKI",False,gd_chart
|
||||
159000,gd_acc_159000,account.data_account_type_current_assets,"OSLABITEV VREDNOSTI KRATKOROČNIH TERJATEV, POVEZANIH S FINANČNIMI PRIHODKI",False,gd_chart
|
||||
160001,gd_acc_160001,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA NEODBITNI DDV",False,gd_chart
|
||||
160002,gd_acc_160002,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 8,5%",False,gd_chart
|
||||
160003,gd_acc_160003,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 20%",False,gd_chart
|
||||
160004,gd_acc_160004,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 8,5% V EU",False,gd_chart
|
||||
160005,gd_acc_160005,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 20% V EU",False,gd_chart
|
||||
160006,gd_acc_160006,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 8,5% IZVEN EU",False,gd_chart
|
||||
160007,gd_acc_160007,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 20% IZVEN EU",False,gd_chart
|
||||
160008,gd_acc_160008,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 8,5% UVOZ",False,gd_chart
|
||||
160009,gd_acc_160009,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 20% UVOZ",False,gd_chart
|
||||
160002,gd_acc_160002,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 9,5%",False,gd_chart
|
||||
160003,gd_acc_160003,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 22%",False,gd_chart
|
||||
160004,gd_acc_160004,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 9,5% V EU",False,gd_chart
|
||||
160005,gd_acc_160005,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 22% V EU",False,gd_chart
|
||||
160006,gd_acc_160006,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 9,5% IZVEN EU",False,gd_chart
|
||||
160007,gd_acc_160007,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 22% IZVEN EU",False,gd_chart
|
||||
160008,gd_acc_160008,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 9,5% UVOZ",False,gd_chart
|
||||
160009,gd_acc_160009,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA ODBITNI DDV 22% UVOZ",False,gd_chart
|
||||
161000,gd_acc_161000,account.data_account_type_current_assets,"KRATKOROČNE TERJATVE ZA DAVEK OD DOHODKOV PRAVNIH OSEB, VKLJUČNO Z DAVKOM, PLAČANIM V TUJINI",False,gd_chart
|
||||
162000,gd_acc_162000,account.data_account_type_current_assets,"DRUGE KRATKOROČNE TERJATVE DO DRŽAVNIH IN DRUGIH INŠTITUCIJ",False,gd_chart
|
||||
165000,gd_acc_165000,account.data_account_type_current_assets,"OSTALE KRATKOROČNE TERJATVE",False,gd_chart
|
||||
@@ -152,12 +152,12 @@ code,id,user_type_id/id,name,reconcile,chart_template_id/id
|
||||
255000,gd_acc_255000,account.data_account_type_current_liabilities,"KRATKOROČNE OBVEZNOSTI ZA DRUGE PREJEMKE IZ DELOVNEGA RAZMERJA",False,gd_chart
|
||||
256000,gd_acc_256000,account.data_account_type_current_liabilities,"KRATKOROČNE OBVEZNOSTI ZA PRISPEVKE IZ DRUGIH PREJEMKOV IZ DELOVNEGA RAZMERJA, KI SE NE OBRAČUNAVAJO SKUPAJ S PLAČAMI",False,gd_chart
|
||||
257000,gd_acc_257000,account.data_account_type_current_liabilities,"KRATKOROČNE OBVEZNOSTI ZA DAVEK IZ DRUGIH PREJEMKOV IZ DELOVNEGA RAZMERJA, KI SE NE OBRAČUNAVAJO SKUPAJ S PLAČAMI",False,gd_chart
|
||||
260001,gd_acc_260001,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 8,5%",False,gd_chart
|
||||
260002,gd_acc_260002,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 20%",False,gd_chart
|
||||
260003,gd_acc_260003,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 8,5% V EU",False,gd_chart
|
||||
260004,gd_acc_260004,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 20% V EU",False,gd_chart
|
||||
260005,gd_acc_260005,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 8,5% IZVEN EU",False,gd_chart
|
||||
260006,gd_acc_260006,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 20% IZVEN EU",False,gd_chart
|
||||
260001,gd_acc_260001,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 9,5%",False,gd_chart
|
||||
260002,gd_acc_260002,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 22%",False,gd_chart
|
||||
260003,gd_acc_260003,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 9,5% V EU",False,gd_chart
|
||||
260004,gd_acc_260004,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 22% V EU",False,gd_chart
|
||||
260005,gd_acc_260005,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 9,5% IZVEN EU",False,gd_chart
|
||||
260006,gd_acc_260006,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA ZARAČUNANI DDV 22% IZVEN EU",False,gd_chart
|
||||
261000,gd_acc_261000,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA DDV, CARINO IN DRUGE DAJATVE OD UVOŽENEGA BLAGA",False,gd_chart
|
||||
262000,gd_acc_262000,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA PRISPEVKE IZPLAČEVALCA",False,gd_chart
|
||||
263000,gd_acc_263000,account.data_account_type_current_liabilities,"OBVEZNOSTI ZA DAVEK OD IZPLAČANIH PLAČ",False,gd_chart
|
||||
|
||||
|
@@ -507,6 +507,12 @@ msgid "Unable to find Wkhtmltopdf on this \n"
|
||||
"wkhtmltopdf.org</a>"
|
||||
msgstr ""
|
||||
|
||||
#. module: report
|
||||
#: code:addons/report/models/report.py:164
|
||||
#, python-format
|
||||
msgid "Unable to find Wkhtmltopdf on this system. The PDF can not be created."
|
||||
msgstr ""
|
||||
|
||||
#. module: report
|
||||
#: model:ir.ui.view,arch_db:report.external_layout_footer
|
||||
msgid "Website:"
|
||||
@@ -542,17 +548,14 @@ msgid "base.config.settings"
|
||||
msgstr ""
|
||||
|
||||
#. module: report
|
||||
#: model:ir.model,name:report.model_ir_actions_report_xml
|
||||
msgid "ir.actions.report.xml"
|
||||
#. openerp-web
|
||||
#: code:addons/report/static/src/js/qwebactionmanager.js:96
|
||||
#, python-format
|
||||
msgid "Your installation of Wkhtmltopdf seems to be broken. The \n"
|
||||
"report will be shown in html.<br><br><a href=\"http://wkhtmltopdf.org/\" target=\"_blank\">wkhtmltopdf.org</a>"
|
||||
msgstr ""
|
||||
|
||||
#. module: report
|
||||
#: model:ir.model,name:report.model_ir_qweb_field_barcode
|
||||
msgid "ir.qweb.field.barcode"
|
||||
msgstr ""
|
||||
|
||||
#. module: report
|
||||
#: model:ir.model,name:report.model_report_abstract_report
|
||||
msgid "report.abstract_report"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -59,16 +59,21 @@ except (OSError, IOError):
|
||||
else:
|
||||
_logger.info('Will use the Wkhtmltopdf binary at %s' % _get_wkhtmltopdf_bin())
|
||||
out, err = process.communicate()
|
||||
version = re.search('([0-9.]+)', out or "0").group(0)
|
||||
if LooseVersion(version) < LooseVersion('0.12.0'):
|
||||
_logger.info('Upgrade Wkhtmltopdf to (at least) 0.12.0')
|
||||
wkhtmltopdf_state = 'upgrade'
|
||||
else:
|
||||
wkhtmltopdf_state = 'ok'
|
||||
match = re.search('([0-9.]+)', out)
|
||||
if match:
|
||||
version = match.group(0)
|
||||
if LooseVersion(version) < LooseVersion('0.12.0'):
|
||||
_logger.info('Upgrade Wkhtmltopdf to (at least) 0.12.0')
|
||||
wkhtmltopdf_state = 'upgrade'
|
||||
else:
|
||||
wkhtmltopdf_state = 'ok'
|
||||
|
||||
if config['workers'] == 1:
|
||||
_logger.info('You need to start Odoo with at least two workers to print a pdf version of the reports.')
|
||||
wkhtmltopdf_state = 'workers'
|
||||
if config['workers'] == 1:
|
||||
_logger.info('You need to start Odoo with at least two workers to print a pdf version of the reports.')
|
||||
wkhtmltopdf_state = 'workers'
|
||||
else:
|
||||
_logger.info('Wkhtmltopdf seems to be broken.')
|
||||
wkhtmltopdf_state = 'broken'
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
@@ -141,6 +146,14 @@ class Report(models.Model):
|
||||
def get_pdf(self, docids, report_name, html=None, data=None):
|
||||
"""This method generates and returns pdf version of a report.
|
||||
"""
|
||||
|
||||
if self._check_wkhtmltopdf() == 'install':
|
||||
# wkhtmltopdf is not installed
|
||||
# the call should be catched before (cf /report/check_wkhtmltopdf) but
|
||||
# if get_pdf is called manually (email template), the check could be
|
||||
# bypassed
|
||||
raise UserError(_("Unable to find Wkhtmltopdf on this system. The PDF can not be created."))
|
||||
|
||||
# As the assets are generated during the same transaction as the rendering of the
|
||||
# templates calling them, there is a scenario where the assets are unreachable: when
|
||||
# you make a request to read the assets while the transaction creating them is not done.
|
||||
|
||||
@@ -18,6 +18,7 @@ var WKHTMLTOPDF_MESSAGES = {
|
||||
'install': _lt('Unable to find Wkhtmltopdf on this \nsystem. The report will be shown in html.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">\nwkhtmltopdf.org</a>'),
|
||||
'workers': _lt('You need to start OpenERP with at least two \nworkers to print a pdf version of the reports.'),
|
||||
'upgrade': _lt('You should upgrade your version of\nWkhtmltopdf to at least 0.12.0 in order to get a correct display of headers and footers as well as\nsupport for table-breaking between pages.<br><br><a href="http://wkhtmltopdf.org/" \ntarget="_blank">wkhtmltopdf.org</a>'),
|
||||
'broken': _lt('Your installation of Wkhtmltopdf seems to be broken. The report will be shown in html.<br><br><a href="http://wkhtmltopdf.org/" target="_blank">wkhtmltopdf.org</a>')
|
||||
};
|
||||
|
||||
var trigger_download = function (session, response, c, action, options) {
|
||||
|
||||
@@ -697,7 +697,6 @@ class QuantPackage(models.Model):
|
||||
# TDE FIXME: why superuser ?
|
||||
package.mapped('quant_ids').sudo().write({'package_id': package.parent_id.id})
|
||||
package.mapped('children_ids').write({'parent_id': package.parent_id.id})
|
||||
self.unlink()
|
||||
return self.env['ir.actions.act_window'].for_xml_id('stock', 'action_package_view')
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -791,7 +791,7 @@ class Orderpoint(models.Model):
|
||||
('qty_multiple_check', 'CHECK( qty_multiple >= 0 )', 'Qty Multiple must be greater than or equal to zero.'),
|
||||
]
|
||||
|
||||
@api.constrains('product_id', 'product_uom')
|
||||
@api.constrains('product_id')
|
||||
def _check_product_uom(self):
|
||||
''' Check if the UoM has the same category as the product standard UoM '''
|
||||
if any(orderpoint.product_id.uom_id.category_id != orderpoint.product_uom.category_id for orderpoint in self):
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<span><strong>Customer Address:</strong></span>
|
||||
</div>
|
||||
<div t-if="o.partner_id" name="partner_header">
|
||||
<div t-field="o.partner_id"
|
||||
<div t-field="o.move_lines[0].partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": True}'/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -340,7 +340,7 @@ var FieldTextHtml = widget.extend({
|
||||
$("body").toggleClass("o_form_FieldTextHtml_fullscreen");
|
||||
var full = $("body").hasClass("o_form_FieldTextHtml_fullscreen");
|
||||
self.$iframe.parents().toggleClass('o_form_fullscreen_ancestor', full);
|
||||
self.resize();
|
||||
$(window).trigger("resize"); // induce a resize() call and let other backend elements know (the navbar extra items management relies on this)
|
||||
});
|
||||
|
||||
this.$body.on('click', '[data-action="cancel"]', function (event) {
|
||||
|
||||
@@ -13,6 +13,4 @@ Yenthe Van Ginneken yenthe.vanginneken@vanroey.be https://github.com/Yenthe666
|
||||
List of contributors:
|
||||
|
||||
Yenthe Van Ginneken yenthe.vanginneken@vanroey.be https://github.com/Yenthe666
|
||||
Maarten Wijnants maarten.wijnants@vanroey.be https://github.com/weilant
|
||||
Vincent Adriaensen vincent.adriaensen@vanroey.be https://github.com/vincentadriaensen
|
||||
Pieter Paulussen pieter.paulussen@vanroey.be https://github.com/PieterPaulussen
|
||||
|
||||
@@ -12,4 +12,5 @@ Aleš Ferlan alefer89@protonmail.com
|
||||
|
||||
List of contributors:
|
||||
|
||||
Aleš Ferlan alefer89@gmail.com https://github.com/Alko89
|
||||
Aleš Ferlan alefer89@protonmail.com
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Cuba, 2016-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,
|
||||
|
||||
Sergio Valdés sergiov@merchise.org https://github.com/Sergio2409
|
||||
@@ -271,7 +271,7 @@ actual arch.
|
||||
self.raise_view_error(message, self.id)
|
||||
return True
|
||||
|
||||
@api.constrains('arch', 'arch_base')
|
||||
@api.constrains('arch_db')
|
||||
def _check_xml(self):
|
||||
# Sanity checks: the view should not break anything upon rendering!
|
||||
# Any exception raised below will cause a transaction rollback.
|
||||
|
||||
@@ -130,6 +130,26 @@ class TestFields(common.TransactionCase):
|
||||
})
|
||||
check_stored(discussion3)
|
||||
|
||||
def test_11_computed_access(self):
|
||||
""" test computed fields with access right errors """
|
||||
User = self.env['res.users']
|
||||
user1 = User.create({'name': 'Aaaah', 'login': 'a'})
|
||||
user2 = User.create({'name': 'Boooh', 'login': 'b'})
|
||||
user3 = User.create({'name': 'Crrrr', 'login': 'c'})
|
||||
# add a rule to not give access to user2
|
||||
self.env['ir.rule'].create({
|
||||
'model_id': self.env['ir.model'].search([('model', '=', 'res.users')]).id,
|
||||
'domain_force': "[('id', '!=', %d)]" % user2.id,
|
||||
})
|
||||
# group users as a recordset, and read them as user demo
|
||||
users = (user1 + user2 + user3).sudo(self.env.ref('base.user_demo'))
|
||||
user1, user2, user3 = users
|
||||
# regression test: a bug invalidated the field's value from cache
|
||||
user1.company_type
|
||||
with self.assertRaises(AccessError):
|
||||
user2.company_type
|
||||
user3.company_type
|
||||
|
||||
def test_12_recursive(self):
|
||||
""" test recursively dependent fields """
|
||||
Category = self.env['test_new_api.category']
|
||||
|
||||
+6
-6
@@ -922,15 +922,15 @@ class Field(object):
|
||||
for field in fields:
|
||||
for record in records:
|
||||
record._cache[field] = field.convert_to_cache(False, record, validate=False)
|
||||
with records.env.protecting(fields, records):
|
||||
if isinstance(self.compute, basestring):
|
||||
getattr(records, self.compute)()
|
||||
else:
|
||||
self.compute(records)
|
||||
if isinstance(self.compute, basestring):
|
||||
getattr(records, self.compute)()
|
||||
else:
|
||||
self.compute(records)
|
||||
|
||||
def compute_value(self, records):
|
||||
""" Invoke the compute method on ``records``; the results are in cache. """
|
||||
with records.env.do_in_draft():
|
||||
fields = records._field_computed[self]
|
||||
with records.env.do_in_draft(), records.env.protecting(fields, records):
|
||||
try:
|
||||
self._compute_value(records)
|
||||
except (AccessError, MissingError):
|
||||
|
||||
+5
-2
@@ -664,8 +664,11 @@ class BaseModel(object):
|
||||
cls = type(self)
|
||||
methods = []
|
||||
for attr, func in getmembers(cls, is_constraint):
|
||||
if not all(name in cls._fields for name in func._constrains):
|
||||
_logger.warning("@constrains%r parameters must be field names", func._constrains)
|
||||
for name in func._constrains:
|
||||
if name not in cls._fields:
|
||||
_logger.warning("method %s.%s: @constrains parameter %r is not a field name", cls._name, attr, name)
|
||||
if not cls._fields[name].store:
|
||||
_logger.warning("method %s.%s: @constrains parameter %r is not stored", cls._name, attr, name)
|
||||
methods.append(func)
|
||||
|
||||
# optimization: memoize result on cls, it will not be recomputed
|
||||
|
||||
Reference in New Issue
Block a user