diff --git a/addons/email_template/tests/test_mail.py b/addons/email_template/tests/test_mail.py index 62291d78dcb..ec7218ed647 100644 --- a/addons/email_template/tests/test_mail.py +++ b/addons/email_template/tests/test_mail.py @@ -237,8 +237,8 @@ class test_message_compose(TestMail): email_template.send_mail(cr, uid, email_template_id, self.group_pigs_id, force_send=True, context=context) sent_emails = self._build_email_kwargs_list email_to_lst = [ - ['b@b.b', 'c@c.c'], ['"Followers of Pigs" '], - ['"Followers of Pigs" '], ['"Followers of Pigs" ']] + ['b@b.b', 'c@c.c'], ['Followers of Pigs '], + ['Followers of Pigs '], ['Followers of Pigs ']] self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails') for email in sent_emails: self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients') diff --git a/addons/l10n_be_coda/wizard/account_coda_import.py b/addons/l10n_be_coda/wizard/account_coda_import.py index aa9bf49b5a1..284049f6a34 100644 --- a/addons/l10n_be_coda/wizard/account_coda_import.py +++ b/addons/l10n_be_coda/wizard/account_coda_import.py @@ -49,7 +49,7 @@ class account_coda_import(osv.osv_memory): return tmp_account_id _defaults = { - 'coda_fname': lambda *a: '', + 'coda_fname': 'coda.txt', 'temporary_account_id': _get_default_tmp_account, } diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index 1cc033e8926..57d801526b8 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -22,6 +22,7 @@ import base64 import logging import re +from email.utils import formataddr from urllib import urlencode from urlparse import urljoin @@ -210,10 +211,9 @@ class mail_mail(osv.Model): # 2. if 'partner' is specified, but no related document: Partner Name # 3; fallback on mail.email_to that we split to have an email addresses list if partner and mail.record_name: - sanitized_record_name = re.sub(r'[^\w+.]+', '-', mail.record_name) - email_to = [_('"Followers of %s" <%s>') % (sanitized_record_name, partner.email)] + email_to = [formataddr((_('Followers of %s') % mail.record_name, partner.email))] elif partner: - email_to = ['%s <%s>' % (partner.name, partner.email)] + email_to = [formataddr((partner.name, partner.email))] else: email_to = tools.email_split(mail.email_to) diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index 00fd00dda58..2a8529e6893 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -25,6 +25,7 @@ import re from openerp import tools from email.header import decode_header +from email.utils import formataddr from openerp import SUPERUSER_ID from openerp.osv import osv, orm, fields from openerp.tools import html_email_clean @@ -203,9 +204,9 @@ class mail_message(osv.Model): def _get_default_from(self, cr, uid, context=None): this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) if this.alias_name and this.alias_domain: - return '%s <%s@%s>' % (this.name, this.alias_name, this.alias_domain) + return formataddr((this.name, '%s@%s' % (this.alias_name, this.alias_domain))) elif this.email: - return '%s <%s>' % (this.name, this.email) + return formataddr((this.name, this.email)) raise osv.except_osv(_('Invalid Action!'), _("Unable to send email, please configure the sender's email address or alias.")) def _get_default_author(self, cr, uid, context=None): diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py index c7f1056c59a..7637c2920f1 100644 --- a/addons/mail/tests/test_mail_features.py +++ b/addons/mail/tests/test_mail_features.py @@ -468,7 +468,7 @@ class test_mail(TestMail): # Test: notifications emails: to a and b, c is email only, r is author # test_emailto = ['Administrator ', 'Bert Tartopoils '] - test_emailto = ['"Followers of -Pigs-" ', '"Followers of -Pigs-" '] + test_emailto = [u'"Followers of \\"Pigs\\" !\xf9 $%-" ', u'"Followers of \\"Pigs\\" !\xf9 $%-" '] self.assertEqual(len(sent_emails), 2, 'message_post: notification emails wrong number of send emails') self.assertEqual(set([m['email_to'][0] for m in sent_emails]), set(test_emailto), @@ -480,7 +480,7 @@ class test_mail(TestMail): 'message_post: notification email sent to more than one email address instead of a precise partner') self.assertIn(sent_email['email_to'][0], test_emailto, 'message_post: notification email email_to incorrect') - self.assertEqual(sent_email['reply_to'], '"Followers of -Pigs-" ', + self.assertEqual(sent_email['reply_to'], u'"Followers of \\"Pigs\\" !\xf9 $%-" ', 'message_post: notification email reply_to incorrect') self.assertEqual(_subject, sent_email['subject'], 'message_post: notification email subject incorrect') @@ -542,7 +542,7 @@ class test_mail(TestMail): # Test: emails send by server (to a, b, c, d) # test_emailto = [u'Administrator ', u'Bert Tartopoils ', u'Carine Poilvache ', u'D\xe9d\xe9 Grosbedon '] - test_emailto = [u'"Followers of Pigs" ', u'"Followers of Pigs" ', u'"Followers of Pigs" ', u'"Followers of Pigs" '] + test_emailto = [u'Followers of Pigs ', u'Followers of Pigs ', u'Followers of Pigs ', u'Followers of Pigs '] # self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect') for sent_email in sent_emails: self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon ', diff --git a/addons/procurement/schedulers.py b/addons/procurement/schedulers.py index d82fa94c132..60435f67cac 100644 --- a/addons/procurement/schedulers.py +++ b/addons/procurement/schedulers.py @@ -28,6 +28,7 @@ from openerp.osv import fields from openerp.tools.translate import _ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT from openerp import tools +from psycopg2 import OperationalError class procurement_order(osv.osv): _inherit = 'procurement.order' @@ -70,33 +71,45 @@ class procurement_order(osv.osv): cr.commit() company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id maxdate = (datetime.today() + relativedelta(days=company.schedule_range)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - offset = 0 + prev_ids = [] while True: - ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_order')], offset=offset, limit=500, order='priority, date_planned', context=context) + ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_order'), ('date_planned', '<', maxdate)], limit=500, order='priority, date_planned', context=context) for proc in procurement_obj.browse(cr, uid, ids, context=context): - if maxdate >= proc.date_planned: + try: self.signal_button_check(cr, uid, [proc.id]) - else: - offset += 1 - if use_new_cursor: - cr.commit() - if not ids: + if use_new_cursor: + cr.commit() + except OperationalError: + if use_new_cursor: + cr.rollback() + continue + else: + raise + if not ids or prev_ids == ids: break - offset = 0 + else: + prev_ids = ids ids = [] + prev_ids = [] while True: - report_ids = [] - ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset) + ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock'), ('date_planned', '<', maxdate)], limit=500) for proc in procurement_obj.browse(cr, uid, ids): - if maxdate >= proc.date_planned: + try: self.signal_button_check(cr, uid, [proc.id]) - report_ids.append(proc.id) - if use_new_cursor: - cr.commit() - offset += len(ids) - if not ids: break + if use_new_cursor: + cr.commit() + except OperationalError: + if use_new_cursor: + cr.rollback() + continue + else: + raise + if not ids or prev_ids == ids: + break + else: + prev_ids = ids if use_new_cursor: cr.commit() @@ -203,52 +216,66 @@ class procurement_order(osv.osv): orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') procurement_obj = self.pool.get('procurement.order') - offset = 0 ids = [1] + prev_ids = [] if automatic: self.create_automatic_op(cr, uid, context=context) - while ids: - ids = orderpoint_obj.search(cr, uid, [], offset=offset, limit=100) + orderpoint_ids = orderpoint_obj.search(cr, uid, []) + while orderpoint_ids: + ids = orderpoint_ids[:100] + del orderpoint_ids[:100] for op in orderpoint_obj.browse(cr, uid, ids, context=context): - prods = self._product_virtual_get(cr, uid, op) - if prods is None: - continue - if prods < op.product_min_qty: - qty = max(op.product_min_qty, op.product_max_qty)-prods - - reste = qty % op.qty_multiple - if reste > 0: - qty += op.qty_multiple - reste - - if qty <= 0: + try: + prods = self._product_virtual_get(cr, uid, op) + if prods is None: continue - if op.product_id.type not in ('consu'): - if op.procurement_draft_ids: - # Check draft procurement related to this order point - pro_ids = [x.id for x in op.procurement_draft_ids] - procure_datas = procurement_obj.read( - cr, uid, pro_ids, ['id', 'product_qty'], context=context) - to_generate = qty - for proc_data in procure_datas: - if to_generate >= proc_data['product_qty']: - self.signal_button_confirm(cr, uid, [proc_data['id']]) - procurement_obj.write(cr, uid, [proc_data['id']], {'origin': op.name}, context=context) - to_generate -= proc_data['product_qty'] - if not to_generate: - break - qty = to_generate + if prods < op.product_min_qty: + qty = max(op.product_min_qty, op.product_max_qty)-prods + + reste = qty % op.qty_multiple + if reste > 0: + qty += op.qty_multiple - reste + + if qty <= 0: + continue + if op.product_id.type not in ('consu'): + if op.procurement_draft_ids: + # Check draft procurement related to this order point + pro_ids = [x.id for x in op.procurement_draft_ids] + procure_datas = procurement_obj.read( + cr, uid, pro_ids, ['id', 'product_qty'], context=context) + to_generate = qty + for proc_data in procure_datas: + if to_generate >= proc_data['product_qty']: + self.signal_button_confirm(cr, uid, [proc_data['id']]) + procurement_obj.write(cr, uid, [proc_data['id']], {'origin': op.name}, context=context) + to_generate -= proc_data['product_qty'] + if not to_generate: + break + qty = to_generate + + if qty: + proc_id = procurement_obj.create(cr, uid, + self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context), + context=context) + self.signal_button_confirm(cr, uid, [proc_id]) + self.signal_button_check(cr, uid, [proc_id]) + orderpoint_obj.write(cr, uid, [op.id], + {'procurement_id': proc_id}, context=context) + if use_new_cursor: + cr.commit() + except OperationalError: + if use_new_cursor: + orderpoint_ids.append(op.id) + cr.rollback() + continue + else: + raise + if prev_ids == ids: + break + else: + prev_ids = ids - if qty: - proc_id = procurement_obj.create(cr, uid, - self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context), - context=context) - self.signal_button_confirm(cr, uid, [proc_id]) - self.signal_button_check(cr, uid, [proc_id]) - orderpoint_obj.write(cr, uid, [op.id], - {'procurement_id': proc_id}, context=context) - offset += len(ids) - if use_new_cursor: - cr.commit() if use_new_cursor: cr.commit() cr.close()