summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/account/models/account_move.py2
-rw-r--r--addons/account/views/account_payment_view.xml3
-rw-r--r--addons/hw_escpos/escpos/escpos.py25
-rw-r--r--addons/l10n_be_hr_payroll_fleet/__manifest__.py1
-rw-r--r--addons/l10n_be_hr_payroll_fleet/security/security.xml7
-rw-r--r--addons/l10n_mx/data/account_tag_data.xml22
-rw-r--r--addons/mail/models/mail_activity.py2
-rw-r--r--addons/mail/wizard/mail_compose_message.py5
-rw-r--r--addons/point_of_sale/static/src/js/gui.js5
-rw-r--r--addons/sale/models/sale.py2
-rw-r--r--addons/website/static/src/js/content/snippets.animation.js4
-rw-r--r--addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml8
-rw-r--r--addons/website_customer/views/website_customer_templates.xml9
-rw-r--r--doc/cla/corporate/ecoservice.md21
-rw-r--r--doc/cla/corporate/savoirfairelinux.md24
-rw-r--r--doc/cla/individual/gjanssens.md11
-rw-r--r--odoo/addons/base/models/ir_mail_server.py12
-rw-r--r--odoo/addons/base/models/res_users.py8
-rw-r--r--odoo/addons/test_convert/__init__.py1
-rw-r--r--odoo/addons/test_convert/__manifest__.py1
-rw-r--r--odoo/addons/test_convert/ir.model.access.csv2
-rw-r--r--odoo/addons/test_convert/models.py16
-rw-r--r--odoo/addons/test_convert/tests/test_convert.py21
-rw-r--r--odoo/tools/convert.py7
24 files changed, 170 insertions, 49 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index 6d11d14aa8b..825cbb37025 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -531,7 +531,7 @@ class AccountMoveLine(models.Model):
else:
date = partial_line.credit_move_id.date if partial_line.debit_move_id == line else partial_line.debit_move_id.date
rate = line.currency_id.with_context(date=date).rate
- amount_residual_currency += sign_partial_line * line.currency_id.round(partial_line.amount * rate)
+ amount_residual_currency += sign_partial_line * partial_line.amount * rate
#computing the `reconciled` field.
reconciled = False
diff --git a/addons/account/views/account_payment_view.xml b/addons/account/views/account_payment_view.xml
index 3387473a9e4..07230902ee8 100644
--- a/addons/account/views/account_payment_view.xml
+++ b/addons/account/views/account_payment_view.xml
@@ -106,7 +106,8 @@
<filter string="Payment Method" name="paymentmethod" domain="[]" context="{'group_by': 'payment_method_id'}"/>
<filter string="State" name="state" domain="[]" context="{'group_by': 'state'}"/>
<filter string="Currency" name="currency" domain="[]" context="{'group_by': 'currency_id'}" groups="base.group_multi_currency"/>
- <filter string="Company" name="company" domain="[]" context="{'group_by': 'company_id'}" groups="base.group_multi_company"/>
+ <!-- company_id is not stored (cdca5d4751a979f6b694f02d88160843f81a77f5). But we can't break structure-->
+ <filter string="Company" name="company" domain="[]" context="{'group_by': 'company_id'}" groups="base.group_multi_company" invisible="1" />
</search>
</field>
</record>
diff --git a/addons/hw_escpos/escpos/escpos.py b/addons/hw_escpos/escpos/escpos.py
index 0369aa2a0a4..3105b38850f 100644
--- a/addons/hw_escpos/escpos/escpos.py
+++ b/addons/hw_escpos/escpos/escpos.py
@@ -894,14 +894,23 @@ class Escpos:
self._raw(PAPER_FULL_CUT)
- def cashdraw(self, pin):
- """ Send pulse to kick the cash drawer """
- if pin == 2:
- self._raw(CD_KICK_2)
- elif pin == 5:
- self._raw(CD_KICK_5)
- else:
- raise CashDrawerError()
+ def cashdraw(self, pin, tries=5):
+ """ Send pulse to kick the cash drawer
+
+ With some printers the drawer will not open after one pulse, for this reason we will check
+ the drawer status up to 'tries' times and send a new pulse if the drawer is still closed. If the
+ drawer status is open, we will stop sending pulses.
+ """
+ for i in range(tries):
+ if pin == 2:
+ self._raw(CD_KICK_2)
+ elif pin == 5:
+ self._raw(CD_KICK_5)
+ else:
+ raise CashDrawerError()
+
+ if i != tries - 1 and not self.get_printer_status()['printer']['drawer_pin_high']:
+ break
def hw(self, hw):
diff --git a/addons/l10n_be_hr_payroll_fleet/__manifest__.py b/addons/l10n_be_hr_payroll_fleet/__manifest__.py
index d31865d69b5..3f840a44b74 100644
--- a/addons/l10n_be_hr_payroll_fleet/__manifest__.py
+++ b/addons/l10n_be_hr_payroll_fleet/__manifest__.py
@@ -11,6 +11,7 @@
'views/fleet_views.xml',
'views/res_config_settings_views.xml',
'views/hr_contract_views.xml',
+ 'security/security.xml',
],
'auto_install': True,
}
diff --git a/addons/l10n_be_hr_payroll_fleet/security/security.xml b/addons/l10n_be_hr_payroll_fleet/security/security.xml
new file mode 100644
index 00000000000..3fc21715a4c
--- /dev/null
+++ b/addons/l10n_be_hr_payroll_fleet/security/security.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <!-- Note for later versions, the group Employee Manager should become contract manager -->
+ <record id="hr.group_hr_manager" model="res.groups">
+ <field name="implied_ids" eval="[(4, ref('fleet.fleet_group_manager'))]"/>
+ </record>
+</odoo>
diff --git a/addons/l10n_mx/data/account_tag_data.xml b/addons/l10n_mx/data/account_tag_data.xml
index 244c9b65ff3..1e8b23dacda 100644
--- a/addons/l10n_mx/data/account_tag_data.xml
+++ b/addons/l10n_mx/data/account_tag_data.xml
@@ -479,25 +479,25 @@
<field name='name'>119.01 IVA pendiente de pago</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_119_02' model='account.account.tag'>
<field name='name'>119.02 IVA de importación pendiente de pago</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_119_03' model='account.account.tag'>
<field name='name'>119.03 IEPS pendiente de pago</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_119_04' model='account.account.tag'>
<field name='name'>119.04 IEPS pendiente de pago en importación</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_120_01' model='account.account.tag'>
<field name='name'>120.01 Anticipo a proveedores nacional</field>
@@ -917,7 +917,7 @@
<field name='name'>180.01 Crédito mercantil</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_181_01' model='account.account.tag'>
<field name='name'>181.01 Gastos de instalación</field>
@@ -2423,7 +2423,7 @@
<field name='name'>503 Devoluciones, descuentos o bonificaciones sobre compras</field>
<field name='color'>1</field>
<field name='applicability'>accounts</field>
- <field name='nature'>D</field>
+ <field name='nature'>A</field>
</record>
<record id='account_tag_503_01' model='account.account.tag'>
<field name='name'>503.01 Devoluciones, descuentos o bonificaciones sobre compras</field>
@@ -2585,13 +2585,13 @@
<field name='name'>505.01 Costo por venta de activo fijo</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_505_02' model='account.account.tag'>
<field name='name'>505.02 Costo por baja de activo fijo</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_601_01' model='account.account.tag'>
<field name='name'>601.01 Sueldos y salarios</field>
@@ -4781,7 +4781,7 @@
<field name='name'>607.01 Participación de los trabajadores en las utilidades</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_608_01' model='account.account.tag'>
<field name='name'>608.01 Participación en resultados de subsidiarias</field>
@@ -4799,7 +4799,7 @@
<field name='name'>610.01 Participación de los trabajadores en las utilidades diferida</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_611_01' model='account.account.tag'>
<field name='name'>611.01 Impuesto Sobre la renta</field>
@@ -4817,7 +4817,7 @@
<field name='name'>612.01 Gastos no deducibles para CUFIN</field>
<field name='color'>4</field>
<field name='applicability'>accounts</field>
- <field name='nature'>A</field>
+ <field name='nature'>D</field>
</record>
<record id='account_tag_613_01' model='account.account.tag'>
<field name='name'>613.01 Depreciación de edificios</field>
diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py
index 982d67b21c7..c9957bfc1a2 100644
--- a/addons/mail/models/mail_activity.py
+++ b/addons/mail/models/mail_activity.py
@@ -146,7 +146,7 @@ class MailActivity(models.Model):
('today', 'Today'),
('planned', 'Planned')], 'State',
compute='_compute_state')
- recommended_activity_type_id = fields.Many2one('mail.activity.type', string="Recommended Activity Type", readonly=True)
+ recommended_activity_type_id = fields.Many2one('mail.activity.type', string="Recommended Activity Type")
previous_activity_type_id = fields.Many2one('mail.activity.type', string='Previous Activity Type', readonly=True)
has_recommended_activities = fields.Boolean(
'Next activities available',
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index f92e23c6cc1..dcaf346e139 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -376,6 +376,7 @@ class MailComposer(models.TransientModel):
- normal mode: return rendered values
/!\ for x2many field, this onchange return command instead of ids
"""
+ attachment_ids = []
if template_id and composition_mode == 'mass_mail':
template = self.env['mail.template'].browse(template_id)
fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id']
@@ -401,7 +402,7 @@ class MailComposer(models.TransientModel):
'res_id': 0,
'type': 'binary', # override default_type from context, possibly meant for another model!
}
- values.setdefault('attachment_ids', list()).append(Attachment.create(data_attach).id)
+ attachment_ids.append(Attachment.create(data_attach).id)
else:
default_values = self.with_context(default_composition_mode=composition_mode, default_model=model, default_res_id=res_id).default_get(['composition_mode', 'model', 'res_id', 'parent_id', 'partner_ids', 'subject', 'body', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'])
values = dict((key, default_values[key]) for key in ['subject', 'body', 'partner_ids', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'] if key in default_values)
@@ -414,6 +415,8 @@ class MailComposer(models.TransientModel):
# this force the complete replacement of x2many field with
# command and is compatible with onchange api.v7
values = self._convert_to_write(values)
+ if attachment_ids:
+ values.update(attachment_ids=[(6, 0, attachment_ids)])
return {'value': values}
diff --git a/addons/point_of_sale/static/src/js/gui.js b/addons/point_of_sale/static/src/js/gui.js
index b5cff2f233a..0d8c67bc3d9 100644
--- a/addons/point_of_sale/static/src/js/gui.js
+++ b/addons/point_of_sale/static/src/js/gui.js
@@ -458,7 +458,7 @@ var Gui = core.Class.extend({
}
} else if (input === '-') {
if (options.firstinput) {
- newbuf = '-';
+ newbuf = '-0';
} else if ( newbuf[0] === '-' ) {
newbuf = newbuf.substring(1,newbuf.length);
} else {
@@ -473,6 +473,9 @@ var Gui = core.Class.extend({
newbuf += input;
}
}
+ if (newbuf === "-") {
+ newbuf = "";
+ }
// End of input buffer at 12 characters.
if (newbuf.length > buffer.length && newbuf.length > 12) {
diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py
index cc06fbddf41..e8954205d2e 100644
--- a/addons/sale/models/sale.py
+++ b/addons/sale/models/sale.py
@@ -1284,7 +1284,7 @@ class SaleOrderLine(models.Model):
result.setdefault(so_line_id, 0.0)
uom = product_uom_map.get(item['product_uom_id'][0])
if so_line.product_uom.category_id == uom.category_id:
- qty = uom._compute_quantity(item['unit_amount'], so_line.product_uom)
+ qty = uom._compute_quantity(item['unit_amount'], so_line.product_uom, rounding_method='HALF-UP')
else:
qty = item['unit_amount']
result[so_line_id] += qty
diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js
index c6a186c8a0c..0616ad311c1 100644
--- a/addons/website/static/src/js/content/snippets.animation.js
+++ b/addons/website/static/src/js/content/snippets.animation.js
@@ -930,6 +930,10 @@ registry.gallerySlider = Animation.extend({
destroy: function () {
this._super.apply(this, arguments);
+ if (!this.$indicator) {
+ return;
+ }
+
this.$prev.prependTo(this.$indicator);
this.$next.appendTo(this.$indicator);
this.$carousel.off('.gallery_slider');
diff --git a/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml b/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml
index e8863b571e3..b1e0e863959 100644
--- a/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml
+++ b/addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml
@@ -164,13 +164,9 @@
<t t-if="any([p.website_published for p in partner.implemented_partner_ids])">
<h3 id="references">References</h3>
<div t-foreach="partner.implemented_partner_ids" t-if="reference.website_published" t-as="reference" class="media mt-3">
- <a t-attf-href="/customers/#{slug(reference)}">
- <span t-field="reference.image_medium" t-options='{"widget": "image", "class": "d-block mr-3"}'/>
- </a>
+ <span t-field="reference.image_medium" t-options='{"widget": "image", "class": "d-block mr-3"}'/>
<div class="media-body" style="min-height: 64px;">
- <a t-attf-href="/customers/#{slug(reference)}">
- <span t-field="reference.self"/>
- </a>
+ <span t-field="reference.self"/>
<div t-field='reference.website_short_description'/>
</div>
</div>
diff --git a/addons/website_customer/views/website_customer_templates.xml b/addons/website_customer/views/website_customer_templates.xml
index da6e9aa8a33..9cd668d901d 100644
--- a/addons/website_customer/views/website_customer_templates.xml
+++ b/addons/website_customer/views/website_customer_templates.xml
@@ -234,4 +234,13 @@
</t>
</template>
+<template id="references_block_href" inherit_id="website_crm_partner_assign.references_block" name="Partner References Block">
+ <xpath expr="//div/span" position="replace">
+ <a t-attf-href="/customers/#{slug(reference)}">$0</a>
+ </xpath>
+ <xpath expr="//div[hasclass('media-body')]/span" position="replace">
+ <a t-attf-href="/customers/#{slug(reference)}">$0</a>
+ </xpath>
+</template>
+
</odoo>
diff --git a/doc/cla/corporate/ecoservice.md b/doc/cla/corporate/ecoservice.md
new file mode 100644
index 00000000000..b1b1cbe8ff0
--- /dev/null
+++ b/doc/cla/corporate/ecoservice.md
@@ -0,0 +1,21 @@
+Germany, 2019-05-14
+
+ecoservice GbR 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,
+
+Falk Neubert neubert@ecoservice.de https://github.com/FNeu75
+
+List of contributors:
+
+* Christian Engelhardt c.engelhardt@ecoservice.de https://github.com/c-engelhardt-ecoservice
+* Christian Schöttke c.schoettke@ecoservice.de https://github.com/cschoettke
+* Falk Neubert neubert@ecoservice.de https://github.com/FNeu75
+* Gülhan Celik g.celik@ecoservice.de https://github.com/guelhancelik
+* Jan Brodersen 4rmitxes@gmail.com https://github.com/Armitxes
+* Kamal Prajapati k.prajapati@ecoservice.de https://github.com/kamalprajapati
+* Marcel Much m.much@ecoservice.de https://github.com/mmuch
diff --git a/doc/cla/corporate/savoirfairelinux.md b/doc/cla/corporate/savoirfairelinux.md
index 913e317cb07..04f4563d4b7 100644
--- a/doc/cla/corporate/savoirfairelinux.md
+++ b/doc/cla/corporate/savoirfairelinux.md
@@ -12,17 +12,24 @@ João Alfredo Gama Batista joao.gama@savoirfairelinux.com https://github.com/joa
List of contributors:
-Agathe Mollé agathe.molle@savoirfairelinux.com https://github.com/Ehtaga
-Bruno Joliveau bruno.joliveau@savoirfairelinux.com https://github.com/bjoliveau
-David Dufresne david.dufresne@savoirfairelinux.com https://github.com/dufresnedavid
-Istvan SZALAÏ istvan.szalai@savoirfairelinux.com https://github.com/ventilooo
-João Alfredo Gama Batista joao.gama@savoirfairelinux.com https://github.com/joaoalf
-Julien Jezequel-Breard julien.jezequel-breard@savoirfairelinux.com https://github.com/jjbreard
-Quentin Lavallée-Bourdeau quentin.lavallee@savoirfairelinux.com https://github.com/qtiplb
+
Rim Ben Dhaou rim.bendhaou@savoirfairelinux.com https://github.com/rimbendhaou
-Yasmine El Mrini yasmine.elmrini@savoirfairelinux.com https://github.com/yasmineelmrini
Luis Garcia Ruiz luis.garcia@savoirfairelinux.com https://github.com/eilst
Dimitar Apostolov dimitar.apostolov@savoirfairelinux.com https://github.com/dapostolov-sfl
+Pierre Gault pierre.gault@savoirfairelinux.com https://github.com/gaultp
+Maroua Romdhane maroua.romdhane@savoirfairelinux.com https://github.com/mromdhane
+Jean-François Bolduc jean-francois.bolduc@savoirfairelinux.com https://github.com/fjdrake
+Blaise Frison blaise.frison@savoirfairelinux.com https://github.com/bfrison-sfl
+Larbi Gharib larbi.gharib@savoirfairelinux.com https://github.com/lgharib
+Jananjoy Rajkumar jananjoy.rajkumar@savoirfairelinux.com https://github.com/jananjoy
+Yasmine El Mrini yasmine.elmrini@savoirfairelinux.com https://github.com/yasmineelmrini (up to 2019-05-13)
+Agathe Mollé agathe.molle@savoirfairelinux.com https://github.com/Ehtaga (up to 2019-05-13)
+Bruno Joliveau bruno.joliveau@savoirfairelinux.com https://github.com/bjoliveau (up to 2019-05-13)
+David Dufresne david.dufresne@savoirfairelinux.com https://github.com/dufresnedavid (up to 2019-05-13)
+Istvan SZALAÏ istvan.szalai@savoirfairelinux.com https://github.com/ventilooo (up to 2019-05-13)
+João Alfredo Gama Batista joao.gama@savoirfairelinux.com https://github.com/joaoalf (up to 2019-05-13)
+Julien Jezequel-Breard julien.jezequel-breard@savoirfairelinux.com https://github.com/jjbreard (up to 2019-05-13)
+Quentin Lavallée-Bourdeau quentin.lavallee@savoirfairelinux.com https://github.com/qtiplb (up to 2019-05-13)
Jérome Boisvert-Chouinard jerome.boisvertchouinard@savoirfairelinux.com https://github.com/jbchouinard (up to 2017-10-17)
Julie Moussu julie.mousse@savoirfairelinux.com https://github.com/JulieSFL (up to 2017-10-17)
Pierre Lamarche pierre.lamarche@savoirfairelinux.com https://github.com/plamarche (up to 2017-10-17)
@@ -34,6 +41,5 @@ Jordi Riera jordi.riera@savoirfairelinux.com https://github.com/foutoucour (up t
Julien Roux julien.roux@savoirfairelinux.com https://github.com/jrouxsfl (up to 2017-05-12)
Loïc Faure-Lacroix loic.lacroix@savoirfairelinux.com https://github.com/llacroix (up to 2017-05-12)
Maxime Chambreuil maxime.chambreuil@savoirfairelinux.com https://github.com/max3903 (up to 2017-05-12)
-Pierre Gault pierre.gault@savoirfairelinux.com https://github.com/gaultp (up to 2017-05-12)
Sandy Carter sandy.carter@savoirfairelinux.com https://github.com/bwrsandman (up to 2017-05-12)
Vincent Vinet vincent.vinet@savoirfairelinux.com https://github.com/veloutin (up to 2017-05-12)
diff --git a/doc/cla/individual/gjanssens.md b/doc/cla/individual/gjanssens.md
new file mode 100644
index 00000000000..d3cda29d978
--- /dev/null
+++ b/doc/cla/individual/gjanssens.md
@@ -0,0 +1,11 @@
+Belgium, 2019-05-09
+
+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,
+
+Geert Janssens geert@kobaltwit.be https://github.com/gjanssens
diff --git a/odoo/addons/base/models/ir_mail_server.py b/odoo/addons/base/models/ir_mail_server.py
index 285bc88822a..58eb2afe5a5 100644
--- a/odoo/addons/base/models/ir_mail_server.py
+++ b/odoo/addons/base/models/ir_mail_server.py
@@ -119,10 +119,18 @@ def encode_rfc2822_address_header(header_text):
# Header as a string, using an unlimited line length.", the old one
# was "A synonym for Header.encode()." so call encode() directly?
name = Header(pycompat.to_text(name)).encode()
- return formataddr((name, email))
+ # if the from does not follow the (name <addr>),* convention, we might
+ # try to encode meaningless strings as address, as getaddresses is naive
+ # note it would also fail on real addresses with non-ascii characters
+ try:
+ return formataddr((name, email))
+ except UnicodeEncodeError:
+ _logger.warning(_('Failed to encode the address %s\n'
+ 'from mail header:\n%s') % addr, header_text)
+ return ""
addresses = getaddresses([pycompat.to_native(ustr(header_text))])
- return COMMASPACE.join(encode_addr(a) for a in addresses)
+ return COMMASPACE.join(a for a in (encode_addr(addr) for addr in addresses) if a)
class IrMailServer(models.Model):
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py
index ea80fa7dbb2..69d923763d8 100644
--- a/odoo/addons/base/models/res_users.py
+++ b/odoo/addons/base/models/res_users.py
@@ -1113,9 +1113,9 @@ class UsersView(models.Model):
group_multi_company = self.env.ref('base.group_multi_company', False)
if group_multi_company and 'company_ids' in values:
if len(user.company_ids) <= 1 and user.id in group_multi_company.users.ids:
- group_multi_company.write({'users': [(3, user.id)]})
+ user.write({'groups_id': [(3, group_multi_company.id)]})
elif len(user.company_ids) > 1 and user.id not in group_multi_company.users.ids:
- group_multi_company.write({'users': [(4, user.id)]})
+ user.write({'groups_id': [(4, group_multi_company.id)]})
return user
@api.multi
@@ -1126,9 +1126,9 @@ class UsersView(models.Model):
if group_multi_company and 'company_ids' in values:
for user in self:
if len(user.company_ids) <= 1 and user.id in group_multi_company.users.ids:
- group_multi_company.write({'users': [(3, user.id)]})
+ user.write({'groups_id': [(3, group_multi_company.id)]})
elif len(user.company_ids) > 1 and user.id not in group_multi_company.users.ids:
- group_multi_company.write({'users': [(4, user.id)]})
+ user.write({'groups_id': [(4, group_multi_company.id)]})
return res
def _remove_reified_groups(self, values):
diff --git a/odoo/addons/test_convert/__init__.py b/odoo/addons/test_convert/__init__.py
index e69de29bb2d..0650744f6bc 100644
--- a/odoo/addons/test_convert/__init__.py
+++ b/odoo/addons/test_convert/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/odoo/addons/test_convert/__manifest__.py b/odoo/addons/test_convert/__manifest__.py
index af6cd1af6e4..a9c67447615 100644
--- a/odoo/addons/test_convert/__manifest__.py
+++ b/odoo/addons/test_convert/__manifest__.py
@@ -5,4 +5,5 @@
'name': 'test_convert',
'description': "Data for xml conversion tests",
'version': '0.0.1',
+ 'data': ['ir.model.access.csv'],
}
diff --git a/odoo/addons/test_convert/ir.model.access.csv b/odoo/addons/test_convert/ir.model.access.csv
new file mode 100644
index 00000000000..014e4d1c827
--- /dev/null
+++ b/odoo/addons/test_convert/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_test_convert_test_model,access_test_convert_test_model,model_test_convert_test_model,,1,1,1,1 \ No newline at end of file
diff --git a/odoo/addons/test_convert/models.py b/odoo/addons/test_convert/models.py
new file mode 100644
index 00000000000..0f059e56e86
--- /dev/null
+++ b/odoo/addons/test_convert/models.py
@@ -0,0 +1,16 @@
+from odoo import api, models
+
+class TestModel(models.Model):
+ _name = 'test_convert.test_model'
+
+ @api.model
+ def action_test_date(self, today_date):
+ return True
+
+ @api.model
+ def action_test_time(self, cur_time):
+ return True
+
+ @api.model
+ def action_test_timezone(self, timezone):
+ return True
diff --git a/odoo/addons/test_convert/tests/test_convert.py b/odoo/addons/test_convert/tests/test_convert.py
index e81526dd43c..1bb79619c21 100644
--- a/odoo/addons/test_convert/tests/test_convert.py
+++ b/odoo/addons/test_convert/tests/test_convert.py
@@ -4,8 +4,10 @@
import collections
import unittest
+from lxml import etree as ET
from lxml.builder import E
+import odoo
from odoo.tests import common
from odoo.tools.convert import _eval_xml
@@ -16,6 +18,25 @@ class TestEvalXML(common.TransactionCase):
def eval_xml(self, node, obj=None):
return _eval_xml(obj, node, self.env)
+ def test_function_eval(self):
+ def id_get(): pass
+ Obj = collections.namedtuple('Obj', ['module', 'idref', 'id_get'])
+ obj = Obj('test_convert', {}, id_get)
+
+ try:
+ test_datetime = ET.XML("<function name='action_test_date' model='test_convert.test_model' eval='[datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")]'/>")
+ self.eval_xml(node=test_datetime, obj=obj)
+ test_time = ET.XML("<function name='action_test_time' model='test_convert.test_model' eval='[time.strftime(\"%Y-%m-%d %H:%M:%S\")]'/>")
+ self.eval_xml(node=test_time, obj=obj)
+ test_timedelta = ET.XML("<function name='action_test_date' model='test_convert.test_model' eval='[(datetime.today()-timedelta(days=365)).strftime(\"%Y-%m-%d %H:%M:%S\")]'/>")
+ self.eval_xml(node=test_timedelta, obj=obj)
+ test_relativedelta = ET.XML("<function name='action_test_date' model='test_convert.test_model' eval='[(datetime.today()+relativedelta(months=3)).strftime(\"%Y-%m-%d %H:%M:%S\")]'/>")
+ self.eval_xml(node=test_relativedelta, obj=obj)
+ test_timezone = ET.XML("<function name='action_test_timezone' model='test_convert.test_model' eval='[pytz.timezone(\"Asia/Calcutta\")]'/>")
+ self.eval_xml(node=test_timezone, obj=obj)
+ except ValueError as e:
+ self.fail(e.message)
+
def test_char(self):
self.assertEqual(
self.eval_xml(Field("foo")),
diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py
index b98e586a62e..3c873597ae0 100644
--- a/odoo/tools/convert.py
+++ b/odoo/tools/convert.py
@@ -179,15 +179,16 @@ def _eval_xml(self, node, env):
elif node.tag == "function":
args = []
a_eval = node.get('eval')
+ model_str = node.get('model')
# FIXME: should probably be exclusive
if a_eval:
- self.idref['ref'] = self.id_get
- args = safe_eval(a_eval, self.idref)
+ idref2 = _get_idref(self, env, model_str, self.idref)
+ args = safe_eval(a_eval, idref2)
for n in node:
return_val = _eval_xml(self, n, env)
if return_val is not None:
args.append(return_val)
- model = env[node.get('model')]
+ model = env[model_str]
method = node.get('name')
# this one still depends on the old API
return odoo.api.call_kw(model, method, args, {})