From 412b0eab4e6cf9fe90e548294129fb2273add3ac Mon Sep 17 00:00:00 2001 From: "Christophe Chauvet (Sylean)" <> Date: Fri, 12 Mar 2010 13:35:28 +0100 Subject: [PATCH 01/23] [FIX] crm, mail_gateway: Use the utf8 encoding bzr revid: stephane@openerp.com-20100312123528-ppvn4w9sdi20iw6v --- addons/crm/crm_action_rule.py | 30 +++++++++++++++---- addons/crm/crm_mailgate.py | 13 +++++--- .../crm/wizard/wizard_crm_new_send_email.py | 2 +- addons/crm/wizard/wizard_crm_send_email.py | 10 +++++-- addons/mail_gateway/mail_gateway.py | 6 ++-- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/addons/crm/crm_action_rule.py b/addons/crm/crm_action_rule.py index 1e7c50588db..0ca078d9b36 100644 --- a/addons/crm/crm_action_rule.py +++ b/addons/crm/crm_action_rule.py @@ -55,11 +55,12 @@ class case(osv.osv): if case.section_id.reply_to and case.email_from: src = case.email_from dest = case.section_id.reply_to + body = "" body = case.email_last or case.description if not destination: src, dest = dest, src - if case.user_id.signature: - body += '\n\n%s' % (case.user_id.signature or '') + if body and case.user_id.signature: + body += '\n\n%s' % (case.user_id.signature).encode('utf8') dest = [dest] attach_to_send = None @@ -79,10 +80,10 @@ class case(osv.osv): openobject_id=str(case.id), attach=attach_to_send ) - if flag: - raise osv.except_osv(_('Email!'),("Email Successfully Sent")) - else: - raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully")) + #if flag: + # raise osv.except_osv(_('Email!'),("Email Successfully Sent")) + #else: + # raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully")) return True def _check(self, cr, uid, ids=False, context={}): @@ -120,6 +121,23 @@ case() class base_action_rule(osv.osv): _inherit = 'base.action.rule' _description = 'Action Rules' + + def email_send(self, cr, uid, obj, emails, body, emailfrom=tools.config.get('email_from',False), context={}): + body = self.format_mail(obj, body) + if not emailfrom: + if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.address_id and obj.user_id.address_id.email: + emailfrom = obj.user_id.address_id.email + + name = '[%d] %s' % (obj.id, tools.ustr(obj.name)) + emailfrom = tools.ustr(emailfrom) + if obj.section_id and obj.section_id.reply_to: + reply_to = obj.section_id.reply_to + else: + reply_to = emailfrom + if not emailfrom: + raise osv.except_osv(_('Error!'), + _("No E-Mail ID Found for your Company address!")) + return tools.email_send(emailfrom, emails, name, body, reply_to=reply_to, openobject_id=str(obj.id)) def do_check(self, cr, uid, action, obj, context={}): ok = super(base_action_rule, self).do_check(cr, uid, action, obj, context=context) diff --git a/addons/crm/crm_mailgate.py b/addons/crm/crm_mailgate.py index 8b2f3bdef88..f500e3e082f 100644 --- a/addons/crm/crm_mailgate.py +++ b/addons/crm/crm_mailgate.py @@ -36,13 +36,18 @@ class crm_cases(osv.osv): _name = "crm.case" _inherit = "crm.case" + def _decode_header(self, s): + from email.Header import decode_header + s = decode_header(s) + return ''.join(map(lambda x:x[0].decode(x[1] or 'ascii', 'replace'), s)) + def msg_new(self, cr, uid, msg): mailgate_obj = self.pool.get('mail.gateway') msg_body = mailgate_obj.msg_body_get(msg) data = { - 'name': msg['Subject'], - 'email_from': msg['From'], - 'email_cc': msg['Cc'], + 'name': self._decode_header(msg['Subject']), + 'email_from': self._decode_header(msg['From']), + 'email_cc': msg['Cc'] and self._decode_header(msg['Cc']), 'user_id': False, 'description': msg_body['body'], } @@ -51,7 +56,7 @@ class crm_cases(osv.osv): data.update(res) res = self.create(cr, uid, data) cases = self.browse(cr, uid, [res]) - self._history(cr, uid, cases, _('Receive'), history=True, email=msg['From']) + self._history(cr, uid, cases, _('Receive'), history=True, email=self._decode_header(msg['From'])) return res def msg_update(self, cr, uid, ids, msg, data={}, default_act='pending'): diff --git a/addons/crm/wizard/wizard_crm_new_send_email.py b/addons/crm/wizard/wizard_crm_new_send_email.py index 0114ac9408f..61491fe437d 100644 --- a/addons/crm/wizard/wizard_crm_new_send_email.py +++ b/addons/crm/wizard/wizard_crm_new_send_email.py @@ -81,7 +81,7 @@ def _mass_mail_send(self, cr, uid, data, context): emails = filter(None, emails) body = data['form']['text'] if case.user_id.signature: - body += '\n\n%s' % (case.user_id.signature) + body += '\n\n%s' % (case.user_id.signature).encode('utf8') case_pool._history(cr, uid, [case], _('Send'), history=True, email=data['form']['to'], details=body) flag = tools.email_send( case.user_id.address_id.email, diff --git a/addons/crm/wizard/wizard_crm_send_email.py b/addons/crm/wizard/wizard_crm_send_email.py index d6b3732d5e7..02f8f2abe04 100644 --- a/addons/crm/wizard/wizard_crm_send_email.py +++ b/addons/crm/wizard/wizard_crm_send_email.py @@ -61,11 +61,17 @@ def _mass_mail_send(self, cr, uid, data, context): 'som': False, 'canal_id': False, }) - emails = [data['form']['to']] + (data['form']['cc'] or '').split(',') + from_to = tools.email_re.search(data['form']['to']).group(1) + emails = [] + if from_to: + emails.append(from_to) + for cc in (data['form']['cc'] or '').split(','): + if cc: + emails.append(tools.email_re.search(cc).group(1)) emails = filter(None, emails) body = data['form']['text'] if case.user_id.signature: - body += '\n\n%s' % (case.user_id.signature) + body += '\n\n%s' % (case.user_id.signature).encode('utf8') tools.email_send( case.user_id.address_id.email, emails, diff --git a/addons/mail_gateway/mail_gateway.py b/addons/mail_gateway/mail_gateway.py index ee7676d4423..a25816d28b2 100644 --- a/addons/mail_gateway/mail_gateway.py +++ b/addons/mail_gateway/mail_gateway.py @@ -362,13 +362,11 @@ class mail_gateway(osv.osv): del msg['Subject'] msg['Subject'] = '[%s] %s' %(str(res_id), subject) - em = [user_email, from_email] + (cc_email or '').split(',') + em = [user_email or '', from_email] + (cc_email or '').split(',') emails = map(self.emails_get, filter(None, em)) - mm = [self._decode_header(msg['From']), self._decode_header(msg['To'])]+self._decode_header(msg.get('Cc','')).split(',') msg_mails = map(self.emails_get, filter(None, mm)) - - emails = filter(lambda m: m and m not in msg_mails, emails) + emails = filter(lambda m: m and m not in msg_mails, emails) try: self.msg_send(msg, mailgateway.reply_to, emails, priority, res_id) if hasattr(self.pool.get(res_model), 'msg_send'): From b6c304baf43c02345914e84f94f9d94d8b03f8df Mon Sep 17 00:00:00 2001 From: Christophe Chauvet Date: Tue, 30 Mar 2010 15:27:19 +0200 Subject: [PATCH 02/23] [FIX] Evaluate domain in act_window element is now possible lp bug: https://launchpad.net/bugs/551664 fixed bzr revid: christophe.chauvet@syleam.fr-20100330132719-ac5h84t8h0mu7tuz --- bin/tools/convert.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 75b438cc6ea..3d98ed6b796 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -384,6 +384,7 @@ form: module.record_id""" % (xml_id,) def ref(str_id): return self.id_get(cr, None, str_id) context=eval(context) + domain=eval(domain) res = { 'name': name, From 01578fff22c482fbfd4c818b50fd364461be892f Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 30 Mar 2010 19:26:03 +0200 Subject: [PATCH 03/23] [ADD] utility methods to split large lists of ids for use in IN clauses bzr revid: odo@openerp.com-20100330172603-ty878ds2i9oa33zq --- bin/sql_db.py | 8 +++++++- bin/tools/misc.py | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/bin/sql_db.py b/bin/sql_db.py index 17bfa340653..94336cde69a 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -63,7 +63,7 @@ re_into = re.compile('.* into "?([a-zA-Z_0-9]+)"? .*$'); sql_counter = 0 class Cursor(object): - IN_MAX = 1000 + IN_MAX = 1000 # decent limit on size of IN queries - guideline = Oracle limit __logger = logging.getLogger('db.cursor') def check(f): @@ -142,6 +142,12 @@ class Cursor(object): self.sql_into_log[res_into.group(1)][1] += delay return res + + def split_for_in_conditions(self, ids): + """Split a list of identifiers into one or more smaller tuples + safe for IN conditions, after uniquifying them.""" + return tools.misc.split_every(self.IN_MAX, set(ids)) + def print_log(self): global sql_counter sql_counter += self.sql_log_count diff --git a/bin/tools/misc.py b/bin/tools/misc.py index 284324873de..ff20966857e 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -32,6 +32,7 @@ import zipfile import release import socket import re +from itertools import islice if sys.version_info[:2] < (2, 4): from threadinglocal import local @@ -1267,6 +1268,18 @@ def detect_server_timezone(): return 'UTC' +def split_every(n, iterable, piece_maker=tuple): + """Splits an iterable into length-n pieces. The last piece will be shorter + if ``n`` does not evenly divide the iterable length. + @param ``piece_maker``: function to build the pieces + from the slices (tuple,list,...) + """ + iterator = iter(iterable) + piece = piece_maker(islice(iterator, n)) + while piece: + yield piece + piece = piece_maker(islice(iterator, n)) + if __name__ == '__main__': import doctest doctest.testmod() From 6c23c63afe714e384dc4c8caab300857486a0691 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Tue, 30 Mar 2010 19:28:06 +0200 Subject: [PATCH 04/23] [IMP] refactoring of check_access_rule to avoid SQL injection and simplify code bzr revid: odo@openerp.com-20100330172806-p1zkvrmupw5zosai --- bin/osv/orm.py | 70 +++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 697eb01f4e2..32efe32558b 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -2572,17 +2572,16 @@ class orm(orm_template): return '"%s"' % (f,) fields_pre2 = map(convert_field, fields_pre) order_by = self._parent_order or self._order - for i in range(0, len(ids), cr.IN_MAX): - sub_ids = ids[i:i+cr.IN_MAX] + for sub_ids in cr.split_for_in_conditions(ids): if d1: - cr.execute('SELECT %s FROM %s WHERE %s.id = ANY (%%s) AND %s ORDER BY %s' % \ + cr.execute('SELECT %s FROM %s WHERE %s.id IN %%s AND %s ORDER BY %s' % \ (','.join(fields_pre2 + [self._table + '.id']), ','.join(tables), self._table, ' and '.join(d1), order_by),[sub_ids,]+d2) - if not cr.rowcount == len({}.fromkeys(sub_ids)): + if cr.rowcount != len(sub_ids): raise except_orm(_('AccessError'), _('You try to bypass an access rule while reading (Document type: %s).') % self._description) else: - cr.execute('SELECT %s FROM \"%s\" WHERE id = ANY (%%s) ORDER BY %s' % + cr.execute('SELECT %s FROM \"%s\" WHERE id IN %%s ORDER BY %s' % (','.join(fields_pre2 + ['id']), self._table, order_by), (sub_ids,)) res.extend(cr.dictfetchall()) @@ -2734,29 +2733,24 @@ class orm(orm_template): if res and res[0]: raise except_orm('ConcurrencyException', _('Records were modified in the meanwhile')) - def check_access_rule(self, cr, uid, ids, mode, context=None): - d1, d2, tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, mode, context=context) - if d1: - d1 = ' and '+' and '.join(d1) - - for i in range(0, len(ids), cr.IN_MAX): - sub_ids = ids[i:i+cr.IN_MAX] - if d1: - cr.execute('SELECT '+self._table+'.id FROM '+','.join(tables)+' ' \ - 'WHERE '+self._table+'.id IN %s'+d1, (tuple(sub_ids),d2)) - if not cr.rowcount == len(sub_ids): + def check_access_rule(self, cr, uid, ids, operation, context=None): + """Verifies that the operation given by ``operation`` is allowed for the user + according to ir.rules. + @param ``operation``: one of ``'read'``, ``'write'``, ``'unlink'`` + @raise ``except_orm``: if current ir.rules do not permit this operation. + @return: ``None`` if the operation is allowed + """ + where_clause, where_params, tables = self.pool.get('ir.rule').domain_get(cr, uid, self._name, operation, context=context) + if where_clause: + where_clause = ' and ' + ' and '.join(where_clause) + for sub_ids in cr.split_for_in_conditions(ids): + cr.execute('SELECT ' + self._table + '.id FROM ' + ','.join(tables) + + ' WHERE ' + self._table + '.id IN %s' + where_clause, + [sub_ids] + where_params) + if cr.rowcount != len(sub_ids): raise except_orm(_('AccessError'), - _('You try to bypass an access rule to '+mode+ - ' (Document type: %s).') % self._name) - else: - cr.execute('SELECT id FROM "'+self._table+'" WHERE id IN %s', - (tuple(sub_ids),)) - if not cr.rowcount == len(sub_ids): - raise except_orm(_('AccessError'), - _('You try to ' +mode+ ' a record that doesn\'t exist (Document type: %s).') - % self._name) - #TODO: this is a SQL injection pattern again, need to refactor it - return ','.join(map(str,ids)) + _('Operation prohibited by access rules (Operation: %s, Document type: %s).') + % (operation, self._name)) def unlink(self, cr, uid, ids, context=None): if not ids: @@ -2787,12 +2781,13 @@ class orm(orm_template): # ids2 = [x[self._inherits[key]] for x in res] # self.pool.get(key).unlink(cr, uid, ids2) - ids_str = self.check_access_rule(cr, uid, ids, 'unlink', context=context) - cr.execute('delete from '+self._table+' ' \ - 'where id in ('+ids_str+')', ids) + self.check_access_rule(cr, uid, ids, 'unlink', context=context) + for sub_ids in cr.split_for_in_conditions(ids): + cr.execute('delete from ' + self._table + ' ' \ + 'where id in %s', sub_ids) for order, object, store_ids, fields in result_store: - if object<>self._name: + if object != self._name: obj = self.pool.get(object) cr.execute('select id from '+obj._table+' where id in ('+','.join(map(str, store_ids))+')') rids = map(lambda x: x[0], cr.fetchall()) @@ -2888,9 +2883,10 @@ class orm(orm_template): upd1.append(user) if len(upd0): - ids_str = self.check_access_rule(cr, user, ids, 'write', context=context) - cr.execute('update '+self._table+' set '+string.join(upd0, ',')+' ' \ - 'where id in ('+ids_str+')', upd1) + self.check_access_rule(cr, user, ids, 'write', context=context) + for sub_ids in cr.split_for_in_conditions(ids): + cr.execute('update ' + self._table + ' set ' + ','.join(upd0) + ' ' \ + 'where id in %s', upd1 + [sub_ids]) if totranslate: # TODO: optimize @@ -2921,11 +2917,9 @@ class orm(orm_template): for table in self._inherits: col = self._inherits[table] nids = [] - for i in range(0, len(ids), cr.IN_MAX): - sub_ids = ids[i:i+cr.IN_MAX] - ids_str = string.join(map(str, sub_ids), ',') + for sub_ids in cr.split_for_in_conditions(ids): cr.execute('select distinct "'+col+'" from "'+self._table+'" ' \ - 'where id in ('+ids_str+')', upd1) + 'where id in %s', (sub_ids,)) nids.extend([x[0] for x in cr.fetchall()]) v = {} From 29903b36c8d02b7d1050db6f38e743124ab4e1d1 Mon Sep 17 00:00:00 2001 From: Launchpad Code Hosting Date: Wed, 31 Mar 2010 04:54:43 +0100 Subject: [PATCH 05/23] Launchpad automatic translations update. bzr revid: codehost@crowberry-20100331035443-psztrssd1w0hpvpj --- bin/addons/base/i18n/bg.po | 4 ++-- bin/addons/base/i18n/hr.po | 4 ++-- bin/addons/base/i18n/it.po | 14 +++++++------- bin/addons/base/i18n/ja.po | 4 ++-- bin/addons/base/i18n/sv.po | 4 ++-- bin/addons/base/i18n/uk.po | 4 ++-- bin/addons/base/i18n/zh_CN.po | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bin/addons/base/i18n/bg.po b/bin/addons/base/i18n/bg.po index 04d5ab798d1..5570b263bec 100644 --- a/bin/addons/base/i18n/bg.po +++ b/bin/addons/base/i18n/bg.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 10:51+0000\n" +"PO-Revision-Date: 2010-03-30 04:19+0000\n" "Last-Translator: Boris \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:50+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/hr.po b/bin/addons/base/i18n/hr.po index 9290624ea43..f3739c66bf3 100644 --- a/bin/addons/base/i18n/hr.po +++ b/bin/addons/base/i18n/hr.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 04:13+0000\n" +"PO-Revision-Date: 2010-03-30 04:36+0000\n" "Last-Translator: goranc \n" "Language-Team: openerp-translators\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:50+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Language: hr\n" diff --git a/bin/addons/base/i18n/it.po b/bin/addons/base/i18n/it.po index a1cfce3afdf..3d99b3829d9 100644 --- a/bin/addons/base/i18n/it.po +++ b/bin/addons/base/i18n/it.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 15:30+0000\n" +"PO-Revision-Date: 2010-03-30 09:53+0000\n" "Last-Translator: Carlo Vettore \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:50+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base @@ -3641,7 +3641,7 @@ msgstr "Crea azione" #. module: base #: selection:ir.actions.report.xml,report_type:0 msgid "HTML from HTML" -msgstr "" +msgstr "HTML da HTML" #. module: base #: selection:ir.actions.report.xml,report_type:0 @@ -3733,12 +3733,12 @@ msgstr "STOCK_ADD" #. module: base #: field:ir.cron,doall:0 msgid "Repeat Missed" -msgstr "" +msgstr "Ripeti mancato" #. module: base #: help:ir.actions.server,state:0 msgid "Type of the Action that is to be executed" -msgstr "" +msgstr "Tipo dell'azione che deve essere eseguita" #. module: base #: field:ir.server.object.lines,server_id:0 @@ -3783,7 +3783,7 @@ msgstr "Botswana" #: model:ir.ui.menu,name:base.menu_partner_title_partner #: view:res.partner.title:0 msgid "Partner Titles" -msgstr "" +msgstr "Qualifiche Partner" #. module: base #: selection:ir.actions.todo,type:0 @@ -6722,7 +6722,7 @@ msgstr "" #. module: base #: field:res.partner.bank,acc_number:0 msgid "Account Number" -msgstr "" +msgstr "Numero conto" #. module: base #: view:res.lang:0 diff --git a/bin/addons/base/i18n/ja.po b/bin/addons/base/i18n/ja.po index dd3caace65e..9430360cb87 100644 --- a/bin/addons/base/i18n/ja.po +++ b/bin/addons/base/i18n/ja.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-server\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 04:11+0000\n" +"PO-Revision-Date: 2010-03-30 04:24+0000\n" "Last-Translator: Harry (Open ERP) \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:50+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/sv.po b/bin/addons/base/i18n/sv.po index 73c67ea25ef..92102068d0d 100644 --- a/bin/addons/base/i18n/sv.po +++ b/bin/addons/base/i18n/sv.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 04:09+0000\n" +"PO-Revision-Date: 2010-03-30 04:18+0000\n" "Last-Translator: Anders Wallenquist \n" "Language-Team: <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:51+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/uk.po b/bin/addons/base/i18n/uk.po index 0c8b97a9a71..be9ac9ddeb1 100644 --- a/bin/addons/base/i18n/uk.po +++ b/bin/addons/base/i18n/uk.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.0\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 04:11+0000\n" +"PO-Revision-Date: 2010-03-30 04:37+0000\n" "Last-Translator: Fabien (Open ERP) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:51+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base diff --git a/bin/addons/base/i18n/zh_CN.po b/bin/addons/base/i18n/zh_CN.po index fd637aa00f7..795f0a2c33f 100644 --- a/bin/addons/base/i18n/zh_CN.po +++ b/bin/addons/base/i18n/zh_CN.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.4\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2009-12-18 08:39+0000\n" -"PO-Revision-Date: 2010-03-29 04:11+0000\n" +"PO-Revision-Date: 2010-03-30 04:19+0000\n" "Last-Translator: OpenERP Administrators \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2010-03-30 03:51+0000\n" +"X-Launchpad-Export-Date: 2010-03-31 03:54+0000\n" "X-Generator: Launchpad (build Unknown)\n" #. module: base From 6a0c68a3641474fb0faaa5c91b8d8b60de26507c Mon Sep 17 00:00:00 2001 From: odoo Date: Wed, 31 Mar 2010 03:54:57 +0000 Subject: [PATCH 06/23] disable non updateble xml files, remove non existent fields in crm.case.log views bzr revid: odoo@ip-10-226-66-207-20100331035457-66s15j3wgy0xidm8 --- addons/crm/__terp__.py | 1 - addons/crm/crm_view.xml | 8 ++++++-- addons/project_issue/__terp__.py | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/addons/crm/__terp__.py b/addons/crm/__terp__.py index b2a40c822a6..ef5b80cc3b2 100644 --- a/addons/crm/__terp__.py +++ b/addons/crm/__terp__.py @@ -70,7 +70,6 @@ between mails and Open ERP.""", 'crm_lead_menu.xml', 'crm_meeting_wizard.xml', 'crm_meeting_view.xml', - 'crm_meeting_menu.xml', 'crm_phonecall_wizard.xml', 'crm_phonecall_view.xml', 'crm_phonecall_menu.xml', diff --git a/addons/crm/crm_view.xml b/addons/crm/crm_view.xml index 6594c2a213d..ccafb1af976 100644 --- a/addons/crm/crm_view.xml +++ b/addons/crm/crm_view.xml @@ -216,10 +216,12 @@ - + @@ -233,9 +235,11 @@ - + diff --git a/addons/project_issue/__terp__.py b/addons/project_issue/__terp__.py index 03ec9e22285..c4187abec5a 100644 --- a/addons/project_issue/__terp__.py +++ b/addons/project_issue/__terp__.py @@ -41,8 +41,8 @@ 'update_xml': [ 'project_issue_wizard.xml', 'project_issue_view.xml', - 'project_issue_menu.xml', - 'project_feature_menu.xml', +# 'project_issue_menu.xml', +# 'project_feature_menu.xml', 'report/project_issue_report_view.xml', 'security/project_issue_security.xml', 'security/ir.model.access.csv', From b6c87a04bf14a60ef09ec42b14dc87054a221084 Mon Sep 17 00:00:00 2001 From: "Harry (Open ERP)" Date: Wed, 31 Mar 2010 11:02:41 +0530 Subject: [PATCH 07/23] [FIX] convert: set uid variable which are used in view domain bzr revid: hmo@tinyerp.com-20100331053241-3jj97egt9nb4kwie --- bin/tools/convert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/tools/convert.py b/bin/tools/convert.py index 3d98ed6b796..a7bd6207cd3 100644 --- a/bin/tools/convert.py +++ b/bin/tools/convert.py @@ -376,7 +376,7 @@ form: module.record_id""" % (xml_id,) usage = rec.get('usage','').encode('utf-8') limit = rec.get('limit','').encode('utf-8') auto_refresh = rec.get('auto_refresh','').encode('utf-8') - + uid = self.uid # def ref() added because , if context has ref('id') eval wil use this ref active_id=str("active_id") # for further reference in client/bin/tools/__init__.py From 101b96a591f70b2e3e336716a2f3a5ca742a3d1b Mon Sep 17 00:00:00 2001 From: "Harry (Open ERP)" Date: Wed, 31 Mar 2010 12:21:02 +0530 Subject: [PATCH 08/23] [FIX] stock: correct incomplete work bzr revid: hmo@tinyerp.com-20100331065102-lkawbyzxkh9mvndv --- addons/stock/__terp__.py | 3 +- addons/stock/wizard/__init__.py | 5 +- addons/stock/wizard/stock_inventory_merge.py | 16 ++- .../wizard/stock_inventory_merge_view.xml | 27 ++++ addons/stock/wizard/stock_picking_make.py | 119 +++++++----------- .../stock/wizard/stock_picking_make_view.xml | 31 +++++ 6 files changed, 122 insertions(+), 79 deletions(-) create mode 100644 addons/stock/wizard/stock_inventory_merge_view.xml create mode 100644 addons/stock/wizard/stock_picking_make_view.xml diff --git a/addons/stock/__terp__.py b/addons/stock/__terp__.py index 5fa272238d5..459a2faaf84 100644 --- a/addons/stock/__terp__.py +++ b/addons/stock/__terp__.py @@ -48,10 +48,11 @@ Thanks to the double entry management, the inventory controlling is powerful and "wizard/stock_inventory_set_stock_zero_view.xml", "wizard/stock_fill_inventory_view.xml", "wizard/stock_invoice_onshipping_view.xml", + "wizard/stock_inventory_merge_view.xml", "wizard/stock_location_product_view.xml", "wizard/stock_inventory_line_split_view.xml", "wizard/stock_change_standard_price_view.xml", - + "wizard/stock_picking_make_view.xml", "wizard/stock_traceability_view.xml", "stock_workflow.xml", "stock_incoterms.xml", diff --git a/addons/stock/wizard/__init__.py b/addons/stock/wizard/__init__.py index 6f5a83a07b3..7c87212571c 100644 --- a/addons/stock/wizard/__init__.py +++ b/addons/stock/wizard/__init__.py @@ -23,18 +23,17 @@ import stock_traceability import stock_move import stock_partial_picking import stock_partial_move -import wizard_picking_make +import stock_picking_make import wizard_replacement import wizard_return import wizard_split_lot_line import wizard_ups -import inventory_merge +import stock_inventory_merge import stock_inventory_set_stock_zero import stock_fill_inventory import stock_inventory_line_split import stock_invoice_onshipping import stock_location_product import stock_change_standard_price - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/wizard/stock_inventory_merge.py b/addons/stock/wizard/stock_inventory_merge.py index 64620054ff8..1c11ad8e2ad 100644 --- a/addons/stock/wizard/stock_inventory_merge.py +++ b/addons/stock/wizard/stock_inventory_merge.py @@ -36,7 +36,18 @@ class stock_inventory_merge(osv.osv_memory): } def do_merge(self, cr, uid, ids, context): - + """ + To merge selected Inventories. + + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param ids: List of IDs selected + @param context: A standard dictionary + + @return: + + """ invent_obj = self.pool.get('stock.inventory') invent_line_obj = self.pool.get('stock.inventory.line') @@ -46,10 +57,7 @@ class stock_inventory_merge(osv.osv_memory): raise osv.except_osv(_('Warning'), _('Please select at least two inventories.')) - - for inventory in invent_obj.browse(cr, uid, context['active_ids'], context=context): - print"-------active-ids----",context['active_ids'] if inventory.state == "done": raise osv.except_osv(_('Warning'), _('Merging is only allowed on draft inventories.')) diff --git a/addons/stock/wizard/stock_inventory_merge_view.xml b/addons/stock/wizard/stock_inventory_merge_view.xml new file mode 100644 index 00000000000..e8af34c0c71 --- /dev/null +++ b/addons/stock/wizard/stock_inventory_merge_view.xml @@ -0,0 +1,27 @@ + + + + + + stock.inventory.merge.form + stock.inventory.merge + form + +
+ +