Skip to content

Commit 04f191b

Browse files
committed
Merge remote-tracking branch 'odoo/14.0' into 14.0
2 parents b8075cd + a238c7f commit 04f191b

File tree

7 files changed

+135
-43
lines changed

7 files changed

+135
-43
lines changed

addons/sms/wizard/sms_composer.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,12 @@ def _action_send_sms_comment(self, records=None):
239239
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
240240

241241
messages = self.env['mail.message']
242+
all_bodies = self._prepare_body_values(records)
243+
242244
for record in records:
243-
messages |= record._message_sms(
244-
self.body, subtype_id=subtype_id,
245+
messages += record._message_sms(
246+
all_bodies[record.id],
247+
subtype_id=subtype_id,
245248
number_field=self.number_field_name,
246249
sms_numbers=self.sanitized_numbers.split(',') if self.sanitized_numbers else None)
247250
return messages

addons/test_mail_full/tests/test_sms_composer.py

+113-37
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,11 @@ def test_composer_numbers_no_model(self):
207207

208208

209209
class TestSMSComposerBatch(TestMailFullCommon):
210+
210211
@classmethod
211212
def setUpClass(cls):
212213
super(TestSMSComposerBatch, cls).setUpClass()
213-
cls._test_body = 'Zizisse an SMS.'
214+
cls._test_body = 'Hello ${object.name} zizisse an SMS.'
214215

215216
cls._create_records_for_batch('mail.test.sms', 3)
216217
cls.sms_template = cls._create_sms_template('mail.test.sms')
@@ -229,8 +230,12 @@ def test_composer_batch_active_domain(self):
229230
with self.mockSMSGateway():
230231
messages = composer._action_send_sms()
231232

232-
for record in self.records:
233-
self.assertSMSNotification([{'partner': r.customer_id} for r in self.records], 'Zizisse an SMS.', messages)
233+
for record, message in zip(self.records, messages):
234+
self.assertSMSNotification(
235+
[{'partner': record.customer_id}],
236+
'Hello %s zizisse an SMS.' % record.name,
237+
message
238+
)
234239

235240
def test_composer_batch_active_ids(self):
236241
with self.with_user('employee'):
@@ -245,8 +250,12 @@ def test_composer_batch_active_ids(self):
245250
with self.mockSMSGateway():
246251
messages = composer._action_send_sms()
247252

248-
for record in self.records:
249-
self.assertSMSNotification([{'partner': r.customer_id} for r in self.records], 'Zizisse an SMS.', messages)
253+
for record, message in zip(self.records, messages):
254+
self.assertSMSNotification(
255+
[{'partner': record.customer_id}],
256+
'Hello %s zizisse an SMS.' % record.name,
257+
message
258+
)
250259

251260
def test_composer_batch_domain(self):
252261
with self.with_user('employee'):
@@ -262,8 +271,12 @@ def test_composer_batch_domain(self):
262271
with self.mockSMSGateway():
263272
messages = composer._action_send_sms()
264273

265-
for record in self.records:
266-
self.assertSMSNotification([{'partner': r.customer_id} for r in self.records], 'Zizisse an SMS.', messages)
274+
for record, message in zip(self.records, messages):
275+
self.assertSMSNotification(
276+
[{'partner': record.customer_id}],
277+
'Hello %s zizisse an SMS.' % record.name,
278+
message
279+
)
267280

268281
def test_composer_batch_res_ids(self):
269282
with self.with_user('employee'):
@@ -278,18 +291,22 @@ def test_composer_batch_res_ids(self):
278291
with self.mockSMSGateway():
279292
messages = composer._action_send_sms()
280293

281-
for record in self.records:
282-
self.assertSMSNotification([{'partner': r.customer_id} for r in self.records], 'Zizisse an SMS.', messages)
294+
for record, message in zip(self.records, messages):
295+
self.assertSMSNotification(
296+
[{'partner': record.customer_id}],
297+
'Hello %s zizisse an SMS.' % record.name,
298+
message
299+
)
283300

284301

285302
class TestSMSComposerMass(TestMailFullCommon):
286303

287304
@classmethod
288305
def setUpClass(cls):
289306
super(TestSMSComposerMass, cls).setUpClass()
290-
cls._test_body = 'Zizisse an SMS.'
307+
cls._test_body = 'Hello ${object.name} zizisse an SMS.'
291308

292-
cls._create_records_for_batch('mail.test.sms', 3)
309+
cls._create_records_for_batch('mail.test.sms', 10)
293310
cls.sms_template = cls._create_sms_template('mail.test.sms')
294311

295312
def test_composer_mass_active_domain(self):
@@ -308,7 +325,10 @@ def test_composer_mass_active_domain(self):
308325
composer.action_send_sms()
309326

310327
for record in self.records:
311-
self.assertSMSOutgoing(record.customer_id, None, content=self._test_body)
328+
self.assertSMSOutgoing(
329+
record.customer_id, None,
330+
content='Hello %s zizisse an SMS.' % record.name
331+
)
312332

313333
def test_composer_mass_active_domain_w_template(self):
314334
with self.with_user('employee'):
@@ -326,7 +346,10 @@ def test_composer_mass_active_domain_w_template(self):
326346
composer.action_send_sms()
327347

328348
for record in self.records:
329-
self.assertSMSOutgoing(record.customer_id, None, content='Dear %s this is an SMS.' % record.display_name)
349+
self.assertSMSOutgoing(
350+
record.customer_id, None,
351+
content='Dear %s this is an SMS.' % record.display_name
352+
)
330353

331354
def test_composer_mass_active_ids(self):
332355
with self.with_user('employee'):
@@ -342,8 +365,11 @@ def test_composer_mass_active_ids(self):
342365
with self.mockSMSGateway():
343366
composer.action_send_sms()
344367

345-
for partner in self.partners:
346-
self.assertSMSOutgoing(partner, None, content=self._test_body)
368+
for partner, record in zip(self.partners, self.records):
369+
self.assertSMSOutgoing(
370+
partner, None,
371+
content='Hello %s zizisse an SMS.' % record.name
372+
)
347373

348374
def test_composer_mass_active_ids_w_blacklist(self):
349375
self.env['phone.blacklist'].create([{
@@ -365,10 +391,17 @@ def test_composer_mass_active_ids_w_blacklist(self):
365391
with self.mockSMSGateway():
366392
composer.action_send_sms()
367393

368-
for partner in self.partners[5:]:
369-
self.assertSMSOutgoing(partner, partner.phone_sanitized, content=self._test_body)
370-
for partner in self.partners[:5]:
371-
self.assertSMSCanceled(partner, partner.phone_sanitized, error_code='sms_blacklist', content=self._test_body)
394+
for partner, record in zip(self.partners[5:], self.records[5:]):
395+
self.assertSMSOutgoing(
396+
partner, partner.phone_sanitized,
397+
content='Hello %s zizisse an SMS.' % record.name
398+
)
399+
for partner, record in zip(self.partners[:5], self.records[:5]):
400+
self.assertSMSCanceled(
401+
partner, partner.phone_sanitized,
402+
error_code='sms_blacklist',
403+
content='Hello %s zizisse an SMS.' % record.name
404+
)
372405

373406
def test_composer_mass_active_ids_wo_blacklist(self):
374407
self.env['phone.blacklist'].create([{
@@ -390,17 +423,22 @@ def test_composer_mass_active_ids_wo_blacklist(self):
390423
with self.mockSMSGateway():
391424
composer.action_send_sms()
392425

393-
for partner in self.partners:
394-
self.assertSMSOutgoing(partner, partner.phone_sanitized, content=self._test_body)
426+
for partner, record in zip(self.partners, self.records):
427+
self.assertSMSOutgoing(
428+
partner, partner.phone_sanitized,
429+
content='Hello %s zizisse an SMS.' % record.name
430+
)
395431

396432
def test_composer_mass_active_ids_w_blacklist_and_done(self):
433+
""" Create some duplicates + blacklist. record[5] will have duplicated
434+
number on 6 and 7. """
397435
self.env['phone.blacklist'].create([{
398436
'number': p.phone_sanitized,
399437
'active': True,
400438
} for p in self.partners[:5]])
401-
for p in self.partners[8:]:
402-
p.mobile = self.partners[8].mobile
403-
self.assertEqual(p.phone_sanitized, self.partners[8].phone_sanitized)
439+
for p in self.partners[5:8]:
440+
p.mobile = self.partners[5].mobile
441+
self.assertEqual(p.phone_sanitized, self.partners[5].phone_sanitized)
404442

405443
with self.with_user('employee'):
406444
composer = self.env['sms.composer'].with_context(
@@ -416,12 +454,29 @@ def test_composer_mass_active_ids_w_blacklist_and_done(self):
416454
with self.mockSMSGateway():
417455
composer.action_send_sms()
418456

419-
for partner in self.partners[8:]:
420-
self.assertSMSOutgoing(partner, partner.phone_sanitized, content=self._test_body)
421-
for partner in self.partners[5:8]:
422-
self.assertSMSCanceled(partner, partner.phone_sanitized, error_code='sms_duplicate', content=self._test_body)
423-
for partner in self.partners[:5]:
424-
self.assertSMSCanceled(partner, partner.phone_sanitized, error_code='sms_blacklist', content=self._test_body)
457+
self.assertSMSOutgoing(
458+
self.partners[5], self.partners[5].phone_sanitized,
459+
content='Hello %s zizisse an SMS.' % self.records[5].name
460+
)
461+
for partner, record in zip(self.partners[8:], self.records[8:]):
462+
self.assertSMSOutgoing(
463+
partner, partner.phone_sanitized,
464+
content='Hello %s zizisse an SMS.' % record.name
465+
)
466+
# duplicates
467+
for partner, record in zip(self.partners[6:8], self.records[6:8]):
468+
self.assertSMSCanceled(
469+
partner, partner.phone_sanitized,
470+
error_code='sms_duplicate',
471+
content='Hello %s zizisse an SMS.' % record.name
472+
)
473+
# blacklist
474+
for partner, record in zip(self.partners[:5], self.records[:5]):
475+
self.assertSMSCanceled(
476+
partner, partner.phone_sanitized,
477+
error_code='sms_blacklist',
478+
content='Hello %s zizisse an SMS.' % record.name
479+
)
425480

426481
def test_composer_mass_active_ids_w_template(self):
427482
with self.with_user('employee'):
@@ -438,7 +493,10 @@ def test_composer_mass_active_ids_w_template(self):
438493
composer.action_send_sms()
439494

440495
for record in self.records:
441-
self.assertSMSOutgoing(record.customer_id, None, content='Dear %s this is an SMS.' % record.display_name)
496+
self.assertSMSOutgoing(
497+
record.customer_id, None,
498+
content='Dear %s this is an SMS.' % record.display_name
499+
)
442500

443501
def test_composer_mass_active_ids_w_template_and_lang(self):
444502
self.env['res.lang']._activate_lang('fr_FR')
@@ -472,9 +530,15 @@ def test_composer_mass_active_ids_w_template_and_lang(self):
472530

473531
for record in self.records:
474532
if record.customer_id == self.partners[2]:
475-
self.assertSMSOutgoing(record.customer_id, None, content='Cher·e· %s ceci est un SMS.' % record.display_name)
533+
self.assertSMSOutgoing(
534+
record.customer_id, None,
535+
content='Cher·e· %s ceci est un SMS.' % record.display_name
536+
)
476537
else:
477-
self.assertSMSOutgoing(record.customer_id, None, content='Dear %s this is an SMS.' % record.display_name)
538+
self.assertSMSOutgoing(
539+
record.customer_id, None,
540+
content='Dear %s this is an SMS.' % record.display_name
541+
)
478542

479543
def test_composer_mass_active_ids_w_template_and_log(self):
480544
with self.with_user('employee'):
@@ -491,7 +555,10 @@ def test_composer_mass_active_ids_w_template_and_log(self):
491555
composer.action_send_sms()
492556

493557
for record in self.records:
494-
self.assertSMSOutgoing(record.customer_id, None, content='Dear %s this is an SMS.' % record.display_name)
558+
self.assertSMSOutgoing(
559+
record.customer_id, None,
560+
content='Dear %s this is an SMS.' % record.display_name
561+
)
495562
self.assertSMSLogged(record, 'Dear %s this is an SMS.' % record.display_name)
496563

497564
def test_composer_template_context_action(self):
@@ -541,7 +608,10 @@ def test_composer_template_context_action(self):
541608
messages = composer._action_send_sms()
542609

543610
number = self.partners[2].phone_get_sanitized_number()
544-
self.assertSMSNotification([{'partner': test_record_2.customer_id, 'number': number}], "Hello %s ceci est en français." % test_record_2.display_name, messages)
611+
self.assertSMSNotification(
612+
[{'partner': test_record_2.customer_id, 'number': number}],
613+
"Hello %s ceci est en français." % test_record_2.display_name, messages
614+
)
545615

546616
# Composer creation with context from a template context action (simulate) - mass (multiple recipient)
547617
with self.with_user('employee'):
@@ -563,5 +633,11 @@ def test_composer_template_context_action(self):
563633
with self.mockSMSGateway():
564634
composer.action_send_sms()
565635

566-
self.assertSMSOutgoing(test_record_1.customer_id, None, content='Dear %s this is an SMS.' % test_record_1.display_name)
567-
self.assertSMSOutgoing(test_record_2.customer_id, None, content="Hello %s ceci est en français." % test_record_2.display_name)
636+
self.assertSMSOutgoing(
637+
test_record_1.customer_id, None,
638+
content='Dear %s this is an SMS.' % test_record_1.display_name
639+
)
640+
self.assertSMSOutgoing(
641+
test_record_2.customer_id, None,
642+
content="Hello %s ceci est en français." % test_record_2.display_name
643+
)

addons/web/static/src/js/fields/field_utils.js

+3
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,9 @@ function parseMonetary(value, field, options) {
628628
}
629629
currency = session.get_currency(currency_id);
630630
}
631+
if (!currency) {
632+
return parseFloat(value);
633+
}
631634
if (!value.includes(currency.symbol)) {
632635
throw new Error(_.str.sprintf(core._t("'%s' is not a correct monetary field"), value));
633636
}

addons/web/static/tests/fields/field_utils_tests.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ QUnit.test('parse integer', function(assert) {
261261
});
262262

263263
QUnit.test('parse monetary', function(assert) {
264-
assert.expect(13);
264+
assert.expect(15);
265265
var originalCurrencies = session.currencies;
266266
const originalParameters = _.clone(core._t.database.parameters);
267267
session.currencies = {
@@ -293,11 +293,13 @@ QUnit.test('parse monetary', function(assert) {
293293
const nbsp = '\u00a0';
294294
_.extend(core._t.database.parameters, {
295295
grouping: [3, 0],
296-
decimal_point: ',',
296+
decimal_point: '.',
297297
thousands_sep: nbsp,
298298
});
299299
assert.strictEqual(fieldUtils.parse.monetary(`1${nbsp}000.00${nbsp}€`, {}, {currency_id: 1}), 1000);
300300
assert.strictEqual(fieldUtils.parse.monetary(`$${nbsp}1${nbsp}000.00`, {}, {currency_id: 3}), 1000);
301+
assert.strictEqual(fieldUtils.parse.monetary(`1${nbsp}000.00`), 1000);
302+
assert.strictEqual(fieldUtils.parse.monetary(`1${nbsp}000${nbsp}000.00`), 1000000);
301303

302304
session.currencies = originalCurrencies;
303305
core._t.database.parameters = originalParameters;

doc/cla/corporate/vauxoo.md

+1
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,4 @@ Luigys Toro [email protected] https://github.com/desdelinux
5656
Francisco J. Luna [email protected] https://github.com/frahikLV
5757
Andrea Arce [email protected] https://github.com/andreaarce
5858
Francisco Alejandro González Luna [email protected] https://github.com/TheAlekLuna
59+
Alejandro Garza [email protected] https://github.com/agarzaarvizu

odoo/addons/base/models/res_partner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ def _get_name_search_order_by_fields(self):
759759

760760
@api.model
761761
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
762-
self = self.with_user(name_get_uid or self.env.uid)
762+
self = self.with_user(name_get_uid) if name_get_uid else self
763763
# as the implementation is in SQL, we force the recompute of fields if necessary
764764
self.recompute(['display_name'])
765765
self.flush()

odoo/addons/base/tests/test_res_partner.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from odoo.tests import Form
55
from odoo.tests.common import TransactionCase
6-
from odoo.exceptions import UserError
6+
from odoo.exceptions import AccessError, UserError
77

88

99
class TestPartner(TransactionCase):
@@ -20,6 +20,13 @@ def test_name_search(self):
2020
ns_res = self.env['res.partner'].name_search('Vlad', args=[('user_ids.email', 'ilike', 'vlad')])
2121
self.assertEqual(set(i[0] for i in ns_res), set(test_user.partner_id.ids))
2222

23+
# Check a partner may be searched when current user has no access but sudo is used
24+
public_user = self.env.ref('base.public_user')
25+
with self.assertRaises(AccessError):
26+
test_partner.with_user(public_user).check_access_rule('read')
27+
ns_res = self.env['res.partner'].with_user(public_user).sudo().name_search('Vlad', args=[('user_ids.email', 'ilike', 'vlad')])
28+
self.assertEqual(set(i[0] for i in ns_res), set(test_user.partner_id.ids))
29+
2330
def test_name_get(self):
2431
""" Check name_get on partner, especially with different context
2532
Check name_get correctly return name with context. """

0 commit comments

Comments
 (0)