[MERGE] forward port of branch 7.0 up to revid 9382 chs@openerp.com-20130823131214...
authorChristophe Simonis <chs@openerp.com>
Fri, 23 Aug 2013 14:31:14 +0000 (16:31 +0200)
committerChristophe Simonis <chs@openerp.com>
Fri, 23 Aug 2013 14:31:14 +0000 (16:31 +0200)
bzr revid: chs@openerp.com-20130823143114-83tdjhbsdes0kydr

14 files changed:
1  2 
addons/account_voucher/account_voucher.py
addons/lunch/lunch.py
addons/lunch/lunch_view.xml
addons/mail/mail_message.py
addons/mail/mail_thread.py
addons/mail/tests/test_mail_gateway.py
addons/mrp/mrp_view.xml
addons/mrp/res_config.py
addons/point_of_sale/point_of_sale.py
addons/project/project.py
addons/sale_stock/sale_stock.py
addons/stock/stock.py
addons/stock/stock_view.xml
addons/stock/wizard/stock_fill_inventory.py

Simple merge
@@@ -7,7 -7,7 +7,7 @@@
          <menuitem name="Administrate Orders" parent="menu_lunch" id="menu_lunch_admin" sequence="51" groups="group_lunch_manager"/>
          <menuitem name="Administrate Cash Moves" parent="menu_lunch" id="menu_lunch_cash" sequence="52" groups="group_lunch_manager"/>
          <menuitem name="Configuration" parent="menu_lunch" id="menu_lunch_config" sequence="53" groups="group_lunch_manager"/>
--        
++
           <!--View Search to group/filter by Supplier and time-->
          <record model="ir.ui.view" id="lunch_order_line_search_view">
              <field name="name">Search</field>
              </field>
          </record>
  
+         <!--view for cashmove-->
+         <record model="ir.ui.view" id="casmove_tree_view">
+             <field name="name">cashmove tree</field>
+             <field name="model">lunch.cashmove</field>
+             <field name="arch" type="xml">
+                 <tree string="cashmove tree">
+                     <field name="date"/>
+                     <field name="user_id"/>
+                     <field name="description"/>
+                     <field name="amount" sum="Total"/>
+                 </tree>
+             </field>
+         </record>
+         <record model="ir.ui.view" id="casmove_form_view">
+             <field name="name">cashmove form</field>
+             <field name="model">lunch.cashmove</field>
+             <field name="arch" type="xml">
+                 <form string="cashmove form" version="7.0">
+                     <sheet>
+                         <group>
 -                            <field name="user_id"/>
++                            <field name="user_id"
++                                   context="{'default_groups_ref': ['base.group_user', 'lunch.group_lunch_user']}"/>
+                             <field name="date"/>
+                             <field name="amount"/>
+                         </group>
+                         <label for='description'/>
+                         <field name="description"/>
+                     </sheet>
+                 </form>
+             </field>
+         </record>
          <!--Action for Your Orders-->
          <record model="ir.actions.act_window" id="action_lunch_order_form">
              <field name="name">New Order</field>
              </field>
          </record>
  
-         <!--view for cashmove-->
-         <record model="ir.ui.view" id="casmove_tree_view">
-             <field name="name">cashmove tree</field>
-             <field name="model">lunch.cashmove</field>
-             <field name="arch" type="xml">
-                 <tree string="cashmove tree">
-                     <field name="date"/>
-                     <field name="user_id"/>
-                     <field name="description"/>
-                     <field name="amount" sum="Total"/>
-                 </tree>
-             </field>
-         </record>
-         <record model="ir.ui.view" id="casmove_form_view">
-             <field name="name">cashmove form</field>
-             <field name="model">lunch.cashmove</field>
-             <field name="arch" type="xml">
-                 <form string="cashmove form" version="7.0">
-                     <sheet>
-                         <group>
-                             <field name="user_id"
-                                 context="{'default_groups_ref': ['base.group_user', 'lunch.group_lunch_user']}"/>
-                             <field name="date"/>
-                             <field name="amount"/>
-                         </group>
-                         <label for='description'/>
-                         <field name="description"/>
-                     </sheet>
-                 </form>
-             </field>
-         </record>
 -        
          <!--view for alerts-->
          <record model="ir.ui.view" id="alert_tree_view">
              <field name="name">alert tree</field>
Simple merge
@@@ -465,20 -420,6 +465,21 @@@ class mail_thread(osv.AbstractModel)
          ir_attachment_obj.unlink(cr, uid, attach_ids, context=context)
          return True
  
 +    def check_mail_message_access(self, cr, uid, mids, operation, model_obj=None, context=None):
 +        """ mail.message check permission rules for related document. This method is
 +            meant to be inherited in order to implement addons-specific behavior.
 +            A common behavior would be to allow creating messages when having read
 +            access rule on the document, for portal document such as issues. """
 +        if not model_obj:
 +            model_obj = self
 +        if operation in ['create', 'write', 'unlink']:
-             model_obj.check_access_rights(cr, uid, 'write')
++            if not model_obj.check_access_rights(cr, uid, 'write', raise_exception=False):
++                model_obj.check_access_rights(cr, uid, 'create')
 +            model_obj.check_access_rule(cr, uid, mids, 'write', context=context)
 +        else:
 +            model_obj.check_access_rights(cr, uid, operation)
 +            model_obj.check_access_rule(cr, uid, mids, operation, context=context)
 +
      #------------------------------------------------------
      # Email specific
      #------------------------------------------------------
@@@ -124,102 -184,24 +185,120 @@@ class TestMailgateway(TestMailBase)
          self.assertEqual(partner_info['partner_id'], p_b_id,
                          'mail_thread: message_find_partner_from_emails wrong partner found')
  
 +    def test_05_mail_message_mail_mail(self):
 +        """ Tests designed for testing email values based on mail.message, aliases, ... """
 +        cr, uid, user_raoul_id = self.cr, self.uid, self.user_raoul_id
 +
 +        # Data: update + generic variables
 +        reply_to1 = '_reply_to1@example.com'
 +        reply_to2 = '_reply_to2@example.com'
 +        email_from1 = 'from@example.com'
 +        alias_domain = 'schlouby.fr'
 +        raoul_from = 'Raoul Grosbedon <raoul@raoul.fr>'
 +        raoul_from_alias = 'Raoul Grosbedon <raoul@schlouby.fr>'
 +        raoul_reply = '"Followers of Pigs" <raoul@raoul.fr>'
 +        raoul_reply_alias = '"Followers of Pigs" <group+pigs@schlouby.fr>'
 +        # Data: remove alias_domain to see emails with alias
 +        param_ids = self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.domain')])
 +        self.registry('ir.config_parameter').unlink(cr, uid, param_ids)
 +
 +        # Do: free message; specified values > default values
 +        msg_id = self.mail_message.create(cr, user_raoul_id, {'reply_to': reply_to1, 'email_from': email_from1})
 +        msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
 +        # Test: message content
 +        self.assertIn('reply_to', msg.message_id,
 +                        'mail_message: message_id should be specific to a mail_message with a given reply_to')
 +        self.assertEqual(msg.reply_to, reply_to1,
 +                        'mail_message: incorrect reply_to: should come from values')
 +        self.assertEqual(msg.email_from, email_from1,
 +                        'mail_message: incorrect email_from: should come from values')
 +        # Do: create a mail_mail with the previous mail_message
 +        mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
 +        mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
 +        # Test: mail_mail content
 +        self.assertEqual(mail.reply_to, reply_to1,
 +                        'mail_mail: incorrect reply_to: should come from mail.message')
 +        self.assertEqual(mail.email_from, email_from1,
 +                        'mail_mail: incorrect email_from: should come from mail.message')
 +        # Do: create a mail_mail with the previous mail_message + specified reply_to
 +        mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel', 'reply_to': reply_to2})
 +        mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
 +        # Test: mail_mail content
 +        self.assertEqual(mail.reply_to, reply_to2,
 +                        'mail_mail: incorrect reply_to: should come from values')
 +        self.assertEqual(mail.email_from, email_from1,
 +                        'mail_mail: incorrect email_from: should come from mail.message')
 +
 +        # Do: mail_message attached to a document
 +        msg_id = self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_pigs_id})
 +        msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
 +        # Test: message content
 +        self.assertIn('mail.group', msg.message_id,
 +                        'mail_message: message_id should contain model')
 +        self.assertIn('%s' % self.group_pigs_id, msg.message_id,
 +                        'mail_message: message_id should contain res_id')
 +        self.assertFalse(msg.reply_to,
 +                        'mail_message: incorrect reply_to: should not be generated if not specified')
 +        self.assertEqual(msg.email_from, raoul_from,
 +                        'mail_message: incorrect email_from: should be Raoul')
 +        # Do: create a mail_mail based on the previous mail_message
 +        mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
 +        mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
 +        # Test: mail_mail content
 +        self.assertEqual(mail.reply_to, raoul_reply,
 +                        'mail_mail: incorrect reply_to: should be Raoul')
 +
 +        # Data: set catchall domain
 +        self.registry('ir.config_parameter').set_param(cr, uid, 'mail.catchall.domain', alias_domain)
 +
 +        # Update message
 +        self.mail_message.write(cr, user_raoul_id, [msg_id], {'email_from': False, 'reply_to': False})
 +        msg.refresh()
 +        # Do: create a mail_mail based on the previous mail_message
 +        mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
 +        mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
 +        # Test: mail_mail content
 +        self.assertEqual(mail.reply_to, raoul_reply_alias,
 +                        'mail_mail: incorrect reply_to: should be Pigs alias')
 +
 +        # Update message: test alias on email_from
 +        msg_id = self.mail_message.create(cr, user_raoul_id, {})
 +        msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
 +        # Do: create a mail_mail based on the previous mail_message
 +        mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
 +        mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
 +        # Test: mail_mail content
 +        self.assertEqual(mail.reply_to, raoul_from_alias,
 +                        'mail_mail: incorrect reply_to: should be message email_from using Raoul alias')
 +
 +        # Update message
 +        self.mail_message.write(cr, user_raoul_id, [msg_id], {'res_id': False, 'email_from': 'someone@schlouby.fr', 'reply_to': False})
 +        msg.refresh()
 +        # Do: create a mail_mail based on the previous mail_message
 +        mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
 +        mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
 +        # Test: mail_mail content
 +        self.assertEqual(mail.reply_to, msg.email_from,
 +                        'mail_mail: incorrect reply_to: should be message email_from')
 +
+     def test_09_message_parse(self):
+         """ Testing incoming emails parsing """
+         cr, uid = self.cr, self.uid
+         res = self.mail_thread.message_parse(cr, uid, MAIL_TEMPLATE_PLAINTEXT)
+         self.assertIn('Please call me as soon as possible this afternoon!', res.get('body', ''),
+                       'message_parse: missing text in text/plain body after parsing')
+         res = self.mail_thread.message_parse(cr, uid, MAIL_TEMPLATE)
+         self.assertIn('<p>Please call me as soon as possible this afternoon!</p>', res.get('body', ''),
+                       'message_parse: missing html in multipart/alternative body after parsing')
+         res = self.mail_thread.message_parse(cr, uid, MAIL_MULTIPART_MIXED)
+         self.assertNotIn('Should create a multipart/mixed: from gmail, *bold*, with attachment', res.get('body', ''),
+                          'message_parse: text version should not be in body after parsing multipart/mixed')
+         self.assertIn('<div dir="ltr">Should create a multipart/mixed: from gmail, <b>bold</b>, with attachment.<br clear="all"><div><br></div>', res.get('body', ''),
+                       'message_parse: html version should be in body after parsing multipart/mixed')
      def test_10_message_process(self):
          """ Testing incoming emails processing. """
          cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
              <field name="name">Bill of Materials</field>
              <field name="domain">[('bom_id','=',False)]</field>
              <field name="res_model">mrp.bom</field>
+             <field name="view_type">tree</field>
          </record>
 -
 +        <record id="act_product_mrp_production" model="ir.actions.act_window">
 +            <field name="context">{'search_default_product_id': [active_id]}</field>
 +            <field name="name">Manufacturing Orders</field>
 +            <field name="res_model">mrp.production</field>
 +            <field name="view_id" ref="mrp_production_tree_view"/>
 +        </record>
          <record model="ir.ui.view" id="product_form_view_bom_button">
              <field name="name">product.product.procurement</field>
              <field name="model">product.product</field>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge