diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-05-16 18:19:49 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-05-16 18:19:49 +0200 |
| commit | 7b9aa21576798d7f8ffe2b2f73e403e276c4b39a (patch) | |
| tree | 68d438edff5535b124bac4d6f4e308341eaee122 | |
| parent | 3b3f85670f40231768a409e3aebb636ad6871b56 (diff) | |
| parent | cecb1ec77d56fefdab53f3ef0bdda9a9c51c14be (diff) | |
[MERGE] forward port branch saas-15 up to cecb1ec77d5
| -rw-r--r-- | addons/account/models/account_move.py | 2 | ||||
| -rw-r--r-- | addons/hw_escpos/escpos/escpos.py | 25 | ||||
| -rw-r--r-- | addons/mail/models/mail_mail.py | 15 | ||||
| -rw-r--r-- | addons/point_of_sale/static/src/js/gui.js | 5 | ||||
| -rw-r--r-- | addons/sale/models/sale.py | 2 | ||||
| -rw-r--r-- | addons/website_crm_partner_assign/views/website_crm_partner_assign_templates.xml | 12 | ||||
| -rw-r--r-- | addons/website_customer/views/website_customer_templates.xml | 9 | ||||
| -rw-r--r-- | odoo/addons/base/res/res_users.py | 8 | ||||
| -rw-r--r-- | odoo/addons/test_convert/__init__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/test_convert/__manifest__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/test_convert/ir.model.access.csv | 2 | ||||
| -rw-r--r-- | odoo/addons/test_convert/models.py | 16 | ||||
| -rw-r--r-- | odoo/addons/test_convert/tests/test_convert.py | 21 | ||||
| -rw-r--r-- | odoo/tools/convert.py | 7 |
14 files changed, 99 insertions, 27 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 08afcf0e071..3d3f85276a6 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -342,7 +342,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/hw_escpos/escpos/escpos.py b/addons/hw_escpos/escpos/escpos.py index 3573efb1d98..bc1c5e1842f 100644 --- a/addons/hw_escpos/escpos/escpos.py +++ b/addons/hw_escpos/escpos/escpos.py @@ -888,14 +888,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/mail/models/mail_mail.py b/addons/mail/models/mail_mail.py index 3027fc43edc..9fde6ebe773 100644 --- a/addons/mail/models/mail_mail.py +++ b/addons/mail/models/mail_mail.py @@ -153,6 +153,7 @@ class MailMail(models.Model): if notif_emails: notifications = self.env['mail.notification'].search([ ('mail_message_id', 'in', notif_emails.mapped('mail_message_id').ids), + ('res_partner_id', 'in', notif_emails.mapped('recipient_ids').ids), ('is_email', '=', True)]) if mail_sent: notifications.write({ @@ -320,6 +321,20 @@ class MailMail(models.Model): }) mail_sent = False + # Update notification in a transient exception state to avoid concurrent + # update in case an email bounces while sending all emails related to current + # mail record. + notifs = self.env['mail.notification'].search([ + ('is_email', '=', True), + ('mail_message_id', 'in', mail.mapped('mail_message_id').ids), + ('res_partner_id', 'in', mail.mapped('recipient_ids').ids), + ('email_status', 'not in', ('sent', 'canceled')) + ]) + if notifs: + notifs.sudo().write({ + 'email_status': 'exception', + }) + # build an RFC2822 email.message.Message object and send it without queuing res = None for email in email_list: 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 4b92f183fd6..9fca947f6f1 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -1269,7 +1269,7 @@ class SaleOrderLine(models.Model): value_to_write.setdefault(so_line, 0.0) uom = self.env['product.uom'].browse(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'] value_to_write[so_line] += qty 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 96346a3814d..bdc28c2fa25 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 @@ -170,18 +170,12 @@ <template id="references_block" name="Partner References Block"> <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-as="reference" class="media"> - <t t-if="reference.website_published"> - <a class="pull-left" t-attf-href="/customers/#{slug(reference)}"> - <span t-field="reference.image_small" t-options='{"widget": "image", "class": "center-block"}'/> - </a> + <div t-foreach="partner.implemented_partner_ids" t-if="reference.website_published" t-as="reference" class="media"> + <span t-field="reference.image_small" t-options='{"widget": "image", "class": "center-block pull-left"}'/> <div class="media-body" style="min-height: 64px;"> - <a class="media-heading" t-attf-href="/customers/#{slug(reference)}"> - <span t-field="reference.self"/> - </a> + <span class="media-heading" t-field="reference.self"/> <div t-field='reference.website_short_description'/> </div> - </t> </div> </t> </template> diff --git a/addons/website_customer/views/website_customer_templates.xml b/addons/website_customer/views/website_customer_templates.xml index 5674f3d3440..ccd0732839d 100644 --- a/addons/website_customer/views/website_customer_templates.xml +++ b/addons/website_customer/views/website_customer_templates.xml @@ -239,4 +239,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 class="pull-left" t-attf-href="/customers/#{slug(reference)}">$0</a> + </xpath> + <xpath expr="//div[@class='media-body']/span" position="replace"> + <a class="media-heading" t-attf-href="/customers/#{slug(reference)}">$0</a> + </xpath> +</template> + </odoo> diff --git a/odoo/addons/base/res/res_users.py b/odoo/addons/base/res/res_users.py index 30eba4f3c0d..8032dc0e15c 100644 --- a/odoo/addons/base/res/res_users.py +++ b/odoo/addons/base/res/res_users.py @@ -875,9 +875,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 @@ -888,9 +888,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 97fb2be7330..222c847ba52 100644 --- a/odoo/tools/convert.py +++ b/odoo/tools/convert.py @@ -180,15 +180,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, {}) |
