[MERGE] forward port of branch saas-4 up to 5087612
authorChristophe Simonis <chs@odoo.com>
Thu, 19 Jun 2014 14:13:35 +0000 (16:13 +0200)
committerChristophe Simonis <chs@odoo.com>
Thu, 19 Jun 2014 14:13:35 +0000 (16:13 +0200)
23 files changed:
1  2 
addons/account/account_invoice.py
addons/account_analytic_analysis/account_analytic_analysis.py
addons/auth_oauth/controllers/main.py
addons/gamification/models/challenge.py
addons/google_calendar/google_calendar.py
addons/hr/hr_view.xml
addons/hr_holidays/hr_holidays.py
addons/mail/mail_thread.py
addons/mrp/mrp.py
addons/project/project_demo.xml
addons/web/static/src/css/base.css
addons/web/static/src/css/base.sass
addons/web/static/src/js/view_form.js
addons/web_calendar/static/src/js/web_calendar.js
addons/website/static/src/js/website.editor.js
addons/website_forum/controllers/main.py
addons/website_forum/static/src/js/website_forum.js
addons/website_mail/controllers/main.py
addons/website_mail/views/website_mail.xml
addons/website_mail_group/views/snippets.xml
addons/website_sale/controllers/main.py
openerp/addons/base/ir/ir_actions.py
openerp/osv/orm.py

Simple merge
@@@ -746,29 -746,32 +746,32 @@@ class account_analytic_account(osv.osv)
              contract_ids = ids
          else:
              contract_ids = self.search(cr, uid, [('recurring_next_date','<=', current_date), ('state','=', 'open'), ('recurring_invoices','=', True), ('type', '=', 'contract')])
-         for contract in self.browse(cr, uid, contract_ids, context=context):
-             try:
-                 invoice_values = self._prepare_invoice(cr, uid, contract, context=context)
-                 invoice_ids.append(self.pool['account.invoice'].create(cr, uid, invoice_values, context=context))
-                 next_date = datetime.datetime.strptime(contract.recurring_next_date or current_date, "%Y-%m-%d")
-                 interval = contract.recurring_interval
-                 if contract.recurring_rule_type == 'daily':
-                     new_date = next_date+relativedelta(days=+interval)
-                 elif contract.recurring_rule_type == 'weekly':
-                     new_date = next_date+relativedelta(weeks=+interval)
-                 elif contract.recurring_rule_type == 'monthly':
-                     new_date = next_date+relativedelta(months=+interval)
-                 else:
-                     new_date = next_date+relativedelta(years=+interval)
-                 self.write(cr, uid, [contract.id], {'recurring_next_date': new_date.strftime('%Y-%m-%d')}, context=context)
-                 if automatic:
-                     cr.commit()
-             except Exception:
-                 if automatic:
-                     cr.rollback()
-                     _logger.error(traceback.format_exc())
-                 else:
-                     raise
+         if contract_ids:
+             cr.execute('SELECT company_id, array_agg(id) as ids FROM account_analytic_account WHERE id IN %s GROUP BY company_id', (tuple(contract_ids),))
+             for company_id, ids in cr.fetchall():
+                 for contract in self.browse(cr, uid, ids, context=dict(context, company_id=company_id, force_company=company_id)):
+                     try:
+                         invoice_values = self._prepare_invoice(cr, uid, contract, context=context)
+                         invoice_ids.append(self.pool['account.invoice'].create(cr, uid, invoice_values, context=context))
+                         next_date = datetime.datetime.strptime(contract.recurring_next_date or current_date, "%Y-%m-%d")
+                         interval = contract.recurring_interval
+                         if contract.recurring_rule_type == 'daily':
+                             new_date = next_date+relativedelta(days=+interval)
+                         elif contract.recurring_rule_type == 'weekly':
+                             new_date = next_date+relativedelta(weeks=+interval)
 -                        elif contract.recurring_rule_type == 'yearly':
 -                            new_date = next_date+relativedelta(years=+interval)
 -                        else:
++                        elif contract.recurring_rule_type == 'monthly':
+                             new_date = next_date+relativedelta(months=+interval)
++                        else:
++                            new_date = next_date+relativedelta(years=+interval)
+                         self.write(cr, uid, [contract.id], {'recurring_next_date': new_date.strftime('%Y-%m-%d')}, context=context)
+                         if automatic:
+                             cr.commit()
+                     except Exception:
+                         if automatic:
+                             cr.rollback()
+                             _logger.exception('Fail to create recurring invoice for contract %s', contract.code)
+                         else:
+                             raise
          return invoice_ids
  
  class account_analytic_account_summary_user(osv.osv):
@@@ -74,7 -70,7 +74,7 @@@ class OAuthLogin(Home)
          state = dict(
              d=request.session.db,
              p=provider['id'],
-             r=redirect,
 -            r=werkzeug.url_quote_plus(request.httprequest.full_path)
++            r=werkzeug.url_quote_plus(redirect),
          )
          token = request.params.get('token')
          if token:
@@@ -143,9 -139,10 +143,9 @@@ class OAuthController(http.Controller)
                  cr.commit()
                  action = state.get('a')
                  menu = state.get('m')
-                 redirect = state.get('r')
+                 redirect = werkzeug.url_unquote_plus(state['r']) if state.get('r') else False
                  url = '/web'
 -                if redirect and not redirect.startswith('/auth_oauth/signin') and \
 -                (not redirect.startswith('/web/login') or 'redirect' in urlparse.urlsplit(redirect).query):
 +                if redirect:
                      url = redirect
                  elif action:
                      url = '/web#action=%s' % action
@@@ -786,22 -615,24 +786,23 @@@ class google_calendar(osv.AbstractModel
                      if actSrc == 'OE':
                          self.delete_an_event(cr, uid, current_event[0], context=context)
                      elif actSrc == 'GG':
-                         new_google_event_id = event.GG.event['id'].split('_')[1]
 -                            new_google_event_id = event.GG.event['id'].rsplit('_', 1)[1]
 -                            if 'T' in new_google_event_id:
 -                                new_google_event_id = new_google_event_id.replace('T', '')[:-1]
 -                            else:
 -                                new_google_event_id = new_google_event_id + "000000"
 -
 -                                if event.GG.status:
 -                                    parent_event = {}
 -                                    if event_to_synchronize[base_event][0][1].OE.event_id:
 -                                        parent_event['id'] = "%s-%s" % (event_to_synchronize[base_event][0][1].OE.event_id, new_google_event_id)
 -                                    else:
 -                                        main_ev = att_obj.search_read(cr, uid, [('google_internal_event_id', '=', event.GG.event['id'].rsplit('_', 1)[0])], fields=['event_id'], context=context)
 -                                        parent_event['id'] = "%s-%s" % (main_ev[0].get('event_id')[0], new_google_event_id)
 -                                    res = self.update_from_google(cr, uid, parent_event, event.GG.event, "copy", context)
 -                                else:
 -                                    if event_to_synchronize[base_event][0][1].OE.event_id:
 -                                        parent_oe_id = event_to_synchronize[base_event][0][1].OE.event_id
 -                                        calendar_event.unlink(cr, uid, "%s-%s" % (parent_oe_id, new_google_event_id), unlink_level=1, context=context)
++                        new_google_event_id = event.GG.event['id'].rsplit('_', 1)[1]
 +                        if 'T' in new_google_event_id:
 +                            new_google_event_id = new_google_event_id.replace('T', '')[:-1]
 +                        else:
 +                            new_google_event_id = new_google_event_id + "000000"
 +
 +                        if event.GG.status:
 +                            parent_event = {}
 +                            if not event_to_synchronize[base_event][0][1].OE.event_id:
-                                 event_to_synchronize[base_event][0][1].OE.event_id = att_obj.search_read(cr, uid, [('google_internal_event_id', '=', event.GG.event['id'].split('_')[0])], ['event_id'], context=context_novirtual)[0].get('event_id')[0]
++                                main_ev = att_obj.search_read(cr, uid, [('google_internal_event_id', '=', event.GG.event['id'].rsplit('_', 1)[0])], fields=['event_id'], context=context_novirtual)
++                                event_to_synchronize[base_event][0][1].OE.event_id = main_ev[0].get('event_id')[0]
 +
 +                            parent_event['id'] = "%s-%s" % (event_to_synchronize[base_event][0][1].OE.event_id, new_google_event_id)
 +                            res = self.update_from_google(cr, uid, parent_event, event.GG.event, "copy", context)
 +                        else:
 +                            parent_oe_id = event_to_synchronize[base_event][0][1].OE.event_id
 +                            calendar_event.unlink(cr, uid, "%s-%s" % (parent_oe_id, new_google_event_id), can_be_deleted=True, context=context)
  
                  elif isinstance(actToDo, Delete):
                      if actSrc == 'GG':
Simple merge
Simple merge
Simple merge
@@@ -1044,36 -1004,19 +1044,36 @@@ class mrp_production(osv.osv)
              'location_id': source_location_id,
              'location_dest_id': destination_location_id,
              'move_dest_id': production.move_prod_id.id,
 -            'state': 'waiting',
              'company_id': production.company_id.id,
 +            'production_id': production.id,
 +            'origin': production.name,
          }
          move_id = stock_move.create(cr, uid, data, context=context)
 -        production.write({'move_created_ids': [(6, 0, [move_id])]}, context=context)
 -        return move_id
 +        #a phantom bom cannot be used in mrp order so it's ok to assume the list returned by action_confirm
 +        #is 1 element long, so we can take the first.
 +        return stock_move.action_confirm(cr, uid, [move_id], context=context)[0]
  
 -    def _make_production_consume_line(self, cr, uid, production_line, parent_move_id, source_location_id=False, context=None):
 +    def _get_raw_material_procure_method(self, cr, uid, product, context=None):
 +        '''This method returns the procure_method to use when creating the stock move for the production raw materials'''
 +        try:
 +            mto_route = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'route_warehouse0_mto')[1]
 +        except:
 +            return "make_to_stock"
 +        routes = product.route_ids + product.categ_id.total_route_ids
 +        if mto_route in [x.id for x in routes]:
 +            return "make_to_order"
 +        return "make_to_stock"
 +
 +    def _make_consume_line_from_data(self, cr, uid, production, product, uom_id, qty, uos_id, uos_qty, context=None):
          stock_move = self.pool.get('stock.move')
 -        production = production_line.production_id
          # Internal shipment is created for Stockable and Consumer Products
 -        if production_line.product_id.type not in ('product', 'consu'):
 +        if product.type not in ('product', 'consu'):
              return False
 +        # Take routing location as a Source Location.
 +        source_location_id = production.location_src_id.id
-         if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
-             source_location_id = production.bom_id.routing_id.location_id.id
++        if production.routing_id and production.routing_id.location_id:
++            source_location_id = production.routing_id.location_id.id
 +
          destination_location_id = production.product_id.property_stock_production.id
          if not source_location_id:
              source_location_id = production.location_src_id.id
Simple merge
Simple merge
Simple merge
Simple merge
                      }
                  );
              });
-             menu.on('click', 'a[data-action!=ace]', function (event) {
+             menu.on('click', 'a[data-view-id]', function (event) {
                  var view_id = $(event.currentTarget).data('view-id');
 -                openerp.jsonRpc('/website/customize_template_toggle', 'call', {
 -                    'view_id': view_id
 +                return openerp.jsonRpc('/web/dataset/call_kw', 'call', {
 +                    model: 'ir.ui.view',
 +                    method: 'toggle',
 +                    args: [],
 +                    kwargs: {
 +                        ids: [parseInt(view_id, 10)],
 +                        context: website.get_context()
 +                    }
                  }).then( function() {
                      window.location.reload();
                  });
@@@ -19,8 -19,9 +19,9 @@@
      </div>
  </template>
  
 -<template id="head" inherit_id="website.layout" name="Mail customization">
 -    <xpath expr="//head" position="inside">
 +<template id="head" inherit_id="website.assets_frontend" name="Mail customization">
 +    <xpath expr="/t" position="inside">
+         <script type="text/javascript" src="/website_mail/static/src/js/follow.js"></script>
          <link rel='stylesheet' href='/website_mail/static/src/css/website_mail.css'/>
      </xpath>
  </template>
Simple merge
Simple merge