From dc18056fd01848c51a8dfe83f22bcc268aaefea4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mois=C3=A9s=20L=C3=B3pez?= <moylop260@vauxoo.com>
Date: Tue, 16 Aug 2016 01:31:06 +0000
Subject: [PATCH] [IMP] tools: support known "falsy" string values for XML
 boolean fields

Historically, developers had to use the `eval` attribute to set
a False value for boolean fields in XML data files:

    <field name="active" eval="False"/>

This is a source of errors for beginners, who tend to provide
a string value directly, as for char/text fields.
Unfortunately string values always evaluated to `True` booleans:

    <field name="active">False</field> <!-- active == true! -->

This patch adds detection of some well-known falsy strings
(case-insensitive): `0`, `false`, `off`, as similarly supported
for the `noupdate` and `forcecreate` attributes of XML data records.

Closes #13152
---
 openerp/tools/convert.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py
index 6827ad68fcf7..e711e3828e35 100644
--- a/openerp/tools/convert.py
+++ b/openerp/tools/convert.py
@@ -195,6 +195,11 @@ def _eval_xml(self, node, env):
     elif node.tag == "test":
         return node.text
 
+
+def str2bool(value):
+    return value.lower() not in ('0', 'false', 'off')
+
+
 class xml_import(object):
 
     @staticmethod
@@ -204,7 +209,7 @@ class xml_import(object):
         val = node.get(attr).strip()
         if not val:
             return default
-        return val.lower() not in ('0', 'false', 'off')
+        return str2bool(val)
 
     def isnoupdate(self, data_node=None):
         return self.noupdate or (len(data_node) and self.nodeattr2bool(data_node, 'noupdate', False))
@@ -701,6 +706,8 @@ form: module.record_id""" % (xml_id,)
                         f_val = int(f_val)
                     elif model._fields[f_name].type in ['float', 'monetary']:
                         f_val = float(f_val)
+                    elif model._fields[f_name].type == 'boolean' and isinstance(f_val, basestring):
+                        f_val = str2bool(f_val)
             res[f_name] = f_val
 
         id = self.env(context=rec_context)['ir.model.data']._update(rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode)
-- 
GitLab