diff --git a/admin_technical_features/__openerp__.py b/admin_technical_features/__openerp__.py index dff69e01f96..15738547a5a 100644 --- a/admin_technical_features/__openerp__.py +++ b/admin_technical_features/__openerp__.py @@ -22,7 +22,7 @@ { 'name': 'Admin Technical Features', - 'version': '8.0.0.1.0', + 'version': '9.0.0.1.0', 'author': "Savoir-faire Linux,Odoo Community Association (OCA)", 'maintainer': 'Savoir-faire Linux', 'website': 'http://www.savoirfairelinux.com', @@ -38,5 +38,5 @@ ], 'demo': [], 'test': [], - 'installable': False, + 'installable': True, } diff --git a/module_prototyper/README.rst b/module_prototyper/README.rst index 4c890aa146a..2f00607ce92 100644 --- a/module_prototyper/README.rst +++ b/module_prototyper/README.rst @@ -6,8 +6,8 @@ Module Prototyper ================= -This module allows the administrator to prototype new features and export them as module. -Functional people can prepare the job for a developer who is left with the logic to implement +This module allows the administrator to prototype new features and export them as module. +Functional people can prepare the job for a developer who is left with the logic to implement in addition to everything the prototype does not export yet. Installation @@ -45,13 +45,13 @@ and create a new prototype: * in the Security tab, select your groups, access rights and record rules * save and click on export -You will get a zip file containing your module ready to be installed and compliant with the -conventions of the OCA. You can then provide the module to a developer who have to implement +You will get a zip file containing your module ready to be installed and compliant with the +conventions of the OCA. You can then provide the module to a developer who have to implement things like default values or onchange methods. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/149/8.0 + :target: https://runbot.odoo-community.org/runbot/149/9.0 Known issues / Roadmap ====================== @@ -72,7 +72,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. +`here `_. Credits ======= @@ -86,6 +86,7 @@ Contributors * El hadji Dem * Savoir-faire Linux * Vincent Vinet +* Nicolas JEUDY Maintainer ---------- @@ -103,22 +104,7 @@ To contribute to this module, please visit http://odoo-community.org. Changelog ========= -v0.3 ----- - -* Replace ir.ui.model by ir.ui.view in generated xml views -* Improve pep8 compatibility of generation of models - -v0.2 ----- - -* Renamed from prototype to module_prototyper as discussed in #108 -* Menu in Settings that gather element used to create a prototype (menu views, views, fields) - -v0.1 ----- +v9.0.0.1.0 +---------- -* The set up of openerp.py is covered, description, maintainer, website, name, technical name... -* Views and menus can be set through odoo and gathered in prototype. The files will be automatically generated and add to the data section of the openerp.py. Be aware some advanced feature as domain or context might still missing. -* Dependencies can be set through the Dependencies tab -* Custom fields can be added. A file by model will be generated with all the fields of the model. The init.py files are updated accordingly. Be aware that some features are not implemented yet, as the domain, the context. +* Initial V9 version from V8.0.3 diff --git a/module_prototyper/__init__.py b/module_prototyper/__init__.py index f01f7f1225a..b1517588559 100644 --- a/module_prototyper/__init__.py +++ b/module_prototyper/__init__.py @@ -1,24 +1,6 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import ( models, wizard diff --git a/module_prototyper/__openerp__.py b/module_prototyper/__openerp__.py index b937f8bf9c5..e1b2ba79570 100644 --- a/module_prototyper/__openerp__.py +++ b/module_prototyper/__openerp__.py @@ -1,46 +1,26 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# © 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Module Prototyper', - 'version': '8.0.0.3.0', - 'author': 'Savoir-faire Linux, Odoo Community Association (OCA)', + 'version': '9.0.0.1.0', + 'author': 'Savoir-faire Linux,' + 'Sudokeys, ' + 'ACSONE SA/NV,' + 'Odoo Community Association (OCA)', 'maintainer': 'Savoir-faire Linux', 'website': 'http://www.savoirfairelinux.com', 'license': 'AGPL-3', 'category': 'Others', 'summary': 'Prototype your module.', - 'depends': [ - 'admin_technical_features', - ], - 'external_dependencies': { - 'python': [], - }, 'data': [ 'wizard/module_prototyper_module_export_view.xml', 'views/module_prototyper_view.xml', 'views/ir_model_fields_view.xml', 'security/ir.model.access.csv', ], - 'installable': False, + 'installable': True, 'application': True, } diff --git a/module_prototyper/models/__init__.py b/module_prototyper/models/__init__.py index 995a201154a..2551cb72fbd 100644 --- a/module_prototyper/models/__init__.py +++ b/module_prototyper/models/__init__.py @@ -1,24 +1,7 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from . import ( module_prototyper, ir_model_fields diff --git a/module_prototyper/models/ir_model_fields.py b/module_prototyper/models/ir_model_fields.py index e67df14f814..196dae42211 100644 --- a/module_prototyper/models/ir_model_fields.py +++ b/module_prototyper/models/ir_model_fields.py @@ -1,24 +1,6 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from openerp import fields, models from openerp.tools.translate import _ diff --git a/module_prototyper/models/licenses.py b/module_prototyper/models/licenses.py index 075d27a5923..9a4bb737427 100644 --- a/module_prototyper/models/licenses.py +++ b/module_prototyper/models/licenses.py @@ -1,24 +1,6 @@ -# -*- encoding: utf-8 -*- -# ############################################################################# -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). BASE_GPL = """ This program is free software: you can redistribute it and/or modify diff --git a/module_prototyper/models/module_prototyper.py b/module_prototyper/models/module_prototyper.py index bd3aaa15db6..99e75d33784 100644 --- a/module_prototyper/models/module_prototyper.py +++ b/module_prototyper/models/module_prototyper.py @@ -1,24 +1,8 @@ -# -*- encoding: utf-8 -*- -# ############################################################################# -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# © 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + import base64 import logging import lxml.etree @@ -26,12 +10,12 @@ import re import textwrap -from collections import namedtuple +from collections import namedtuple, OrderedDict from datetime import date from jinja2 import Environment, FileSystemLoader -from openerp import models, api, fields +from openerp import api, fields, models, tools from openerp.tools.safe_eval import safe_eval from . import licenses @@ -109,7 +93,7 @@ def get_default_description(self): version = fields.Char( 'Version', size=9, - default='8.0.1.0.0', + default='9.0.1.0.0', help=('Enter the version of your module with 5 digits') ) auto_install = fields.Boolean( @@ -189,6 +173,14 @@ def get_default_description(self): help=('Enter the list of reports that you have created and ' 'want to export in this module.') ) + + workflow_ids = fields.Many2many( + 'workflow', 'prototype_wf_rel', + 'module_prototyper_id', 'workflow_id', 'Workflows', + help=('Enter the list of workflow that you have created ' + 'and want to export in this module') + ) + activity_ids = fields.Many2many( 'workflow.activity', 'prototype_wf_activity_rel', 'module_prototyper_id', 'activity_id', 'Activities', @@ -209,6 +201,21 @@ def get_default_description(self): File_details = namedtuple('file_details', ['filename', 'filecontent']) template_path = '{}/../templates/'.format(os.path.dirname(__file__)) + @api.onchange('workflow_ids') + def on_workflow_ids_change(self): + act_ids = set(self.activity_ids._ids) + for wf in self.workflow_ids: + act_ids.update(set(wf.activities._ids)) + self.activity_ids = [(6, None, list(act_ids))] + + @api.onchange('activity_ids') + def on_acitvity_ids_change(self): + trans_ids = set(self.transition_ids._ids) + for act in self.activity_ids: + trans_ids.update(set(act.out_transitions._ids)) + trans_ids.update(set(act.in_transitions._ids)) + self.transition_ids = [(6, None, list(trans_ids))] + @api.model def set_jinja_env(self, api_version): """Set the Jinja2 environment. @@ -265,6 +272,7 @@ def generate_files(self): file_details.extend(self.generate_menus_details()) file_details.append(self.generate_module_init_file_details()) file_details.extend(self.generate_data_files()) + file_details.extend(self.generate_workflow_files()) # must be the last as the other generations might add information # to put in the __openerp__: additional dependencies, views files, etc. file_details.append(self.generate_module_openerp_file_details()) @@ -461,6 +469,240 @@ def generate_data_files(self): return res + @api.model + def _get_import_compat_fields_excluded(self, model_name): + return ['create_uid', 'write_uid', 'create_date', 'write_date'] + + @api.model + def get_import_compat_fields(self, model_name): + """Get the list fields in a format suited for the export_data function + This method is inspired by + openerp.addons.web.controllers.Export.get_fields + """ + model = self.env[model_name] + fields = model.fields_get() + exclude = self._get_import_compat_fields_excluded(model_name) + + fields.pop('id', None) + fields_sequence = sorted( + fields.iteritems(), + key=lambda field: tools.ustr(field[1].get('string', ''))) + + records = [] + for field_name, field in fields_sequence: + if exclude and field_name in exclude: + continue + if field.get('readonly'): + # If none of the field's states unsets readonly, skip the field + if all(dict(attrs).get('readonly', True) + for attrs in field.get('states', {}).values()): + continue + if not field.get('exportable', True): + continue + + id = field_name + name = field['string'] + record = {'id': id, 'string': name, + 'export_id': id, 'children': False, + 'field_type': field.get('type'), + 'required': field.get('required'), + 'relation_field': field.get('relation_field'), + 'selection': field.get('selection')} + records.append(record) + + if len(name.split('/')) < 3 and 'relation' in field: + ref = field.pop('relation') + record['export_id'] += '/id' + record['params'] = {'model': ref, 'prefix': id, 'name': name} + + if field['type'] == 'one2many': + # m2m field in import_compat is childless + record['children'] = True + return records + + @api.model + def _sanitize_value(self, field_value): + """sanitaze value for xml export + value is a dictionary item generated by get_import_compat_fields + """ + value = field_value.get('value') + field_type = field_value.get('field_type') + if not value: + return field_value + if field_type in ('one2many', 'many2many'): + value = [v.replace('__export__.', '') for v in value] + elif field_type == 'many2one': + value = value.replace('__export__.', '') + elif field_type == 'selection': + for key, val in field_value['selection']: + if value == val: + value = key + break + field_value['value'] = value + return field_value + + @api.model + def get_import_compat_values(self, model_instances): + """For each instance this function build a list of dict. Each dict is + the definition of the exported field (import compatible) with + the corresponding value from the instance. + The return value is a dict where key = model_instance, value = datas + """ + ret = {} + if len(model_instances) == 0: + return ret + model_name = model_instances._name + # Here we get the definition of the fields that can be exported for + # the given model. Only fields compatible for the import are retrieved + fields_def = self.get_import_compat_fields(model_name) + # The definition is a list of dict. We create a dict by 'export_id' of + # these definitions. The export_id is the field's name to use to get + # the value in a, import compatible way. Fox ex for relation fields, + # the name = field_name/id + fields_dict = dict( + [(f['export_id'], f) for f in fields_def]) + fields_to_export = fields_dict.keys() + multi_valued_field = [(f['export_id']) for f in fields_def if + f['field_type'] in ('one2many', 'many2many')] + for instance in model_instances: + datas = [] + # get exported data by using the same method as the one used + # by the export wizard + data_lines = instance.export_data(fields_to_export)['datas'] + values = instance.export_data(fields_to_export)['datas'][0] + # values is a list of value in the same order as + # the fields_to_export list. We now build a dictionary to safely + # process these values + values_dict = dict(zip(fields_to_export, values)) + # fix multi valued value: + for key in multi_valued_field: + value = values_dict[key] + value = [value] if value else [] + values_dict[key] = value + for line in data_lines[1:]: + # multi valued fields are provided by additional lines + line_values_dict = dict(zip(fields_to_export, line)) + for key in multi_valued_field: + val_item = line_values_dict[key] + if val_item: + values_dict[key].append(val_item) + for export_id, value in values_dict.iteritems(): + # take a copy of the definition of the field. + field_def = fields_dict[export_id].copy() + # add the value retrieved on the instance + field_def['value'] = value + self._sanitize_value(field_def) + datas.append(field_def) + ret[instance] = datas + return ret + + @api.multi + def get_workflows_datas(self): + """This methods return a list of model to export by wokflow. Each + item is a list of models required to export the worklow + Data is defined by the following structure + [{ 'workflow': workflow, + 'xml_id': workflow xml_id, + 'data_models: { + model_name1: [ + (model_instance, import compatible model values1), + (model_instance, import compatible model values2), + (model_instance, import compatible model valuesN])), + model_name1: [ + (model_instance, import compatible model values1), + (model_instance, import compatible model values2), + (model_instance, import compatible model valuesN])), + }}] + The order in the data_models ordered_dict is the one used + when rendering the xml record + """ + self.ensure_one() + workflows = {} + datas = self.get_import_compat_values(self.workflow_ids) + for wk, values in datas.iteritems(): + workflows.setdefault( + wk, {'transitions': [], 'activities': [], + 'values': values}) + + datas = self.get_import_compat_values(self.transition_ids) + for transition, values in datas.iteritems(): + wk_def = workflows.setdefault( + transition.wkf_id, {'transitions': [], 'activities': []}) + wk_def['transitions'].append((transition, values)) + + datas = self.get_import_compat_values(self.activity_ids) + for activity, values in datas.iteritems(): + wk_def = workflows.setdefault( + activity.wkf_id, {'transitions': [], 'activities': []}) + wk_def['activities'].append((activity, values)) + ret = [] + for workflow, val in workflows.iteritems(): + data_models = OrderedDict() + if val.get('values'): + # export workflow definition + data_models['workflow'] = [(workflow, val['values'])] + data_models['workflow.activity'] = val['activities'] + data_models['workflow.transition'] = val['transitions'] + ret.append({ + 'workflow': workflow, + 'xml_id': self.get_model_xml_id(workflow), + 'data_models': data_models + }) + return ret + + @classmethod + def get_model_xml_id(cls, model_instance): + if not model_instance: + return '' + xml_id = model_instance.get_xml_id() + return xml_id.values()[0].replace('__export__.', '') + + @classmethod + def filter_field_values(cls, field_values, mode=None): + """Return a list of field_values (items returned by + get_import_compat_values) accooding to the given mode + Possible value for mode: + * None: return all values + * no_relation: return all values for field with type not in + (one2many, many2many) + * relation_only: return all values for field with type in + (one2many, many2many) + """ + if not mode: + return field_values + if mode == 'no_relation': + return [v for v in field_values if v['field_type'] not in ( + 'one2many', 'many2many')] + if mode == 'relation_only': + return [v for v in field_values if v['field_type'] in ( + 'one2many', 'many2many')] + return field_values + + @api.multi + def generate_workflow_files(self): + """"Wrapper to generate the workflow definition files for the model. + """ + self.ensure_one() + workflows_def = [] + workflows = self.get_workflows_datas() + for workflow_datas in workflows: + xml_id = workflow_datas['xml_id'] + filepath = 'data/{}_workflow.xml'.format( + self.friendly_name(self.unprefix(xml_id)) + ) + workflows_def.append( + self.generate_file_details( + filepath, + 'data/workflow_name.xml.template', + data=workflow_datas, + get_xml_id=self.get_model_xml_id, + filter_field_values=self.filter_field_values, + ) + ) + self._data_files.append(filepath) + + return workflows_def + @classmethod def unprefix(cls, name): if not name: diff --git a/module_prototyper/templates/8.0/data/workflow_name.xml.template b/module_prototyper/templates/8.0/data/workflow_name.xml.template new file mode 100644 index 00000000000..080a73d837b --- /dev/null +++ b/module_prototyper/templates/8.0/data/workflow_name.xml.template @@ -0,0 +1,50 @@ +{% macro render_ref_list(values) -%} + {% set comma = joiner(", ") %} + {% for val in values %}{% for i in val.split(',') %}{{ comma() }}{{ "ref('%s')" % i }}{% endfor %}{% endfor %} +{%- endmacro %} +{% macro render_value(field_value) -%} + {% set value = field_value['value'] %} + {% if field_value['field_type'] == 'text' %}{% else %}{{ value }}{% endif %} +{%- endmacro %} +{% macro render_field(field_value) -%} + {% set value = field_value['value'] %} + {% set field_type = field_value.get('field_type') %} + {% if field_type in ('one2many', 'many2many') -%} + + {% elif field_type == 'many2one' -%} + + {% elif field_type == 'boolean' -%} + + {% else -%} + {{ render_value(field_value) }} + {% endif %} +{%- endmacro %} +{% macro render_model_record(instance, fields_value, mode=None) -%} + {% set filtered_fields_value = filter_field_values(fields_value, mode=mode) %} + {% if filtered_fields_value %} + + {% for field_value in filtered_fields_value %} + {{ render_field(field_value) }} + {%- endfor %} + + + {% endif %} +{%- endmacro %} + + + + {% for model_name, models in data['data_models'].iteritems() %} + + + {% for model_instance, fields_value in models -%} + {{ render_model_record(model_instance, fields_value, mode='no_relation') }} + {%- endfor %} + {% endfor %} + {% for model_name, models in data['data_models'].iteritems() %} + + {% for model_instance, fields_value in models -%} + {{ render_model_record(model_instance, fields_value, mode='relation_only') }} + {%- endfor %} + {% endfor %} + + diff --git a/module_prototyper/tests/__init__.py b/module_prototyper/tests/__init__.py index aff3c1c83fe..589d580890d 100644 --- a/module_prototyper/tests/__init__.py +++ b/module_prototyper/tests/__init__.py @@ -1,24 +1,7 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from . import ( test_prototype_module_export, test_prototype diff --git a/module_prototyper/tests/test_prototype.py b/module_prototyper/tests/test_prototype.py index 76d3c8fdc51..545e987e0db 100644 --- a/module_prototyper/tests/test_prototype.py +++ b/module_prototyper/tests/test_prototype.py @@ -1,21 +1,6 @@ -# -*- encoding: utf-8 -*- # -# OpenERP, Open Source Management Solution -# This module copyright (C) 2013 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import ast import lxml.etree diff --git a/module_prototyper/tests/test_prototype_module_export.py b/module_prototyper/tests/test_prototype_module_export.py index e58cd1b9037..faf2f332300 100644 --- a/module_prototyper/tests/test_prototype_module_export.py +++ b/module_prototyper/tests/test_prototype_module_export.py @@ -1,24 +1,7 @@ -# -*- encoding: utf-8 -*- -# ############################################################################# -# -# OpenERP, Open Source Management Solution -# This module copyright (C) 2010 - 2014 Savoir-faire Linux -# (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- +# © 2010 - 2014 Savoir-faire Linux () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from openerp.tests import common import zipfile import StringIO diff --git a/module_prototyper/views/ir_model_fields_view.xml b/module_prototyper/views/ir_model_fields_view.xml index df2df0daf9c..f4f55b2ebad 100644 --- a/module_prototyper/views/ir_model_fields_view.xml +++ b/module_prototyper/views/ir_model_fields_view.xml @@ -39,8 +39,7 @@ ir.model - + diff --git a/module_prototyper/views/module_prototyper_view.xml b/module_prototyper/views/module_prototyper_view.xml index 25106d29207..f4a58bdffcf 100644 --- a/module_prototyper/views/module_prototyper_view.xml +++ b/module_prototyper/views/module_prototyper_view.xml @@ -90,6 +90,8 @@ +