Thibault Delavallée (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-addons/trunk-mail-concreting-tde into 
lp:~openerp-dev/openobject-addons/trunk-openchatter-DOM-chm.

Requested reviews:
  OpenERP R&D Team (openerp-dev)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-mail-concreting-tde/+merge/131865

Misc server-side changes and fixes.
-- 
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-mail-concreting-tde/+merge/131865
Your team OpenERP R&D Team is requested to review the proposed merge of 
lp:~openerp-dev/openobject-addons/trunk-mail-concreting-tde into 
lp:~openerp-dev/openobject-addons/trunk-openchatter-DOM-chm.
=== modified file 'account_voucher/voucher_sales_purchase_view.xml'
=== modified file 'analytic/analytic_view.xml'
=== modified file 'base_calendar/crm_meeting_view.xml'
=== modified file 'mail/mail_followers.py'
--- mail/mail_followers.py	2012-10-29 11:21:17 +0000
+++ mail/mail_followers.py	2012-10-29 11:30:38 +0000
@@ -84,11 +84,16 @@
         return False
 
     def set_message_read(self, cr, uid, msg_ids, read=None, context=None):
+<<<<<<< TREE
         """ Set a message and its child messages as (un)read for uid.
 
             :param bool read: read / unread
         """
         # TDE note: use child_of or front-end send correct values ?
+=======
+        """ TDE note: add a comment, verify method calls, because js seems obfuscated. """
+        # TDE note: child_of to set unread ?
+>>>>>>> MERGE-SOURCE
         user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
         notif_ids = self.search(cr, uid, [
             ('partner_id', '=', user_pid),

=== modified file 'mail/mail_message.py'
--- mail/mail_message.py	2012-10-29 11:21:17 +0000
+++ mail/mail_message.py	2012-10-29 11:30:38 +0000
@@ -63,9 +63,14 @@
         return name[:self._message_record_name_length] + '...'
 
     def _get_record_name(self, cr, uid, ids, name, arg, context=None):
+<<<<<<< TREE
         """ Return the related document name, using name_get. It is done using
             SUPERUSER_ID, to be sure to have the record name correctly stored. """
         # TDE note: regroup by model/ids, to have less queries to perform
+=======
+        """ Return the related document name, using name_get. It is done using
+            SUPERUSER_ID, to be sure to have the record name correctly stored. """
+>>>>>>> MERGE-SOURCE
         result = dict.fromkeys(ids, False)
         for message in self.read(cr, uid, ids, ['model', 'res_id'], context=context):
             if not message.get('model') or not message.get('res_id'):
@@ -118,6 +123,7 @@
                         ], 'Type',
             help="Message type: email for email message, notification for system "\
                  "message, comment for other messages such as user replies"),
+<<<<<<< TREE
         'email_from': fields.char('From',
             help="Email address of the sender. This field is set when no matching partner is found for incoming emails."),
         'author_id': fields.many2one('res.partner', 'Author',
@@ -125,6 +131,15 @@
         'partner_ids': fields.many2many('res.partner', string='Recipients'),
         'notified_partner_ids': fields.many2many('res.partner', 'mail_notification',
             'message_id', 'partner_id', 'Recipients'),
+=======
+        'email_from': fields.char('From',
+            help="Email address of the sender, to use if it does not match any partner."),
+        'author_id': fields.many2one('res.partner', 'Author',
+            help="Partner that did write the message. If not set, try to use the From field instead."),
+        'partner_ids': fields.many2many('res.partner', string='Recipients'),
+        'notified_partner_ids': fields.many2many('res.partner', 'mail_notification',
+            'message_id', 'partner_id', 'Recipients'),
+>>>>>>> MERGE-SOURCE
         'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel',
             'message_id', 'attachment_id', 'Attachments'),
         'parent_id': fields.many2one('mail.message', 'Parent Message', select=True, ondelete='set null', help="Initial thread message."),
@@ -206,6 +221,7 @@
 
             :param dict message: read result of a mail.message
         """
+<<<<<<< TREE
         # TDE note: this method should be optimized, to lessen the number of queries, will be done ASAP
         is_author = False
         if message['author_id']:
@@ -214,6 +230,15 @@
         elif message['email_from']:
             author_id = (0, message['email_from'])
 
+=======
+        is_author = False
+        if message['author_id']:
+            is_author = message['author_id'][0] == self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
+            author_id = message['author_id']
+        elif message['email_from']:
+            author_id = (0, message['email_from'])
+
+>>>>>>> MERGE-SOURCE
         has_voted = False
         if uid in message.get('vote_user_ids'):
             has_voted = True
@@ -322,10 +347,18 @@
                 ('id', 'child_of', message['id']),
                 ('id', 'not in', message_loaded_ids),
                 ], context=context, limit=self._message_read_more_limit)
-            if not not_loaded_ids:
-                continue
-
-            # all_not_loaded_ids += not_loaded_ids
+<<<<<<< TREE
+            if not not_loaded_ids:
+                continue
+
+            # all_not_loaded_ids += not_loaded_ids
+=======
+            if not not_loaded_ids:
+                continue
+            # print 'not_loaded_ids', not_loaded_ids
+
+            # all_not_loaded_ids += not_loaded_ids
+>>>>>>> MERGE-SOURCE
             # group childs not read
             id_min, id_max, nb = max(not_loaded_ids), 0, 0
             for not_loaded_id in not_loaded_ids:
@@ -388,12 +421,20 @@
                 ancestors and expandables
             :return list: list of message structure for the Chatter widget
         """
+<<<<<<< TREE
         # print 'message_read', ids, domain, message_unload_ids, thread_level, context, parent_id, limit
         assert thread_level in [0, 1], 'message_read() thread_level should be 0 (flat) or 1 (1 level of thread); given %s.' % thread_level
         domain = domain if domain is not None else []
         message_unload_ids = message_unload_ids if message_unload_ids is not None else []
         if message_unload_ids:
             domain += [('id', 'not in', message_unload_ids)]
+=======
+        assert thread_level in [0, 1], 'message_read() thread_level should be 0 (flat) or 1 (1 level of thread); given %s.' % thread_level
+        domain = domain if domain is not None else []
+        message_unload_ids = message_unload_ids if message_unload_ids is not None else []
+        if message_unload_ids:
+            domain += [('id', 'not in', message_unload_ids)]
+>>>>>>> MERGE-SOURCE
         limit = limit or self._message_read_limit
         read_messages = {}
         message_list = []
@@ -448,6 +489,7 @@
         if not cr.fetchone():
             cr.execute("""CREATE INDEX mail_message_model_res_id_idx ON mail_message (model, res_id)""")
 
+<<<<<<< TREE
     def _search(self, cr, uid, args, offset=0, limit=None, order=None,
         context=None, count=False, access_rights_uid=None):
         """ Override that adds specific access rights of mail.message, to remove
@@ -500,6 +542,59 @@
         else:
             return list(final_ids)
 
+=======
+    def _search(self, cr, uid, args, offset=0, limit=None, order=None,
+        context=None, count=False, access_rights_uid=None):
+        """ Override that adds specific access rights of mail.message, to remove
+            ids uid could not see according to our custom rules. Please refer
+            to check_access_rule for more details about those rules.
+
+            After having received ids of a classic search, keep only:
+            - if author_id == pid, uid is the author, OR
+            - a notification (id, pid) exists, uid has been notified, OR
+            - uid have read access to the related document is model, res_id
+            - otherwise: remove the id
+        """
+        # Rules do not apply to administrator
+        if uid == SUPERUSER_ID:
+            return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
+            context=context, count=count, access_rights_uid=access_rights_uid)
+        # Perform a super with count as False, to have the ids, not a counter
+        ids = super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
+            context=context, count=False, access_rights_uid=access_rights_uid)
+        if not ids and count:
+            return 0
+        elif not ids:
+            return ids
+
+        pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'])['partner_id'][0]
+        author_ids, partner_ids, allowed_ids = set([]), set([]), set([])
+        model_ids = {}
+
+        messages = super(mail_message, self).read(cr, uid, ids, ['author_id', 'model', 'res_id', 'notified_partner_ids'], context=context)
+        for message in messages:
+            if message.get('author_id') and message.get('author_id')[0] == pid:
+                author_ids.add(message.get('id'))
+            elif pid in message.get('notified_partner_ids'):
+                partner_ids.add(message.get('id'))
+            elif message.get('model') and message.get('res_id'):
+                model_ids.setdefault(message.get('model'), {}).setdefault(message.get('res_id'), set()).add(message.get('id'))
+
+        model_access_obj = self.pool.get('ir.model.access')
+        for doc_model, doc_dict in model_ids.iteritems():
+            if not model_access_obj.check(cr, uid, doc_model, 'read', False):
+                continue
+            doc_ids = doc_dict.keys()
+            allowed_doc_ids = self.pool.get(doc_model).search(cr, uid, [('id', 'in', doc_ids)], context=context)
+            allowed_ids |= set([message_id for allowed_doc_id in allowed_doc_ids for message_id in doc_dict[allowed_doc_id]])
+
+        final_ids = author_ids | partner_ids | allowed_ids
+        if count:
+            return len(final_ids)
+        else:
+            return list(final_ids)
+
+>>>>>>> MERGE-SOURCE
     def check_access_rule(self, cr, uid, ids, operation, context=None):
         """ Access rules of mail.message:
             - read: if
@@ -623,6 +718,7 @@
             self.pool.get('ir.attachment').unlink(cr, uid, attachments_to_delete, context=context)
         return super(mail_message, self).unlink(cr, uid, ids, context=context)
 
+<<<<<<< TREE
     def copy(self, cr, uid, id, default=None, context=None):
         """ Overridden to avoid duplicating fields that are unique to each email """
         if default is None:
@@ -712,6 +808,95 @@
         """
         message = self.read(cr, uid, newid, ['model', 'res_id', 'author_id', 'subtype_id', 'partner_ids'], context=context)
 
+=======
+    def copy(self, cr, uid, id, default=None, context=None):
+        """ Overridden to avoid duplicating fields that are unique to each email """
+        if default is None:
+            default = {}
+        default.update(message_id=False, headers=False)
+        return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
+
+    #------------------------------------------------------
+    # Messaging API
+    #------------------------------------------------------
+
+    MAIL_TEMPLATE = """<div>
+    % if message:
+        ${display_message(message)}
+    % endif
+    % for ctx_msg in context_messages:
+        ${display_message(ctx_msg)}
+    % endfor
+    % if add_expandable:
+        ${display_expandable()}
+    % endif
+    ${display_message(header_message)}
+    </div>
+
+    <%def name="display_message(message)">
+        <div>
+            Subject: ${message.subject}<br />
+            Body: ${message.body}
+        </div>
+    </%def>
+
+    <%def name="display_expandable()">
+        <div>This is an expandable.</div>
+    </%def>
+    """
+
+    def message_quote_context(self, cr, uid, id, context=None, limit=3, add_original=False):
+        """
+            1. message.parent_id = False: new thread, no quote_context
+            2. get the lasts messages in the thread before message
+            3. get the message header
+            4. add an expandable between them
+
+            :param dict quote_context: options for quoting
+            :return string: html quote
+        """
+        add_expandable = False
+
+        message = self.browse(cr, uid, id, context=context)
+        if not message.parent_id:
+            return ''
+        context_ids = self.search(cr, uid, [
+            ('parent_id', '=', message.parent_id.id),
+            ('id', '<', message.id),
+            ], limit=limit, context=context)
+
+        if len(context_ids) >= limit:
+            add_expandable = True
+            context_ids = context_ids[0:-1]
+
+        context_ids.append(message.parent_id.id)
+        context_messages = self.browse(cr, uid, context_ids, context=context)
+        header_message = context_messages.pop()
+
+        try:
+            if not add_original:
+                message = False
+            result = MakoTemplate(self.MAIL_TEMPLATE).render_unicode(message=message,
+                                                        context_messages=context_messages,
+                                                        header_message=header_message,
+                                                        add_expandable=add_expandable,
+                                                        # context kw would clash with mako internals
+                                                        ctx=context,
+                                                        format_exceptions=True)
+            result = result.strip()
+            return result
+        except Exception:
+            _logger.exception("failed to render mako template for quoting message")
+            return ''
+        return result
+
+    def _notify(self, cr, uid, newid, context=None):
+        """ Add the related record followers to the destination partner_ids if is not a private message.
+            Call mail_notification.notify to manage the email sending
+        """
+        message = self.read(cr, uid, newid, ['model', 'res_id', 'author_id', 'subtype_id', 'partner_ids'], context=context)
+
+>>>>>>> MERGE-SOURCE
         partners_to_notify = set([])
         # message has no subtype_id: pure log message -> no partners, no one notified
         if not message.get('subtype_id'):

=== modified file 'mail/mail_message_view.xml'
=== modified file 'mail/mail_thread.py'
--- mail/mail_thread.py	2012-10-29 10:12:30 +0000
+++ mail/mail_thread.py	2012-10-29 11:30:38 +0000
@@ -707,6 +707,7 @@
 
         return mail_message.create(cr, uid, values, context=context)
 
+<<<<<<< TREE
     def message_post_api(self, cr, uid, thread_id, body='', subject=False, parent_id=False, attachment_ids=None, context=None):
         """ Wrapper on message_post, used only in Chatter (JS). The purpose is
             to handle attachments.
@@ -717,14 +718,37 @@
 
         # HACK FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
         if attachment_ids:
+=======
+    def message_post_api(self, cr, uid, thread_id, body='', subject=False, type='notification',
+                        parent_id=False, attachment_ids=None, context=None):
+        """ Wrapper on message_post, used only in Chatter (JS). The purpose is
+            to handle attachments.
+
+            # TDE FIXME: body is plaintext: convert it into html
+        """
+        new_message_id = self.message_post(cr, uid, thread_id=thread_id, body=body, subject=subject, type=type,
+                        subtype='mail.mt_comment', parent_id=parent_id, context=context)
+
+        # HACK FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
+        if attachment_ids:
+>>>>>>> MERGE-SOURCE
             ir_attachment = self.pool.get('ir.attachment')
             mail_message = self.pool.get('mail.message')
+<<<<<<< TREE
             filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
                 ('res_model', '=', 'mail.compose.message'),
                 ('res_id', '=', 0),
                 ('create_uid', '=', uid),
                 ('id', 'in', attachment_ids)], context=context)
             if filtered_attachment_ids:
+=======
+            filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [
+                ('res_model', '=', 'mail.message'),
+                ('res_id', '=', 0),
+                ('create_uid', '=', uid),
+                ('id', 'in', attachment_ids)], context=context)
+            if filtered_attachment_ids:
+>>>>>>> MERGE-SOURCE
                 ir_attachment.write(cr, SUPERUSER_ID, attachment_ids, {'res_model': self._name, 'res_id': thread_id}, context=context)
                 mail_message.write(cr, SUPERUSER_ID, [new_message_id], {'attachment_ids': [(6, 0, [pid for pid in attachment_ids])]}, context=context)
 

=== modified file 'mail/static/src/js/mail.js'
--- mail/static/src/js/mail.js	2012-10-29 11:22:54 +0000
+++ mail/static/src/js/mail.js	2012-10-29 11:30:38 +0000
@@ -353,9 +353,14 @@
                         this.context.default_res_id, 
                         mail.ChatterUtils.get_text2html(body), 
                         false, 
+<<<<<<< TREE
+=======
+                        'comment', 
+>>>>>>> MERGE-SOURCE
                         this.context.default_parent_id, 
                         attachments,
                         this.parent_thread.context
+<<<<<<< TREE
                     ]).then(function (record) {
                         var thread = self.parent_thread;
                         // create object and attach to the thread object
@@ -371,6 +376,13 @@
                             }
                         });
                         //session.web.unblockUI();
+=======
+                    ]).then(function(records){
+                        // TDE note: temp deactivation, because this will be fixed in DOM-CHM
+                        // self.parent_thread.switch_new_message(records);
+                        // self.datasets.attachment_ids=[];
+                        // self.on_cancel();
+>>>>>>> MERGE-SOURCE
                     });
                 return true;
             }
@@ -1102,6 +1114,7 @@
             // domain and context: options + additional
             fetch_domain = replace_domain ? replace_domain : this.domain;
             fetch_context = replace_context ? replace_context : this.context;
+<<<<<<< TREE
             var message_loaded_ids = this.id ? [this.id].concat( self.get_child_ids() ) : self.get_child_ids();
 
             // CHM note : option for sending in flat mode by server
@@ -1109,6 +1122,12 @@
 
             return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded_ids, nb_indented_thread, fetch_context, this.context.default_parent_id || undefined])
                 .then(callback ? _.bind(callback, this, arguments) : this.proxy('switch_new_message'));
+=======
+            var message_loaded = [this.datasets.id||0].concat( self.options.thread._parents[0].get_child_ids() );
+
+            return this.ds_message.call('message_read', [ids, fetch_domain, message_loaded, 1, fetch_context, this.context.default_parent_id || undefined]
+                ).then(this.proxy('switch_new_message'));
+>>>>>>> MERGE-SOURCE
         },
 
         /**

=== modified file 'mail/tests/test_mail.py'
=== modified file 'project/project_view.xml'
=== modified file 'project_issue/project_issue_view.xml'
=== modified file 'sale/sale_view.xml'
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to