[MERGE] forward port of branch 7.0 up to 245bb4e

This commit is contained in:
Denis Ledoux 2014-08-12 14:16:35 +02:00
commit 2c9a116c74
6 changed files with 96 additions and 68 deletions

View File

@ -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) 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 sent_emails = self._build_email_kwargs_list
email_to_lst = [ email_to_lst = [
['b@b.b', 'c@c.c'], ['"Followers of Pigs" <admin@yourcompany.example.com>'], ['b@b.b', 'c@c.c'], ['Followers of Pigs <admin@yourcompany.example.com>'],
['"Followers of Pigs" <raoul@raoul.fr>'], ['"Followers of Pigs" <bert@bert.fr>']] ['Followers of Pigs <raoul@raoul.fr>'], ['Followers of Pigs <bert@bert.fr>']]
self.assertEqual(len(sent_emails), 4, 'email_template: send_mail: 3 valid email recipients + email_to -> should send 4 emails') 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: for email in sent_emails:
self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients') self.assertIn(email['email_to'], email_to_lst, 'email_template: send_mail: wrong email_recipients')

View File

@ -49,7 +49,7 @@ class account_coda_import(osv.osv_memory):
return tmp_account_id return tmp_account_id
_defaults = { _defaults = {
'coda_fname': lambda *a: '', 'coda_fname': 'coda.txt',
'temporary_account_id': _get_default_tmp_account, 'temporary_account_id': _get_default_tmp_account,
} }

View File

@ -22,6 +22,7 @@
import base64 import base64
import logging import logging
import re import re
from email.utils import formataddr
from urllib import urlencode from urllib import urlencode
from urlparse import urljoin from urlparse import urljoin
@ -210,10 +211,9 @@ class mail_mail(osv.Model):
# 2. if 'partner' is specified, but no related document: Partner Name <email> # 2. if 'partner' is specified, but no related document: Partner Name <email>
# 3; fallback on mail.email_to that we split to have an email addresses list # 3; fallback on mail.email_to that we split to have an email addresses list
if partner and mail.record_name: if partner and mail.record_name:
sanitized_record_name = re.sub(r'[^\w+.]+', '-', mail.record_name) email_to = [formataddr((_('Followers of %s') % mail.record_name, partner.email))]
email_to = [_('"Followers of %s" <%s>') % (sanitized_record_name, partner.email)]
elif partner: elif partner:
email_to = ['%s <%s>' % (partner.name, partner.email)] email_to = [formataddr((partner.name, partner.email))]
else: else:
email_to = tools.email_split(mail.email_to) email_to = tools.email_split(mail.email_to)

View File

@ -25,6 +25,7 @@ import re
from openerp import tools from openerp import tools
from email.header import decode_header from email.header import decode_header
from email.utils import formataddr
from openerp import SUPERUSER_ID from openerp import SUPERUSER_ID
from openerp.osv import osv, orm, fields from openerp.osv import osv, orm, fields
from openerp.tools import html_email_clean 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): def _get_default_from(self, cr, uid, context=None):
this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
if this.alias_name and this.alias_domain: 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: 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.")) 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): def _get_default_author(self, cr, uid, context=None):

View File

@ -468,7 +468,7 @@ class test_mail(TestMail):
# Test: notifications emails: to a and b, c is email only, r is author # Test: notifications emails: to a and b, c is email only, r is author
# test_emailto = ['Administrator <a@a>', 'Bert Tartopoils <b@b>'] # test_emailto = ['Administrator <a@a>', 'Bert Tartopoils <b@b>']
test_emailto = ['"Followers of -Pigs-" <a@a>', '"Followers of -Pigs-" <b@b>'] test_emailto = [u'"Followers of \\"Pigs\\" !\xf9 $%-" <a@a>', u'"Followers of \\"Pigs\\" !\xf9 $%-" <b@b>']
self.assertEqual(len(sent_emails), 2, self.assertEqual(len(sent_emails), 2,
'message_post: notification emails wrong number of send emails') 'message_post: notification emails wrong number of send emails')
self.assertEqual(set([m['email_to'][0] for m in sent_emails]), set(test_emailto), 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') '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, self.assertIn(sent_email['email_to'][0], test_emailto,
'message_post: notification email email_to incorrect') 'message_post: notification email email_to incorrect')
self.assertEqual(sent_email['reply_to'], '"Followers of -Pigs-" <group+pigs@schlouby.fr>', self.assertEqual(sent_email['reply_to'], u'"Followers of \\"Pigs\\" !\xf9 $%-" <group+pigs@schlouby.fr>',
'message_post: notification email reply_to incorrect') 'message_post: notification email reply_to incorrect')
self.assertEqual(_subject, sent_email['subject'], self.assertEqual(_subject, sent_email['subject'],
'message_post: notification email subject incorrect') '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: emails send by server (to a, b, c, d)
# test_emailto = [u'Administrator <a@a>', u'Bert Tartopoils <b@b>', u'Carine Poilvache <c@c>', u'D\xe9d\xe9 Grosbedon <d@d>'] # test_emailto = [u'Administrator <a@a>', u'Bert Tartopoils <b@b>', u'Carine Poilvache <c@c>', u'D\xe9d\xe9 Grosbedon <d@d>']
test_emailto = [u'"Followers of Pigs" <a@a>', u'"Followers of Pigs" <b@b>', u'"Followers of Pigs" <c@c>', u'"Followers of Pigs" <d@d>'] test_emailto = [u'Followers of Pigs <a@a>', u'Followers of Pigs <b@b>', u'Followers of Pigs <c@c>', u'Followers of Pigs <d@d>']
# self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect') # self.assertEqual(len(sent_emails), 3, 'sent_email number of sent emails incorrect')
for sent_email in sent_emails: for sent_email in sent_emails:
self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon <r@r>', self.assertEqual(sent_email['email_from'], 'Raoul Grosbedon <r@r>',

View File

@ -28,6 +28,7 @@ from openerp.osv import fields
from openerp.tools.translate import _ from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
from openerp import tools from openerp import tools
from psycopg2 import OperationalError
class procurement_order(osv.osv): class procurement_order(osv.osv):
_inherit = 'procurement.order' _inherit = 'procurement.order'
@ -70,33 +71,45 @@ class procurement_order(osv.osv):
cr.commit() cr.commit()
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id 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) maxdate = (datetime.today() + relativedelta(days=company.schedule_range)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
offset = 0 prev_ids = []
while True: 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): 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]) self.signal_button_check(cr, uid, [proc.id])
else:
offset += 1
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
if not ids: except OperationalError:
if use_new_cursor:
cr.rollback()
continue
else:
raise
if not ids or prev_ids == ids:
break break
offset = 0 else:
prev_ids = ids
ids = [] ids = []
prev_ids = []
while True: while True:
report_ids = [] ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock'), ('date_planned', '<', maxdate)], limit=500)
ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset)
for proc in procurement_obj.browse(cr, uid, ids): for proc in procurement_obj.browse(cr, uid, ids):
if maxdate >= proc.date_planned: try:
self.signal_button_check(cr, uid, [proc.id]) self.signal_button_check(cr, uid, [proc.id])
report_ids.append(proc.id)
if use_new_cursor: if use_new_cursor:
cr.commit() cr.commit()
offset += len(ids) except OperationalError:
if not ids: break 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: if use_new_cursor:
cr.commit() cr.commit()
@ -203,52 +216,66 @@ class procurement_order(osv.osv):
orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
procurement_obj = self.pool.get('procurement.order') procurement_obj = self.pool.get('procurement.order')
offset = 0
ids = [1] ids = [1]
prev_ids = []
if automatic: if automatic:
self.create_automatic_op(cr, uid, context=context) self.create_automatic_op(cr, uid, context=context)
while ids: orderpoint_ids = orderpoint_obj.search(cr, uid, [])
ids = orderpoint_obj.search(cr, uid, [], offset=offset, limit=100) while orderpoint_ids:
ids = orderpoint_ids[:100]
del orderpoint_ids[:100]
for op in orderpoint_obj.browse(cr, uid, ids, context=context): for op in orderpoint_obj.browse(cr, uid, ids, context=context):
prods = self._product_virtual_get(cr, uid, op) try:
if prods is None: prods = self._product_virtual_get(cr, uid, op)
continue if prods is None:
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 continue
if op.product_id.type not in ('consu'): if prods < op.product_min_qty:
if op.procurement_draft_ids: qty = max(op.product_min_qty, op.product_max_qty)-prods
# Check draft procurement related to this order point
pro_ids = [x.id for x in op.procurement_draft_ids] reste = qty % op.qty_multiple
procure_datas = procurement_obj.read( if reste > 0:
cr, uid, pro_ids, ['id', 'product_qty'], context=context) qty += op.qty_multiple - reste
to_generate = qty
for proc_data in procure_datas: if qty <= 0:
if to_generate >= proc_data['product_qty']: continue
self.signal_button_confirm(cr, uid, [proc_data['id']]) if op.product_id.type not in ('consu'):
procurement_obj.write(cr, uid, [proc_data['id']], {'origin': op.name}, context=context) if op.procurement_draft_ids:
to_generate -= proc_data['product_qty'] # Check draft procurement related to this order point
if not to_generate: pro_ids = [x.id for x in op.procurement_draft_ids]
break procure_datas = procurement_obj.read(
qty = to_generate 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: if use_new_cursor:
cr.commit() cr.commit()
cr.close() cr.close()