[MERGE] Forward-port of latest 7.0 bugfixes, up to rev. 9459 rev-id: fva@openerp...
authorDenis Ledoux <dle@openerp.com>
Wed, 18 Sep 2013 16:13:05 +0000 (18:13 +0200)
committerDenis Ledoux <dle@openerp.com>
Wed, 18 Sep 2013 16:13:05 +0000 (18:13 +0200)
bzr revid: mat@openerp.com-20130826135110-f9q4p65ds2aholcw
bzr revid: dle@openerp.com-20130828141129-ecxl2vlpb8vw0o9f
bzr revid: dle@openerp.com-20130828162659-n8a0ku9o3h01qaov
bzr revid: dle@openerp.com-20130830094205-q3itwd7x0246d9n6
bzr revid: dle@openerp.com-20130830133604-mfnfbscn5wdk4vi4
bzr revid: dle@openerp.com-20130902131244-v9uh0s8rg4889i7j
bzr revid: mat@openerp.com-20130903134105-68ziuaccreu6rs61
bzr revid: chs@openerp.com-20130906171851-jtfsf4au1k30wwlr
bzr revid: dle@openerp.com-20130909103120-k5oefxgebhyslac3
bzr revid: dle@openerp.com-20130909170047-pbzw4ernvcpivbhh
bzr revid: chs@openerp.com-20130910122113-171osvcukxffxcry
bzr revid: tde@openerp.com-20130912121059-k840pi4rwdzpez8g
bzr revid: dle@openerp.com-20130913085251-p906ci2divy82jur
bzr revid: tde@openerp.com-20130913092546-kzshg1a7sls566l8
bzr revid: mat@openerp.com-20130917122102-drf8fj9lrjj0fvju
bzr revid: mat@openerp.com-20130917161614-w8u2c1ayeb5kxm30
bzr revid: dle@openerp.com-20130918161305-7ep1642nxzyy3vhd

32 files changed:
1  2 
addons/account/account.py
addons/account/account_invoice.py
addons/account/account_invoice_view.xml
addons/account/account_move_line.py
addons/account/account_view.xml
addons/account/wizard/account_financial_report.py
addons/account/wizard/account_invoice_refund.py
addons/account/wizard/account_report_common.py
addons/base_calendar/base_calendar.py
addons/crm/crm.py
addons/crm/crm_lead.py
addons/hr_expense/hr_expense.py
addons/hr_recruitment/hr_recruitment.py
addons/hr_timesheet_sheet/hr_timesheet_sheet.py
addons/l10n_be/wizard/l10n_be_vat_intra.py
addons/l10n_be_coda/wizard/account_coda_import.py
addons/mail/res_users.py
addons/mrp/__openerp__.py
addons/mrp/mrp.py
addons/mrp/mrp_view.xml
addons/point_of_sale/point_of_sale.py
addons/product/pricelist.py
addons/product/product.py
addons/product/product_view.xml
addons/project/project.py
addons/project_mrp/project_mrp.py
addons/purchase/partner.py
addons/sale/sale_view.xml
addons/sale_mrp/sale_mrp.py
addons/stock/stock.py
addons/stock/wizard/stock_change_standard_price.py
addons/stock/wizard/stock_return_picking.py

Simple merge
Simple merge
Simple merge
Simple merge
@@@ -157,9 -159,10 +157,9 @@@ class account_invoice_refund(osv.osv_me
                      for line in movelines:
                          if line.account_id.id == inv.account_id.id:
                              to_reconcile_ids[line.account_id.id] = [line.id]
-                         if type(line.reconcile_id) != osv.orm.browse_null:
-                             reconcile_obj.unlink(cr, uid, line.reconcile_id.id)
+                         if line.reconcile_id:
+                             line.reconcile_id.unlink()
 -                    wf_service.trg_validate(uid, 'account.invoice', \
 -                                        refund.id, 'invoice_open', cr)
 +                    inv_obj.signal_invoice_open(cr, uid, [refund.id])
                      refund = inv_obj.browse(cr, uid, refund_id[0], context=context)
                      for tmpline in  refund.move_id.line_id:
                          if tmpline.account_id.id == inv.account_id.id:
@@@ -588,16 -586,7 +587,8 @@@ property or property parameter.")
          """
          if context is None:
              context = {}
 +
-         for vals in self.browse(cr, uid, ids, context=context):
-             if vals.ref and vals.ref.user_id:
-                 mod_obj = self.pool[vals.ref._name]
-                 res=mod_obj.read(cr,uid,[vals.ref.id],['duration','class'],context)
-                 defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id,'duration':res[0]['duration'],'class':res[0]['class']}
-                 mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
-             self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
-         return True
+         return self.write(cr, uid, ids, {'state': 'accepted'}, context)
  
      def do_decline(self, cr, uid, ids, context=None, *args):
          """
@@@ -124,20 -123,11 +124,20 @@@ class crm_case_section(osv.osv)
          'child_ids': fields.one2many('crm.case.section', 'parent_id', 'Child Teams'),
          'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"),
          'note': fields.text('Description'),
 -        'working_hours': fields.float('Working Hours', digits=(16,2 )),
 +        'working_hours': fields.float('Working Hours', digits=(16, 2)),
          'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'),
-         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
+         'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
                                      help="The email address associated with this team. New emails received will automatically "
                                           "create new leads assigned to the team."),
 +        'open_lead_ids': fields.one2many('crm.lead', 'section_id',
 +            string='Open Leads', readonly=True,
 +            domain=['&', ('type', '!=', 'opportunity'), ('state', 'not in', ['done', 'cancel'])]),
 +        'open_opportunity_ids': fields.one2many('crm.lead', 'section_id',
 +            string='Open Opportunities', readonly=True,
 +            domain=['&', '|', ('type', '=', 'opportunity'), ('type', '=', 'both'), ('state', 'not in', ['done', 'cancel'])]),
 +        'color': fields.integer('Color Index'),
 +        'use_leads': fields.boolean('Leads',
 +            help="This enables the management of leads in the sales team. Otherwise the sales team manages only opportunities."),
      }
  
      def _get_stage_common(self, cr, uid, context):
Simple merge
@@@ -116,7 -105,12 +109,11 @@@ class hr_expense_expense(osv.osv)
      def copy(self, cr, uid, id, default=None, context=None):
          if default is None:
              default = {}
-         default.update(account_move_id=False)
+         default.update(
+             account_move_id=False,
 -            voucher_id=False,
+             date_confirm=False,
+             date_valid=False,
+             user_valid=False)
          return super(hr_expense_expense, self).copy(cr, uid, id, default=default, context=context)
  
      def unlink(self, cr, uid, ids, context=None):
Simple merge
@@@ -77,9 -77,10 +77,10 @@@ Dashboard / Reports for MRP will includ
      #TODO: This yml tests are needed to be completely reviewed again because the product wood panel is removed in product demo as it does not suit for new demo context of computer and consultant company
      # so the ymls are too complex to change at this stage
      'test': [
+          'test/bom_with_service_type_product.yml',
 -#         'test/order_demo.yml',
 -#         'test/order_process.yml',
 -#         'test/cancel_order.yml',
 +         'test/order_demo.yml',
 +         'test/order_process.yml',
 +         'test/cancel_order.yml',
      ],
      'installable': True,
      'application': True,
@@@ -721,6 -731,11 +741,10 @@@ class mrp_production(osv.osv)
          stock_mov_obj = self.pool.get('stock.move')
          production = self.browse(cr, uid, production_id, context=context)
  
 -        wf_service = netsvc.LocalService("workflow")
+         if not production.move_lines and production.state == 'ready':
+             # trigger workflow if not products to consume (eg: services)
 -            wf_service.trg_validate(uid, 'mrp.production', production_id, 'button_produce', cr)
++            self.signal_button_produce(cr, uid, [production_id])
          produced_qty = 0
          for produced_product in production.move_created_ids2:
              if (produced_product.scrapped) or (produced_product.product_id.id != production.product_id.id):
  
      def _get_auto_picking(self, cr, uid, production):
          return True
+     
+     def _hook_create_post_procurement(self, cr, uid, production, procurement_id, context=None):
+         return True
  
      def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None):
 -        wf_service = netsvc.LocalService("workflow")
          procurement_order = self.pool.get('procurement.order')
          production = production_line.production_id
          location_id = production.location_src_id.id
  
              for line in production.product_lines:
                  consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
-                 shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\
+                 if shipment_id:
+                     shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\
                                   destination_location_id=source_location_id, context=context)
-                 self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)
+                     self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)
  
-             self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id])
+             if shipment_id:
 -                wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
++                self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id])
              production.write({'state':'confirmed'}, context=context)
          return shipment_id
  
              <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>
+             <field name="view_type">form</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
@@@ -757,8 -756,9 +762,8 @@@ class product_product(osv.osv)
              context = {}
          if context and context.get('search_default_categ_id', False):
              args.append((('categ_id', 'child_of', context['search_default_categ_id'])))
-         return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False)
+         return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
  
 -product_product()
  
  class product_packaging(osv.osv):
      _name = "product.packaging"
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -2979,26 -2999,28 +2983,38 @@@ class stock_picking_in(osv.osv)
          #override in order to redirect the check of acces rules on the stock.picking object
          return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context)
  
 -    def _workflow_trigger(self, cr, uid, ids, trigger, context=None):
 -        #override in order to trigger the workflow of stock.picking at the end of create, write and unlink operation
 -        #instead of it's own workflow (which is not existing)
 -        return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context)
 +    def create_workflow(self, cr, uid, ids, context=None):
 +        # overridden in order to trigger the workflow of stock.picking at the end of create,
 +        # write and unlink operation instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').create_workflow(cr, uid, ids, context=context)
 +
 +    def delete_workflow(self, cr, uid, ids, context=None):
 +        # overridden in order to trigger the workflow of stock.picking at the end of create,
 +        # write and unlink operation instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').delete_workflow(cr, uid, ids, context=context)
  
 -    def _workflow_signal(self, cr, uid, ids, signal, context=None):
 -        #override in order to fire the workflow signal on given stock.picking workflow instance
 -        #instead of it's own workflow (which is not existing)
 -        return self.pool.get('stock.picking')._workflow_signal(cr, uid, ids, signal, context=context)
 +    def step_workflow(self, cr, uid, ids, context=None):
 +        # overridden in order to trigger the workflow of stock.picking at the end of create,
 +        # write and unlink operation instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').step_workflow(cr, uid, ids, context=context)
 +
 +    def signal_workflow(self, cr, uid, ids, signal, context=None):
 +        # overridden in order to fire the workflow signal on given stock.picking workflow instance
 +        # instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
  
+     def message_post(self, *args, **kwargs):
+         """Post the message on stock.picking to be able to see it in the form view when using the chatter"""
+         return self.pool.get('stock.picking').message_post(*args, **kwargs)
+     def message_subscribe(self, *args, **kwargs):
+         """Send the subscribe action on stock.picking model as it uses _name in request"""
+         return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
+     def message_unsubscribe(self, *args, **kwargs):
+         """Send the unsubscribe action on stock.picking model to match with subscribe"""
+         return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
      _columns = {
          'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
          'state': fields.selection(
@@@ -3040,26 -3062,28 +3056,38 @@@ class stock_picking_out(osv.osv)
          #override in order to redirect the check of acces rules on the stock.picking object
          return self.pool.get('stock.picking').check_access_rule(cr, uid, ids, operation, context=context)
  
 -    def _workflow_trigger(self, cr, uid, ids, trigger, context=None):
 -        #override in order to trigger the workflow of stock.picking at the end of create, write and unlink operation
 -        #instead of it's own workflow (which is not existing)
 -        return self.pool.get('stock.picking')._workflow_trigger(cr, uid, ids, trigger, context=context)
 -
 -    def _workflow_signal(self, cr, uid, ids, signal, context=None):
 -        #override in order to fire the workflow signal on given stock.picking workflow instance
 -        #instead of it's own workflow (which is not existing)
 -        return self.pool.get('stock.picking')._workflow_signal(cr, uid, ids, signal, context=context)
 +    def create_workflow(self, cr, uid, ids, context=None):
 +        # overridden in order to trigger the workflow of stock.picking at the end of create,
 +        # write and unlink operation instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').create_workflow(cr, uid, ids, context=context)
 +
 +    def delete_workflow(self, cr, uid, ids, context=None):
 +        # overridden in order to trigger the workflow of stock.picking at the end of create,
 +        # write and unlink operation instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').delete_workflow(cr, uid, ids, context=context)
 +
 +    def step_workflow(self, cr, uid, ids, context=None):
 +        # overridden in order to trigger the workflow of stock.picking at the end of create,
 +        # write and unlink operation instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').step_workflow(cr, uid, ids, context=context)
 +
 +    def signal_workflow(self, cr, uid, ids, signal, context=None):
 +        # overridden in order to fire the workflow signal on given stock.picking workflow instance
 +        # instead of its own workflow (which is not existing)
 +        return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
  
+     def message_post(self, *args, **kwargs):
+         """Post the message on stock.picking to be able to see it in the form view when using the chatter"""
+         return self.pool.get('stock.picking').message_post(*args, **kwargs)
+     def message_subscribe(self, *args, **kwargs):
+         """Send the subscribe action on stock.picking model as it uses _name in request"""
+         return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
+     def message_unsubscribe(self, *args, **kwargs):
+         """Send the unsubscribe action on stock.picking model to match with subscribe"""
+         return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
      _columns = {
          'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
          'state': fields.selection(