[MERGE] Forward-port saas-3 up to 7273474
authorOlivier Dony <odo@openerp.com>
Fri, 1 Aug 2014 21:14:59 +0000 (23:14 +0200)
committerOlivier Dony <odo@openerp.com>
Fri, 1 Aug 2014 21:14:59 +0000 (23:14 +0200)
1  2 
addons/website/views/website_templates.xml
openerp/osv/orm.py

@@@ -8,27 -8,7 +8,27 @@@
  
  <template id="website.theme" name="Theme">
      <link id="bootstrap_css" rel='stylesheet' href='/web/static/lib/bootstrap/css/bootstrap.css' t-ignore="true"/>
 -    <link id="website_css" rel='stylesheet' href='/website/static/src/css/website.css' t-ignore="true"/>
 +    <link rel="stylesheet" href='/website/static/src/css/website.css' t-ignore="true"/>
 +</template>
 +
 +<template id="website.assets_frontend" name="Website assets">
 +    <t t-call="website.theme"/>
 +
 +    <script type="text/javascript" src="/web/static/src/js/watch.js"></script>
 +
 +    <script type="text/javascript" src="/website/static/src/js/website.js"></script>
 +
 +    <script type="text/javascript" src="/website/static/src/js/website.snippets.animation.js"></script>
 +    <script type="text/javascript" src="/web/static/lib/bootstrap/js/bootstrap.js"></script>
 +
 +</template>
 +
 +<template id="assets_backend" name="website assets for backend" inherit_id="web.assets_backend">
 +    <xpath expr="." position="inside">
 +        <link rel="stylesheet" href="/website/static/src/css/website.backend.css"/>
 +
 +        <script type="text/javascript" src="/website/static/src/js/website.backend.js"></script>
 +    </xpath>
  </template>
  
  <template id="website.submenu" name="Submenu">
@@@ -65,6 -45,7 +65,6 @@@
            t-att-data-oe-company-name="res_company.name">
          <head>
              <meta charset="utf-8" />
 -            <script type="text/javascript" src="/web/static/src/js/watch.js"></script>
              <t t-if="main_object and 'website_meta_title' in main_object">
                  <t t-set="title" t-value="main_object.website_meta_title"/>
              </t>
                  and main_object.website_meta_keywords or website_meta_keywords"/>
              <title><t t-esc="title"/></title>
  
 -            <!-- Load stylesheets before scripts to avoid blocking -->
 -            <link rel='stylesheet' href='/web/static/lib/fontawesome/css/font-awesome.css'/>
 -
 -            <t t-call="website.theme"/>
 -
 -            <script type="text/javascript" src="/web/static/lib/es5-shim/es5-shim.min.js"></script>
 -            <script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
 -            <script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script>
 -            <script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script>
 -            <script type="text/javascript" src="/web/static/lib/jquery.form/jquery.form.js"></script>
 -            <script type="text/javascript">
 -                // Bootstrap and jQuery UI conflicts
 -                $.fn.bstooltip = $.fn.tooltip;
 -                $.fn.bsbutton = $.fn.button;
 -            </script>
 -
 -            <script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
 -            <script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script>
 -
 -            <script type="text/javascript" src="/website/static/src/js/website.js"></script>
 +            <t t-set="languages" t-value="website.get_languages()"/>
 +            <t t-if="request.website_multilang">
 +                <t t-foreach="languages" t-as="lg">
 +                    <t t-set="force_lang" t-value="lg[0] if lg[0] != website.default_lang_code else None"/>
 +                    <link rel="alternate" t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=force_lang)" t-att-hreflang="lg[0].replace('_', '-').lower()" />
 +                </t>
 +            </t>
  
 -            <script t-if="not translatable" type="text/javascript" src="/website/static/src/js/website.snippets.animation.js"></script>
 -            <script type="text/javascript" src="/web/static/lib/bootstrap/js/bootstrap.js"></script>
 +            <t t-call-assets="web.assets_common"/>
 +            <t t-call-assets="website.assets_frontend"/>
  
              <t t-raw="head or ''" name='layout_head'/>
 +            <t t-if="website.google_analytics_key">
 +                <script>
 +                    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
 +                    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
 +                    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
 +                    })(window,document,'script','//www.google-analytics.com/analytics.js','_gaw');
 +
 +                    _gaw('create',_.str.trim('<t t-esc="website.google_analytics_key"/>'));
 +                    _gaw('send','pageview');
 +                </script>
 +            </t>
          </head>
          <body>
              <div id="wrapwrap">
                                          their performance.
                                      </p>
                                  </div>
 -                                <t t-set="languages" t-value="website.get_languages()"/>
 -                                <ul class="list-inline js_language_selector mt16" t-if="(len(languages) &gt; 1 or editable)">
 +                                <ul class="list-inline js_language_selector mt16" t-if="(request.website_multilang and len(languages) &gt; 1) or editable">
                                      <li t-foreach="languages" t-as="lg">
 -                                        <a t-att-href="url_for('', lang=lg[0]) + '?' + keep_query()"
 +                                        <a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang=lg[0])"
                                             t-att-data-default-lang="editable and 'true' if lg[0] == website.default_lang_code else None">
                                              <t t-esc="lg[1].split('/').pop()"/>
                                          </a>
                      </div>
                      <div class="container mt16 mb8">
                          <div class="pull-right" t-ignore="true" t-if="not editable">
-                             Create a <a href="http://openerp.com/apps/website">free website</a> with
-                             <a class="label label-danger" href="https://openerp.com/apps/website">OpenERP</a>
+                             Create a <a href="http://www.odoo.com/page/website-builder">free website</a> with
+                             <a class="label label-danger" href="http://www.odoo.com/page/website-builder">Odoo</a>
                          </div>
                          <div class="pull-left text-muted">
                              Copyright &amp;copy; <span t-field="res_company.name">Company name</span>
                      </div>
                  </footer>
              </div>
 -            <t t-if="website.google_analytics_key">
 -                <script>
 -                    (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
 -                    function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
 -                    e=o.createElement(i);r=o.getElementsByTagName(i)[0];
 -                    e.src='//www.google-analytics.com/analytics.js';
 -                    r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
 -                    ga('create',_.str.trim('<t t-esc="website.google_analytics_key"/>'));
 -                    ga('send','pageview');
 -                </script>
 -            </t>
          </body>
      </html>
  </template>
  
 -<template id="layout_logo_show" inherit_id="website.layout" inherit_option_id="website.layout" name="Show Logo">
 +<template id="layout_logo_show" inherit_id="website.layout" optional="enabled" name="Show Logo">
      <xpath expr="//header//a[@class='navbar-brand']" position="replace">
          <a href="/" class="navbar-brand logo">
              <img src="/logo.png"/>
      </xpath>
  </template>
  
 -<template id="editor_head" inherit_id="website.layout" name="Editor" groups="base.group_website_publisher">
 +<template id="editor_head" inherit_id="website.layout" name="Editor" groups="base.group_website_publisher,base.group_website_designer">
      <xpath expr="//body" position="attributes">
          <attribute name="style">padding-top: 51px;</attribute>
      </xpath>
              </div>
          </div>
      </xpath>
 -    <xpath expr='//script[@src="/web/static/lib/bootstrap/js/bootstrap.js"]' position="before">
 -        <link rel='stylesheet' href='/website/static/src/css/snippets.css'/>
 -        <link rel='stylesheet' href='/website/static/src/css/editor.css'/>
 -        <link rel='stylesheet' href='/website/static/lib/bootstrap-tour/bootstrap-tour.css'/>
 +    <xpath expr='//t[@t-call-assets="website.assets_frontend"]' position="after">
 +        <t t-call-assets="website.assets_editor"/>
 +    </xpath>
 +</template>
  
 +<template id="assets_editor" name="Editor assets">
 +    <script type="text/javascript">
 +        var CKEDITOR_BASEPATH = '/web/static/lib/ckeditor/';
 +    </script>
 +    <link rel='stylesheet' href='/website/static/src/css/snippets.css'/>
 +    <link rel='stylesheet' href='/website/static/src/css/editor.css'/>
  
 -        <link rel="stylesheet" href="/web/static/lib/select2/select2.css"/>
 -        <link rel="stylesheet" href="/website/static/lib/select2-bootstrap-css/select2-bootstrap.css"/>
 -        <link rel='stylesheet' href="/web/static/lib/jquery.ui/css/smoothness/jquery-ui-1.9.1.custom.css"/>
 +    <link rel='stylesheet' href="/web/static/lib/jquery.ui/css/smoothness/jquery-ui-1.9.1.custom.css"/>
  
 -        <script type="text/javascript" src="/web/static/lib/select2/select2.js"></script>
 -        <script type="text/javascript" src="/web/static/lib/ckeditor/ckeditor.js"></script>
 -        <script t-if="not translatable" type="text/javascript" src="/website/static/lib/ace/ace.js"></script>
 -        <script type="text/javascript" src="/website/static/lib/vkbeautify/vkbeautify.0.99.00.beta.js"></script>
 -        <script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script>
 -        <script type="text/javascript" src="/website/static/lib/bootstrap-tour/bootstrap-tour.js"></script>
 -        <!-- mutation observers shim backed by mutation events (8 < IE < 11, Safari < 6, FF < 14, Chrome < 17) -->
 -        <script type="text/javascript" src="/website/static/lib//jquery.mjs.nestedSortable/jquery.mjs.nestedSortable.js"></script>
 -        <script type="text/javascript" src="/website/static/lib/MutationObservers/test/sidetable.js"></script>
 -        <script type="text/javascript" src='/website/static/lib/nearest/jquery.nearest.js'></script>
 -        <script type="text/javascript" src="/website/static/lib/MutationObservers/MutationObserver.js"></script>
 +    <link rel="stylesheet" href="/web/static/lib/select2/select2.css"/>
 +    <link rel="stylesheet" href="/website/static/lib/select2-bootstrap-css/select2-bootstrap.css"/>
  
 -        <script type="text/javascript" src="/website/static/lib/jquery.placeholder/jquery.placeholder.js"></script>
 +    <script type="text/javascript" src="/web/static/lib/select2/select2.js"></script>
  
 -        <script type="text/javascript" src="/website/static/src/js/website.editor.js"></script>
 -        <script type="text/javascript" src="/website/static/src/js/website.editor.newpage.js" groups="base.group_website_designer"></script>
 -        <script type="text/javascript" src="/website/static/src/js/website.menu.js" groups="base.group_website_designer"></script>
 -        <script type="text/javascript" src="/website/static/src/js/website.mobile.js"></script>
 -        <script type="text/javascript" src="/website/static/src/js/website.seo.js"></script>
 -        <script type="text/javascript" id="website_tour_js" src="/website/static/src/js/website.tour.js"></script>
 -        <script type="text/javascript" src="/website/static/src/js/website.tour.banner.js" groups="base.group_website_designer"></script>
 -        <script t-if="not translatable" type="text/javascript" src="/website/static/src/js/website.snippets.editor.js"></script>
 -        <script t-if="not translatable" type="text/javascript" src="/website/static/src/js/website.ace.js"></script>
 -        <script t-if="translatable" type="text/javascript" src="/website/static/src/js/website.translator.js"></script>
 +    <script type="text/javascript" src="/web/static/lib/ckeditor/ckeditor.js"></script>
 +    <script type="text/javascript" src="/website/static/lib/ace/ace.js"></script>
 +    <script type="text/javascript" src="/website/static/lib/ace/theme-monokai.js"></script>
 +    <script type="text/javascript" src="/website/static/lib/ace/mode-xml.js"></script>
 +    <script type="text/javascript" src="/website/static/lib/vkbeautify/vkbeautify.0.99.00.beta.js"></script>
 +    <t t-call="web.jqueryui_conflict">
 +        <script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script>
 +    </t>
 +    <!-- mutation observers shim backed by mutation events (8 < IE < 11, Safari < 6, FF < 14, Chrome < 17) -->
 +    <script type="text/javascript" src="/website/static/lib//jquery.mjs.nestedSortable/jquery.mjs.nestedSortable.js"></script>
 +    <script type="text/javascript" src="/website/static/lib/MutationObservers/test/sidetable.js"></script>
 +    <script type="text/javascript" src='/website/static/lib/nearest/jquery.nearest.js'></script>
 +    <script type="text/javascript" src="/website/static/lib/MutationObservers/MutationObserver.js"></script>
  
 -        <script type="text/javascript" src="/website/static/src/js/jQuery.transfo.js"></script>
 -    </xpath>
 +    <script type="text/javascript" src="/website/static/src/js/website.editor.js"></script>
 +    <script type="text/javascript" src="/website/static/src/js/website.editor.newpage.js"></script> <!-- groups="base.group_website_designer" -->
 +    <script type="text/javascript" src="/website/static/src/js/website.menu.js"></script> <!-- groups="base.group_website_designer" -->
 +    <script type="text/javascript" src="/website/static/src/js/website.mobile.js"></script>
 +    <script type="text/javascript" src="/website/static/src/js/website.seo.js"></script>
 +    <script type="text/javascript" src="/website/static/src/js/website.tour.js"></script>
 +    <script type="text/javascript" src="/website/static/src/js/website.tour.banner.js"></script> <!-- groups="base.group_website_designer" -->
 +    <script type="text/javascript" src="/website/static/src/js/website.snippets.editor.js"></script>
 +    <script type="text/javascript" src="/website/static/src/js/website.ace.js"></script>
 +    <script type="text/javascript" src="/website/static/src/js/website.translator.js"></script>
 +
 +    <script type="text/javascript" src="/website/static/src/js/jQuery.transfo.js"></script>
  </template>
  
 -<template id="debugger" inherit_option_id="website.layout" name="Debugger &amp; Tests">
 +<template id="debugger" inherit_id="website.layout" optional="disabled" name="Debugger &amp; Tests">
      <xpath expr='//t[@name="layout_head"]' position="after">
          <t t-set="debugger_hook" t-value="1" />
      </xpath>
      </xpath>
  </template>
  
 -<template id="show_sign_in" inherit_option_id="website.layout" inherit_id="website.layout" name="Show Sign In" groups="base.group_public">
 +<template id="show_sign_in" optional="enabled" inherit_id="website.layout" name="Show Sign In" groups="base.group_public">
      <xpath expr="//ul[@id='top_menu']" position="inside">
          <li class="divider"/>
          <li>
      </xpath>
  </template>
  
 -<template id="footer_custom" inherit_option_id="website.layout" name="Custom Footer">
 +<template id="footer_custom" inherit_id="website.layout" optional="disabled" name="Custom Footer">
      <xpath expr="//div[@id='footer_container']" position="before">
          <div class="oe_structure">
              <section data-snippet-id='three-columns' class="mt16 mb16">
diff --combined openerp/osv/orm.py
@@@ -672,11 -672,11 +672,11 @@@ class BaseModel(object)
  
      OpenERP models are created by inheriting from this class' subclasses:
  
 -        * Model: for regular database-persisted models
 -        * TransientModel: for temporary data, stored in the database but automatically
 -                          vaccuumed every so often
 -        * AbstractModel: for abstract super classes meant to be shared by multiple
 -                        _inheriting classes (usually Models or TransientModels)
 +    * Model: for regular database-persisted models
 +    * TransientModel: for temporary data, stored in the database but automatically
 +                      vaccuumed every so often
 +    * AbstractModel: for abstract super classes meant to be shared by multiple
 +                     _inheriting classes (usually Models or TransientModels)
  
      The system will later instantiate the class once per database (on
      which the class' module is installed).
      _all_columns = {}
  
      _table = None
 -    _invalids = set()
      _log_create = False
      _sql_constraints = []
      _protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists']
                  # Failed to write, log to messages, rollback savepoint (to
                  # avoid broken transaction) and keep going
                  cr.execute('ROLLBACK TO SAVEPOINT model_load_save')
+             except Exception, e:
+                 message = (_('Unknown error during import:') +
+                            u' %s: %s' % (type(e), unicode(e)))
+                 moreinfo = _('Resolve other errors first')
+                 messages.append(dict(info, type='error',
+                                      message=message,
+                                      moreinfo=moreinfo))
+                 # Failed for some reason, perhaps due to invalid data supplied,
+                 # rollback savepoint and keep going
+                 cr.execute('ROLLBACK TO SAVEPOINT model_load_save')
          if any(message['type'] == 'error' for message in messages):
              cr.execute('ROLLBACK TO SAVEPOINT model_load')
              ids = False
  
              yield dbid, xid, converted, dict(extras, record=stream.index)
  
 -    def get_invalid_fields(self, cr, uid):
 -        return list(self._invalids)
 -
      def _validate(self, cr, uid, ids, context=None):
          context = context or {}
          lng = context.get('lang')
                  # Check presence of __call__ directly instead of using
                  # callable() because it will be deprecated as of Python 3.0
                  if hasattr(msg, '__call__'):
 -                    tmp_msg = msg(self, cr, uid, ids, context=context)
 -                    if isinstance(tmp_msg, tuple):
 -                        tmp_msg, params = tmp_msg
 -                        translated_msg = tmp_msg % params
 -                    else:
 -                        translated_msg = tmp_msg
 +                    translated_msg = msg(self, cr, uid, ids, context=context)
 +                    if isinstance(translated_msg, tuple):
 +                        translated_msg = translated_msg[0] % translated_msg[1]
                  else:
                      translated_msg = trans._get_source(cr, uid, self._name, 'constraint', lng, msg)
                  if extra_error:
                  error_msgs.append(
                          _("The field(s) `%s` failed against a constraint: %s") % (', '.join(fields), translated_msg)
                  )
 -                self._invalids.update(fields)
          if error_msgs:
              raise except_orm('ValidateError', '\n'.join(error_msgs))
 -        else:
 -            self._invalids.clear()
  
      def default_get(self, cr, uid, fields_list, context=None):
          """
              self._transient_vacuum(cr, user)
  
          self.check_access_rights(cr, user, 'create')
 -        
 +
+         vals = self._add_missing_default_values(cr, user, vals, context)
          if self._log_access:
              for f in LOG_ACCESS_COLUMNS:
                  if vals.pop(f, None) is not None:
                      _logger.warning(
                          'Field `%s` is not allowed when creating the model `%s`.',
                          f, self._name)
-         vals = self._add_missing_default_values(cr, user, vals, context)
  
          tocreate = {}
          for v in self._inherits:
@@@ -5225,7 -5246,7 +5236,7 @@@ def convert_pgerror_23502(model, fields
      m = re.match(r'^null value in column "(?P<field>\w+)" violates '
                   r'not-null constraint\n',
                   str(e))
 -    field_name = m.group('field')
 +    field_name = m and m.group('field')
      if not m or field_name not in fields:
          return {'message': unicode(e)}
      message = _(u"Missing required value for the field '%s'.") % field_name
  def convert_pgerror_23505(model, fields, info, e):
      m = re.match(r'^duplicate key (?P<field>\w+) violates unique constraint',
                   str(e))
 -    field_name = m.group('field')
 +    field_name = m and m.group('field')
      if not m or field_name not in fields:
          return {'message': unicode(e)}
      message = _(u"The value for the field '%s' already exists.") % field_name