dijous, 30 de març del 2017

Error a l'enviar un email des de Odoo v9.

Avui he trobat un problema en una instal·lació de Odoo 9 d'un client: en intentar enviar un email (amb el SMTP correctament configurat) dóna l'error:
Failed to render template <Template memory:7f001e0240d0> using values {'format_tz': <function <lambda> at 0x7efff4974f50>, 'ctx': {'record_name': False, u'uid': 1, 'button_access': None, 'thread_model': u'mail.message', 'safe': False, 'actions': [], 'not_followers': res.partner(11065,), u'params': {}, 'button_unfollow': False, u'lang': u'es_ES', 'tracking': [], u'tz': u'Europe/Andorra', u'active_model': u'mail.message', u'default_no_auto_thread': False, 'mail_post_autofollow': True, 'followers': res.partner(), 'company_name': u'XXXX, SL.', 'signature': u'<p><span>--<br></span></p><p></p><p>\nAdministrator</p>', 'button_follow': False, 'model_name': False, 'website_url': u'http://www.xxxx.com'}, 'user': res.users(1,), 'object': mail.message(32735,)}

Buscant una possible solució, he trobat https://groups.google.com/forum/#!topic/openerp-spain-users/cGNMjLRzEJY , on indiquen que el problema es corregeix posant l'idioma anglès... molt estrany, no?

Malhauradament, configurar l'Odoo per a que estigui en anglès no és una solució vàlida en el meu cas.
Afegint missatges de log a l'arxiu "/usr/lib/python2.7/dist-packages/openerp/addons/mail/models/mail_template.py", he vist que usa el següent text com a template:

<div itemscope itemtype="http://schema.org/EmailMessage">
  <div itemprop="potentialAction" itemscope itemtype="http://schema.org/ViewAction">
    % if ctx.get('button_access'):
      <link itemprop="target" href="${ctx['button_access']['url']}"/>
      <link itemprop="url" href="${ctx['button_access']['url']}"/>
    % endif
    <meta itemprop="name" content="Ver ${ctx['model_name']}"/>
  </div>
</div>
<div summary="o_mail_notification" style="padding:0px; width:600px; margin:0 auto; background: #FFFFFF repeat top /100%; color:#777777">
  <table cellspacing="0" cellpadding="0" style="width:600px; border-collapse:collapse; background:inherit; color:inherit">
    <tbody>
      <tr>
        <td valign="center" width="270" style="padding:5px 10px 5px 5px;font-size: 30px">
          % if ctx.get('button_access'):
            <a href="${ctx['button_access']['url']}" style="-webkit-user-select: none; padding: 5px 10px; font-size: 12px; line-height: 18px; color: #FFFFFF; border-color:#a24689; text-decoration: none; display: inline-block; margin-bottom: 0px; font-weight: 400; text-align: center; vertical-align: middle; cursor: pointer; white-space: nowrap; background-image: none; background-color: #a24689; border: 1px solid #a24689; border-radius:3px" class="o_default_snippet_text">
              ${ctx['button_access']['title']}
            </a>
          % endif
          % if ctx.get('button_follow'):
            <a href="${ctx['button_follow']['url']}" style="-webkit-user-select: none; padding: 5px 10px; font-size: 12px; line-height: 18px; color: #FFFFFF; border-color:#a24689; text-decoration: none; display: inline-block; margin-bottom: 0px; font-weight: 400; text-align: center; vertical-align: middle; cursor: pointer; white-space: nowrap; background-image: none; background-color: #a24689; border: 1px solid #a24689; border-radius:3px" class="o_default_snippet_text">
              ${ctx['button_follow']['title']}
            </a>
          % elif ctx.get('button_unfollow'):
            <a href="${ctx['button_unfollow']['url']}" style="-webkit-user-select: none; padding: 5px 10px; font-size: 12px; line-height: 18px; color: #FFFFFF; border-color:#a24689; text-decoration: none; display: inline-block; margin-bottom: 0px; font-weight: 400; text-align: center; vertical-align: middle; cursor: pointer; white-space: nowrap; background-image: none; background-color: #a24689; border: 1px solid #a24689; border-radius:3px" class="o_default_snippet_text">
              ${ctx['button_unfollow']['title']}
            </a>
          % endif
          % if not ctx.get('button_access') and not ctx.get('button_follow') and not ctx.get('button_unfollow') and ctx.get('model_name'):
            <p style="padding: 5px 10px; font-size: 12px;">
              Sobre <strong>${ctx['model_name']} % if ctx.get('record_name'): : ${ctx['record_name']} % endif </strong>
            </p>
          % endif
        </td>
        <td valign="center" align="right" width="270" style="padding:5px 15px 5px 10px; font-size: 12px;">
          <p>
            % if ctx.get('actions'):
              % for action in ctx['actions']:
                <a href="${action['url']}" style="text-decoration:none; color: #a24689;">
                  <strong>${action['title']}</strong>
                </a>
                %if cmp(len(ctx['actions']), 1) == 1 and cmp(len(ctx['actions']), loop.index) == 1:
                  |
                % endif
              % endfor
            % else:
                <strong>Enviado por</strong>
              % if ctx.get('website_url'):
                <a href="${ctx['website_url']}" style="text-decoration:none; color: #a24689;">
              % endif
              <strong>${ctx.get('company_name')}</strong>
              % if ctx.get('website_url'):
                </a>
              % endif
              <strong>usando</strong>
              <a href="https://www.odoo.com" style="text-decoration:none; color: #a24689;">
                <strong>Odoo</strong>
              </a>
            % endif
          </p>
        </td>
      </tr>
    </tbody>
  </table>
</div>
<div style="padding:0px; width:600px; margin:0 auto; background: #FFFFFF repeat top /100%; color:#777777">
  <table cellspacing="0" cellpadding="0" style="vertical-align:top; padding:0px; border-collapse:collapse; background:inherit; color:inherit">
    <tbody>
      <tr>
        <td valign="top" style="width:600px; padding:5px 10px 5px 5px;">
          <div>
            <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0;margin:15px auto;padding:0">
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</div>
<div style="padding:0px; width:600px; margin:0 auto; background: #FFFFFF repeat top /100%;color:#777777">
  <table cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto; width:600px; border-collapse:collapse; background:inherit; color:inherit">
    <tbody>
      <tr>
        <td style="padding:5px 10px 5px 5px;font-size: 14px;">
          ${object.body | safe}
          % if ctx.get('tracking'):
            <ul>
              % for tracking in ctx['tracking']
                <li>${tracking[0]} : ${tracking[1]} -&gt; ${tracking[2]}</li>
              % endfor
            </ul>
          % endif
        </td>
      </tr>
    </tbody>
  </table>
</div>
% if ctx.get('signature'):
  <div style="padding:0px; width:600px;margin:0 auto; background: #FFFFFF repeat top /100%;color:#777777">
    <table cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto; width:600px; border-collapse:collapse; background:inherit; color:inherit">
      <tbody>
        <tr>
          <td style="padding:5px 10px 5px 5px;font-size: 14px; text-align: left;">
            ${ctx['signature'] | safe}
          </td>
        </tr>
      </tbody>
    </table>
  </div>
% endif
Es correspon a la plantilla de mail amb nom "Notification Email". En canviar aquesta plantilla per només:
  ${object.body | safe}

El missatge s'envia correctament, pel que el problema està en el contingut de la plantilla.
L'he eliminat i he anat afegint fragments fins que... misteri! Ha funcionat amb tota la plantilla!

L'única diferència que hi sé veure és que inicialment estava tota en una sola línia, mentre que ara l'he partit tal com es veu més amunt, indentant els tags... Serà problema del buffer de línia?


Precisió decimal en un camp de Odoo (QWeb)

En afegir un camp a un mòdul d'Odoo, el sistema, per defecte, li assigna una precisió (a la vista) de dos decimals. És igual la precisió que tingui a la base de dades, sempre seran dos decimals.
Per a poder-ho modificar, cal indicar-ho al xml de la vista amb un atribut del tipus: digits="(16,7)"
Amb això tindrem que s'accepta un número de fins a 16 posicions, de les quals 7 són decimals.

Un exemple complet de la vista heretada:

<openerp>
    <data>

     <record model="ir.ui.view" id="add_field_partner_tree">
         <field name="name">res.partner.form.inherit</field>  
         <field name="model">res.partner</field>
         <field name="inherit_id" ref="base.view_partner_form"/>
         <field name="arch" type="xml">
           <xpath expr="//field[@name='lang']" position="after"> 
             <field name="descompte_defecte" />
           </xpath>
           <xpath expr="//field[@name='category_id']" position="after"> 
             <field name="factor_preus" digits="(16,7)" />
           </xpath>
         </field>
     </record>

    </data>

</openerp>