Browse Source

[10.0][MIG] Module Prototyper (#634)

* [ADD] Updated manifest and README

* [ADD] Version 10.0 template and api_version model

* [ADD] Updated license header, updated api call

* [FIX] Flake

* [FIX] Flake

* [FIX] Tests

* [FIX] Flake8

* [ADD] Extra test for changed method 'set_jinja_env'

* [FIX] Fixed 'Try me on runbot' button
12.0-mig-module_prototyper_last
Dennis Sluijk 8 years ago
committed by Nicolas JEUDY
parent
commit
f85505c380
  1. 25
      module_prototyper/README.rst
  2. 2
      module_prototyper/__init__.py
  3. 10
      module_prototyper/__manifest__.py
  4. 54
      module_prototyper/data/README.rst
  5. 16
      module_prototyper/data/module_prototyper_api_version_data.xml
  6. 3
      module_prototyper/models/__init__.py
  7. 21
      module_prototyper/models/ir_model_fields.py
  8. 2
      module_prototyper/models/licenses.py
  9. 43
      module_prototyper/models/module_prototyper.py
  10. 12
      module_prototyper/models/module_prototyper_api_version.py
  11. 1
      module_prototyper/security/ir.model.access.csv
  12. 7
      module_prototyper/templates/10.0/__init__.py.template
  13. 58
      module_prototyper/templates/10.0/__manifest__.py.template
  14. 6
      module_prototyper/templates/10.0/data/model_name.xml.template
  15. 6
      module_prototyper/templates/10.0/demo/model_name.xml.template
  16. 5
      module_prototyper/templates/10.0/header.template
  17. 9
      module_prototyper/templates/10.0/models/__init__.py.template
  18. 35
      module_prototyper/templates/10.0/models/model_name.py.template
  19. 4
      module_prototyper/templates/10.0/security/ir.model.access.csv.template
  20. 8
      module_prototyper/templates/10.0/security/model_name.xml.template
  21. 27
      module_prototyper/templates/10.0/views/model_menus.xml.template
  22. 15
      module_prototyper/templates/10.0/views/model_views.xml.template
  23. 4
      module_prototyper/templates/8.0/__openerp__.py.template
  24. 24
      module_prototyper/templates/8.0/header.template
  25. 2
      module_prototyper/tests/__init__.py
  26. 39
      module_prototyper/tests/test_prototype.py
  27. 10
      module_prototyper/tests/test_prototype_module_export.py
  28. 88
      module_prototyper/views/ir_model_fields_view.xml
  29. 264
      module_prototyper/views/module_prototyper_view.xml
  30. 2
      module_prototyper/wizard/__init__.py
  31. 25
      module_prototyper/wizard/module_prototyper_module_export.py
  32. 68
      module_prototyper/wizard/module_prototyper_module_export_view.xml

25
module_prototyper/README.rst

@ -51,7 +51,7 @@ things like default values or onchange methods.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/149/9.0
:target: https://runbot.odoo-community.org/runbot/149/10.0
Known issues / Roadmap Known issues / Roadmap
====================== ======================
@ -69,10 +69,10 @@ Known issues / Roadmap
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/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 <https://github.com/OCA/server-tools/issues/new?body=module:%20module_prototyper%0Aversion:%209.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/server-tools/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.
Credits Credits
======= =======
@ -87,6 +87,7 @@ Contributors
* Savoir-faire Linux <support@savoirfairelinux.com> * Savoir-faire Linux <support@savoirfairelinux.com>
* Vincent Vinet <vincent.vinet@savoirfairelinux.com> * Vincent Vinet <vincent.vinet@savoirfairelinux.com>
* Nicolas JEUDY <nicolas@sudokeys.com> * Nicolas JEUDY <nicolas@sudokeys.com>
* Dennis Sluijk <d.sluijk@onestein.nl>
Maintainer Maintainer
---------- ----------
@ -97,14 +98,8 @@ Maintainer
This module is maintained by the OCA. This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.
Changelog
=========
v9.0.0.1.0
----------
* Initial V9 version from V8.0.3
To contribute to this module, please visit https://odoo-community.org.

2
module_prototyper/__init__.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution

10
module_prototyper/__manifest__.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -22,8 +22,9 @@
{ {
'name': 'Module Prototyper', 'name': 'Module Prototyper',
'version': '9.0.0.1.0',
'author': 'Savoir-faire Linux, Odoo Community Association (OCA), Sudokeys',
'version': '10.0.1.0.0',
'author': 'Savoir-faire Linux, Sudokeys, Onestein, '
'Odoo Community Association (OCA)',
'maintainer': 'Savoir-faire Linux', 'maintainer': 'Savoir-faire Linux',
'website': 'http://www.savoirfairelinux.com', 'website': 'http://www.savoirfairelinux.com',
'license': 'AGPL-3', 'license': 'AGPL-3',
@ -34,11 +35,12 @@
'python': [], 'python': [],
}, },
'data': [ 'data': [
'data/module_prototyper_api_version_data.xml',
'wizard/module_prototyper_module_export_view.xml', 'wizard/module_prototyper_module_export_view.xml',
'views/module_prototyper_view.xml', 'views/module_prototyper_view.xml',
'views/ir_model_fields_view.xml', 'views/ir_model_fields_view.xml',
'security/ir.model.access.csv', 'security/ir.model.access.csv',
], ],
'installable': False,
'installable': True,
'application': True, 'application': True,
} }

54
module_prototyper/data/README.rst

@ -2,33 +2,37 @@
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
===========
Module name
===========
==============
{module_title}
==============
This module was written to extend the functionality of ... to support ...
and allow you to ...
This module extends the functionality of ... to support ...
and to allow you to ...
Installation Installation
============ ============
To install this module, you need to: To install this module, you need to:
* do this ...
#. Do this ...
Configuration Configuration
============= =============
To configure this module, you need to: To configure this module, you need to:
* go to ...
#. Go to ...
.. figure:: path/to/local/image.png
:alt: alternative description
:width: 600 px
Usage Usage
===== =====
To use this module, you need to: To use this module, you need to:
* go to ...
#. Go to ...
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot :alt: Try me on Runbot
@ -37,37 +41,47 @@ To use this module, you need to:
.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt .. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt
.. branch is "8.0" for example .. branch is "8.0" for example
For further information, please visit:
* https://www.odoo.com/forum/help-1
Known issues / Roadmap Known issues / Roadmap
====================== ======================
* ...
* Add ...
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/{project_repo}/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 <https://github.com/OCA/{project_repo}/issues/new?body=module:%20{module_name}%0Aversion:%20{version}%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/{project_repo}/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.
Credits Credits
======= =======
Images
------
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors Contributors
------------ ------------
* Firstname Lastname <email.address@example.org> * Firstname Lastname <email.address@example.org>
* Second Person <second.person@example.org>
Funders
-------
The development of this module has been financially supported by:
* Company 1 name
* Company 2 name
Maintainer Maintainer
---------- ----------
.. image:: http://odoo-community.org/logo.png
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association :alt: Odoo Community Association
:target: http://odoo-community.org
:target: https://odoo-community.org
This module is maintained by the OCA. This module is maintained by the OCA.
@ -75,4 +89,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.
To contribute to this module, please visit https://odoo-community.org.

16
module_prototyper/data/module_prototyper_api_version_data.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 Onestein (<http://www.onestein.eu>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="api_version_80" model="module_prototyper.api_version">
<field name="name">8.0</field>
<field name="manifest_file_name">__openerp__</field>
</record>
<record id="api_version_100" model="module_prototyper.api_version">
<field name="name">10.0</field>
<field name="manifest_file_name">__manifest__</field>
</record>
</odoo>

3
module_prototyper/models/__init__.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -21,5 +21,6 @@
############################################################################## ##############################################################################
from . import ( from . import (
module_prototyper, module_prototyper,
module_prototyper_api_version,
ir_model_fields ir_model_fields
) )

21
module_prototyper/models/ir_model_fields.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -20,11 +20,10 @@
# #
############################################################################## ##############################################################################
from openerp import fields, models
from openerp.tools.translate import _
from odoo import fields, models
class ir_model_fields(models.Model):
class IrModelFields(models.Model):
"""Addition of text fields to fields.""" """Addition of text fields to fields."""
_inherit = "ir.model.fields" _inherit = "ir.model.fields"
@ -33,17 +32,17 @@ class ir_model_fields(models.Model):
# TODO: Make column1 and 2 required if a model has a m2m to itself # TODO: Make column1 and 2 required if a model has a m2m to itself
column1 = fields.Char( column1 = fields.Char(
'Column1', 'Column1',
help=_("name of the column referring to 'these' records in the "
"relation table"),
help="name of the column referring to 'these' records in the "
"relation table",
) )
column2 = fields.Char( column2 = fields.Char(
'Column2', 'Column2',
help=_("name of the column referring to 'those' records in the "
"relation table"),
help="name of the column referring to 'those' records in the "
"relation table",
) )
limit = fields.Integer('Read limit', help=_("Read limit"))
limit = fields.Integer('Read limit', help="Read limit")
client_context = fields.Char( client_context = fields.Char(
'Context', 'Context',
help=_("Context to use on the client side when handling the field "
"(python dictionary)"),
help="Context to use on the client side when handling the field "
"(python dictionary)",
) )

2
module_prototyper/models/licenses.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
# ############################################################################# # #############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution

43
module_prototyper/models/module_prototyper.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
# ############################################################################# # #############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -31,8 +31,8 @@ from datetime import date
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from openerp import models, api, fields
from openerp.tools.safe_eval import safe_eval
from odoo import models, api, fields
from odoo.tools.safe_eval import safe_eval
from . import licenses from . import licenses
@ -55,7 +55,7 @@ class ModulePrototyper(models.Model):
""" """
Extract the content of default description Extract the content of default description
""" """
filepath = '{}/../data/README.rst'.format(os.path.dirname(__file__))
filepath = '%s/../data/README.rst' % (os.path.dirname(__file__),)
with open(filepath, 'r') as content_file: with open(filepath, 'r') as content_file:
content = content_file.read() content = content_file.read()
return content return content
@ -108,8 +108,8 @@ class ModulePrototyper(models.Model):
) )
version = fields.Char( version = fields.Char(
'Version', 'Version',
size=9,
default='8.0.1.0.0',
size=10,
default='10.0.1.0.0',
help=('Enter the version of your module with 5 digits') help=('Enter the version of your module with 5 digits')
) )
auto_install = fields.Boolean( auto_install = fields.Boolean(
@ -203,17 +203,18 @@ class ModulePrototyper(models.Model):
) )
_env = None _env = None
_api_version = None
_data_files = () _data_files = ()
_demo_files = () _demo_files = ()
_field_descriptions = None _field_descriptions = None
File_details = namedtuple('file_details', ['filename', 'filecontent']) File_details = namedtuple('file_details', ['filename', 'filecontent'])
template_path = '{}/../templates/'.format(os.path.dirname(__file__))
template_path = '%s/../templates/' % (os.path.dirname(__file__),)
@api.model @api.model
def set_jinja_env(self, api_version):
def setup_env(self, api_version):
"""Set the Jinja2 environment. """Set the Jinja2 environment.
The environment will helps the system to find the templates to render. The environment will helps the system to find the templates to render.
:param api_version: string, odoo api
:param api_version: module_prototyper.api_version, odoo api
:return: jinja2.Environment instance. :return: jinja2.Environment instance.
""" """
if self._env is None: if self._env is None:
@ -221,9 +222,10 @@ class ModulePrototyper(models.Model):
lstrip_blocks=True, lstrip_blocks=True,
trim_blocks=True, trim_blocks=True,
loader=FileSystemLoader( loader=FileSystemLoader(
os.path.join(self.template_path, api_version)
os.path.join(self.template_path, api_version.name)
) )
) )
self._api_version = api_version
return self._env return self._env
def set_field_descriptions(self): def set_field_descriptions(self):
@ -267,7 +269,9 @@ class ModulePrototyper(models.Model):
file_details.extend(self.generate_data_files()) file_details.extend(self.generate_data_files())
# must be the last as the other generations might add information # must be the last as the other generations might add information
# to put in the __openerp__: additional dependencies, views files, etc. # to put in the __openerp__: additional dependencies, views files, etc.
file_details.append(self.generate_module_openerp_file_details())
file_details.append(
self.generate_module_openerp_file_details()
)
if self.icon_image: if self.icon_image:
file_details.append(self.save_icon()) file_details.append(self.save_icon())
@ -293,9 +297,10 @@ class ModulePrototyper(models.Model):
@api.model @api.model
def generate_module_openerp_file_details(self): def generate_module_openerp_file_details(self):
"""Wrapper to generate the __openerp__.py file of the module.""" """Wrapper to generate the __openerp__.py file of the module."""
fn_inc_ext = '%s.py' % (self._api_version.manifest_file_name,)
return self.generate_file_details( return self.generate_file_details(
'__openerp__.py',
'__openerp__.py.template',
fn_inc_ext,
'%s.template' % (fn_inc_ext,),
prototype=self, prototype=self,
data_files=self._data_files, data_files=self._data_files,
demo_fiels=self._demo_files, demo_fiels=self._demo_files,
@ -366,8 +371,8 @@ class ModulePrototyper(models.Model):
views_details = [] views_details = []
for model, views in relations.iteritems(): for model, views in relations.iteritems():
filepath = 'views/{}_view.xml'.format(
self.friendly_name(self.unprefix(model))
filepath = 'views/%s_view.xml' % (
self.friendly_name(self.unprefix(model)),
) )
views_details.append( views_details.append(
self.generate_file_details( self.generate_file_details(
@ -394,8 +399,8 @@ class ModulePrototyper(models.Model):
menus_details = [] menus_details = []
for model_name, menus in relations.iteritems(): for model_name, menus in relations.iteritems():
model_name = self.unprefix(model_name) model_name = self.unprefix(model_name)
filepath = 'views/{}_menus.xml'.format(
self.friendly_name(model_name)
filepath = 'views/%s_menus.xml' % (
self.friendly_name(model_name),
) )
menus_details.append( menus_details.append(
self.generate_file_details( self.generate_file_details(
@ -418,7 +423,7 @@ class ModulePrototyper(models.Model):
""" """
python_friendly_name = self.friendly_name(self.unprefix(model.model)) python_friendly_name = self.friendly_name(self.unprefix(model.model))
return self.generate_file_details( return self.generate_file_details(
'models/{}.py'.format(python_friendly_name),
'models/%s.py' % (python_friendly_name,),
'models/model_name.py.template', 'models/model_name.py.template',
name=python_friendly_name, name=python_friendly_name,
model=model, model=model,
@ -449,7 +454,7 @@ class ModulePrototyper(models.Model):
('demo', demo, self._demo_files)]: ('demo', demo, self._demo_files)]:
for model_name, records in model_data.iteritems(): for model_name, records in model_data.iteritems():
fname = self.friendly_name(self.unprefix(model_name)) fname = self.friendly_name(self.unprefix(model_name))
filename = '{0}/{1}.xml'.format(prefix, fname)
filename = '%s/%s.xml' % (prefix, fname)
self._data_files.append(filename) self._data_files.append(filename)
res.append(self.generate_file_details( res.append(self.generate_file_details(

12
module_prototyper/models/module_prototyper_api_version.py

@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Onestein (<http://www.onestein.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
class ModulePrototyperApiVersion(models.Model):
_name = 'module_prototyper.api_version'
name = fields.Char()
manifest_file_name = fields.Char()

1
module_prototyper/security/ir.model.access.csv

@ -1,2 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_prototype_admin,prototype_system,model_module_prototyper,base.group_system,1,1,1,1 access_prototype_admin,prototype_system,model_module_prototyper,base.group_system,1,1,1,1
access_prototype_api_version_admin,prototype_api_version_system,model_module_prototyper_api_version,base.group_system,1,1,1,1

7
module_prototyper/templates/10.0/__init__.py.template

@ -0,0 +1,7 @@
{% extends "header.template" %}
{% block body %}
{% if models %}
from . import models
{% endif %}
{% endblock %}

58
module_prototyper/templates/10.0/__manifest__.py.template

@ -0,0 +1,58 @@
{% extends "header.template" %}
{% block body %}
{
'name': '{{ prototype.human_name }}',
'version': '{{ prototype.version }}',
'author': '{{ prototype.author }}',
'maintainer': '{{ prototype.maintainer }}',
'website': '{{ prototype.website }}',
'license': '{{ prototype.licence }}',
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml # noqa
# for the full list
'category': '{{ prototype.with_context({}).category_id.name }}',{# In english please! #}
'summary': '{{ prototype.summary }}',
'description': """
{{ prototype.description }}
* Module exported by the Module Prototyper module for version 10.0.
* If you have any questions, please contact Savoir-faire Linux
(support@savoirfairelinux.com)
""",
# any module necessary for this one to work correctly
'depends': [
{% for dependency in prototype.dependency_ids %}
'{{ dependency.name }}',
{% endfor %}
],
'external_dependencies': {
'python': [],
},
# always loaded
'data': [
{% for data_file in data_files %}
'{{ data_file }}',
{% endfor %}
],
# only loaded in demonstration mode
'demo': [
{% for demo_file in prototype.demo_ids %}
'{{ demo_file.name }}',
{% endfor %}
],
'js': [],
'css': [],
'qweb': [],
'installable': True,
# Install this module automatically if all dependency have been previously
# and independently installed. Used for synergetic or glue modules.
'auto_install': {{ prototype.auto_install }},
'application': {{ prototype.application }},
}
{% endblock %}

6
module_prototyper/templates/10.0/data/model_name.xml.template

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<odoo>
{{ data }}
</odoo>

6
module_prototyper/templates/10.0/demo/model_name.xml.template

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<odoo>
{{ demo }}
</odoo>

5
module_prototyper/templates/10.0/header.template

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright {{ export_year }} {% if author %}{{ author }}{% endif %} ({% if website %}({{ website }}).{% endif %})
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{% block body %}
{% endblock %}

9
module_prototyper/templates/10.0/models/__init__.py.template

@ -0,0 +1,9 @@
{% extends "header.template" %}
{% block body %}
{% for model in models %}
{% if loop.first %}
{% endif %}
from . import {{ model }}
{% endfor %}
{% endblock %}

35
module_prototyper/templates/10.0/models/model_name.py.template

@ -0,0 +1,35 @@
{% extends "header.template" %}
{% block body %}
from odoo import models, fields
from odoo.tools.translate import _
class {{ unprefix(name) }}(models.Model):
{% if model.state == 'base' %}
_name = "{{ model.model }}"
{% else %}
_inherit = "{{ model.model }}"
{% endif %}
{% if description %}
_description = "{{ description }}"
{% endif %}
{% for field in fields %}
{% for line in wrap(field.notes, replace_whitespace=False) %}
# {{line}}
{% endfor %}
{{ unprefix(field.name) }} = fields.{{ field.ttype|capitalize }}(
string=_("{{ field.field_description }}"),
required={{ field.required }},
translate={{ field.translate }},
readonly={{ field.readonly }}
{% if field.size %}
size={{ field.size }},
{% endif %}
{% if field.helper %}
help=_("{{ field.helper }}"),
{% endif %}
)
{% endfor %}
{% endblock %}

4
module_prototyper/templates/10.0/security/ir.model.access.csv.template

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
{% for rule in access_rules %}
{{ rule.id }},{{ rule.name }},{{ rule.model_id.id }},{{ rule.group_id.id }},{{ rule.perm_write }},{{ rule.perm_write }},{{ rule.perm_create }},{{ rule.perm_unlink }}
{% endfor %}

8
module_prototyper/templates/10.0/security/model_name.xml.template

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<odoo>
{{ groups }}
{{ rules }}
</odoo>

27
module_prototyper/templates/10.0/views/model_menus.xml.template

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<odoo>
{% for menu in menus %}
<record id="action_{{ menu.action.name }}_{{ menu.action.view_type }}_view" model="{{ menu.action.type }}">
<field name="name">{{ unprefix(menu.action.name) }}</field>
<field name="type">{{ menu.action.type }}</field>
<field name="res_model">{{ unprefix(menu.action.res_model) }}</field>
<field name="view_type">{{ menu.action.view_type }}</field>
<field name="view_mode">{{ menu.action.view_mode }}</field>
{% if menu.action.help %}
<field name="help" type="html">{{ menu.action.help }}
</field>
{% endif %}
</record>
<menuitem action="action_{{ unprefix(menu.action.name) }}_{{ menu.action.view_type }}_view"
name="{{ menu.name }}"
id="menu_action_{{ unprefix(menu.name)|replace('.', '_') }}_{{ menu.action.view_type }}"
{% if menu.parent_id %}parent="{{ menu.parent_id.get_xml_id().values()[0] }}"{% endif %}
sequence="{{ menu.sequence }}"
groups="{% for group in menu.groups_id %}{{ group.get_xml_id().values()[0] }},{% endfor %}"
/>
{% if not loop.last %}
{% endif %}
{% endfor %}
</odoo>

15
module_prototyper/templates/10.0/views/model_views.xml.template

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<odoo>
<!-- TODO: put here a reminder on what to do at the first edition -->
{% for view in views %}
<record id="{{ unprefix(view.name)|replace('.', '_')}}_view" model="ir.ui.view">
<field name="name">{{ unprefix(view.name) }}.view</field>
<field name="model">{{ unprefix(view.model) }}</field>
<field name="view_type">{{ view.type }}</field>
<field name="inherit_id" ref="{{ view.inherit_id.get_xml_id().values()[0] }}"/>
<field name="arch" type="xml">
{{ fixup_arch(view.arch) }}
</field>
</record>
{% endfor %}
</odoo>

4
module_prototyper/templates/8.0/__openerp__.py.template

@ -16,10 +16,6 @@
'summary': '{{ prototype.summary }}', 'summary': '{{ prototype.summary }}',
'description': """ 'description': """
{{ prototype.description }} {{ prototype.description }}
* Module exported by the Module Prototyper module for version 8.0.
* If you have any questions, please contact Savoir-faire Linux
(support@savoirfairelinux.com)
""", """,
# any module necessary for this one to work correctly # any module necessary for this one to work correctly

24
module_prototyper/templates/8.0/header.template

@ -1,23 +1,5 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Odoo, Open Source Management Solution
# This module copyright (C) {{ export_year }} {% if author %}{{ author }}{% endif %}
# {% if website %}({{ website }}).{% endif %}
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
# -*- coding: utf-8 -*-
# Copyright {{ export_year }} {% if author %}{{ author }}{% endif %} ({% if website %}({{ website }}).{% endif %})
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{% block body %} {% block body %}
{% endblock %} {% endblock %}

2
module_prototyper/tests/__init__.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution

39
module_prototyper/tests/test_prototype.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*- #
# -*- coding: utf-8 -*-
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
# This module copyright (C) 2013 Savoir-faire Linux # This module copyright (C) 2013 Savoir-faire Linux
# (<http://www.savoirfairelinux.com>). # (<http://www.savoirfairelinux.com>).
@ -28,7 +28,7 @@ except ImportError:
from jinja2 import Environment from jinja2 import Environment
from jinja2.exceptions import TemplateNotFound from jinja2.exceptions import TemplateNotFound
from openerp.tests import common
from odoo.tests import common
class TestModulePrototyper(common.TransactionCase): class TestModulePrototyper(common.TransactionCase):
@ -49,17 +49,17 @@ class TestModulePrototyper(common.TransactionCase):
'website': 't_website', 'website': 't_website',
'dependencies': [(6, 0, [1, 2, 3, 4])], 'dependencies': [(6, 0, [1, 2, 3, 4])],
}) })
self.api_version = '8.0'
self.api_version = self.env['module_prototyper.api_version'].search([
('id', '=', self.ref('module_prototyper.api_version_80'))
])
def test_generate_files_assert_if_no_env(self): def test_generate_files_assert_if_no_env(self):
self.assertRaises(
AssertionError,
self.prototype.generate_files
)
with self.assertRaises(AssertionError):
self.prototype.generate_files()
def test_generate_files(self): def test_generate_files(self):
"""Test generate_files returns a tuple.""" """Test generate_files returns a tuple."""
self.prototype.set_jinja_env(self.api_version)
self.prototype.setup_env(self.api_version)
details = self.prototype.generate_files() details = self.prototype.generate_files()
self.assertIsInstance(details, list) self.assertIsInstance(details, list)
# namedtuples in tuple # namedtuples in tuple
@ -80,9 +80,9 @@ class TestModulePrototyper(common.TransactionCase):
res = checker.check_all() res = checker.check_all()
self.assertFalse( self.assertFalse(
res, res,
"Python file {0} has pep8 errors:\n"
"{1}\n{2}".format(name, checker.report.messages,
repr(contents))
"Python file %s has pep8 errors:\n"
"%s\n%s" % (name, checker.report.messages,
repr(contents))
) )
elif name.endswith(".xml"): elif name.endswith(".xml"):
@ -90,19 +90,24 @@ class TestModulePrototyper(common.TransactionCase):
lxml.etree.fromstring(contents) lxml.etree.fromstring(contents)
def test_generate_files_raise_templatenotfound_if_not_found(self): def test_generate_files_raise_templatenotfound_if_not_found(self):
self.prototype.set_jinja_env('t_api_version')
self.assertRaises(
TemplateNotFound,
self.prototype.generate_files
)
not_existing_api = self.env['module_prototyper.api_version'].create({
'name': 'non_existing_api'
})
self.prototype.setup_env(not_existing_api)
with self.assertRaises(TemplateNotFound):
self.prototype.generate_files()
def test_set_env(self): def test_set_env(self):
"""test the jinja2 environment is set.""" """test the jinja2 environment is set."""
self.assertIsNone(self.prototype._env) self.assertIsNone(self.prototype._env)
self.prototype.set_jinja_env(self.api_version)
self.prototype.setup_env(self.api_version)
self.assertIsInstance( self.assertIsInstance(
self.prototype._env, Environment self.prototype._env, Environment
) )
self.assertEqual(
self.api_version,
self.prototype._api_version
)
def test_friendly_name_return(self): def test_friendly_name_return(self):
"""Test if the returns match the pattern.""" """Test if the returns match the pattern."""

10
module_prototyper/tests/test_prototype_module_export.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
# ############################################################################# # #############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -19,14 +19,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################## ##############################################################################
from openerp.tests import common
from odoo.tests import common
import zipfile import zipfile
import StringIO import StringIO
class test_prototype_module_export(common.TransactionCase):
class TestPrototypeModuleExport(common.TransactionCase):
def setUp(self): def setUp(self):
super(test_prototype_module_export, self).setUp()
super(TestPrototypeModuleExport, self).setUp()
self.main_model = self.env['module_prototyper.module.export'] self.main_model = self.env['module_prototyper.module.export']
self.prototype_model = self.env['module_prototyper'] self.prototype_model = self.env['module_prototyper']
self.module_category_model = self.env[ self.module_category_model = self.env[
@ -65,7 +65,7 @@ class test_prototype_module_export(common.TransactionCase):
).create({}) ).create({})
exporter.action_export(exporter.id) exporter.action_export(exporter.id)
self.assertEqual(exporter.state, 'get') self.assertEqual(exporter.state, 'get')
self.assertEqual(exporter.name, '{}.zip'.format(self.prototype.name))
self.assertEqual(exporter.name, '%s.zip' % (self.prototype.name,))
def test_zip_files_returns_tuple(self): def test_zip_files_returns_tuple(self):
"""Test the method return of the method that generate the zip file.""" """Test the method return of the method that generate the zip file."""

88
module_prototyper/views/ir_model_fields_view.xml

@ -1,50 +1,48 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<openerp>
<data>
<odoo>
<record id="view_ir_model_fields_form" model="ir.ui.view">
<field name="name">view_ir_model_fields_form</field>
<field name="model">ir.model.fields</field>
<field name="inherit_id" ref="base.view_model_fields_form"/>
<field name="arch" type="xml">
<field name="groups" position="before">
<label for="helper"/>
<field name="helper"
placeholder="Text that will be set as the helper of the field..."/>
<label for="notes"/>
<field name="notes"
placeholder="Notes to help developers to understand the work or advanced features that should be added, ie: onchange, etc."/>
</field>
<field name="relation_field" position="after">
<field name="column1"
attrs="{'invisible': [('ttype', '!=', 'many2many')]}"
/>
<field name="column2"
attrs="{'invisible': [('ttype', '!=', 'many2many')]}"
/>
</field>
<field name="translate" position="after">
<field name="limit"
attrs="{'invisible': [('ttype', '!=', 'many2many')]}"
/>
<field name="client_context"
attrs="{'invisible': [('ttype', 'not in', ['many2one','one2many','many2many'])]}"
/>
</field>
<record id="view_ir_model_fields_form" model="ir.ui.view">
<field name="name">view_ir_model_fields_form</field>
<field name="model">ir.model.fields</field>
<field name="inherit_id" ref="base.view_model_fields_form"/>
<field name="arch" type="xml">
<field name="groups" position="before">
<label for="helper"/>
<field name="helper"
placeholder="Text that will be set as the helper of the field..."/>
<label for="notes"/>
<field name="notes"
placeholder="Notes to help developers to understand the work or advanced features that should be added, ie: onchange, etc."/>
</field> </field>
</record>
<record id="view_ir_model_form" model="ir.ui.view">
<field name="name">view_ir_model_form</field>
<field name="model">ir.model</field>
<field name="inherit_id" ref="base.view_model_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='field_id']/form/notebook" position="before">
<separator string="Notes"/>
<field name="notes"/>
</xpath>
<field name="relation_field" position="after">
<field name="column1"
attrs="{'invisible': [('ttype', '!=', 'many2many')]}"
/>
<field name="column2"
attrs="{'invisible': [('ttype', '!=', 'many2many')]}"
/>
</field>
<field name="translate" position="after">
<field name="limit"
attrs="{'invisible': [('ttype', '!=', 'many2many')]}"
/>
<field name="client_context"
attrs="{'invisible': [('ttype', 'not in', ['many2one','one2many','many2many'])]}"
/>
</field> </field>
</record>
</field>
</record>
<record id="view_ir_model_form" model="ir.ui.view">
<field name="name">view_ir_model_form</field>
<field name="model">ir.model</field>
<field name="inherit_id" ref="base.view_model_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='field_id']/form/notebook" position="before">
<separator string="Notes"/>
<field name="notes"/>
</xpath>
</field>
</record>
</data>
</openerp>
</odoo>

264
module_prototyper/views/module_prototyper_view.xml

@ -1,146 +1,144 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<openerp>
<data>
<odoo>
<record id="module_prototyper_base_tree_view" model="ir.ui.view">
<field name="name">Base tree View for module prototypes</field>
<field name="model">module_prototyper</field>
<field name="arch" type="xml">
<tree string="Prototype">
<field name="human_name"/>
<field name="name"/>
<field name="summary"/>
</tree>
</field>
</record>
<record id="module_prototyper_base_tree_view" model="ir.ui.view">
<field name="name">Base tree View for module prototypes</field>
<field name="model">module_prototyper</field>
<field name="arch" type="xml">
<tree string="Prototype">
<field name="human_name"/>
<field name="name"/>
<field name="summary"/>
</tree>
</field>
</record>
<record id="module_prototyper_base_form_view" model="ir.ui.view">
<field name="name">Base form view for module prototypes</field>
<field name="model">module_prototyper</field>
<field name="arch" type="xml">
<form string="Module">
<sheet>
<field name="icon_image" widget="image"
class="oe_avatar oe_left"/>
<div class="oe_title">
<h1>
<field name="human_name"
placeholder="ex: Module Prototyper"/>
</h1>
<div>
<button name="%(button_module_export_action)d"
string="Export" type="action"/>
</div>
<record id="module_prototyper_base_form_view" model="ir.ui.view">
<field name="name">Base form view for module prototypes</field>
<field name="model">module_prototyper</field>
<field name="arch" type="xml">
<form string="Module">
<sheet>
<field name="icon_image" widget="image"
class="oe_avatar oe_left"/>
<div class="oe_title">
<h1>
<field name="human_name"
placeholder="ex: Module Prototyper"/>
</h1>
<div>
<button name="%(button_module_export_action)d"
string="Export" type="action"/>
</div> </div>
</div>
<group>
<group> <group>
<group>
<field name="name"
placeholder="ex: module_prototyper"/>
<field name="summary"
placeholder="ex: Prototype your module."/>
<field name="category_id"
placeholder="ex: Others, Sales, Website"/>
<field name="version"/>
<field name="license"/>
</group>
<group>
<field name="author"
placeholder="ex: Odoo Community Association"/>
<field name="website" widget="url"
placeholder="ex: http://odoo-community.org/"/>
<field name="maintainer"
placeholder="ex: Odoo Community Association"/>
<field name="auto_install"/>
<field name="application"/>
</group>
<field name="name"
placeholder="ex: module_prototyper"/>
<field name="summary"
placeholder="ex: Prototype your module."/>
<field name="category_id"
placeholder="ex: Others, Sales, Website"/>
<field name="version"/>
<field name="license"/>
</group> </group>
<notebook>
<page string="Description">
<field name="description"/>
</page>
<page string="Dependencies">
<field name="dependency_ids"/>
</page>
<page string="Fields">
<label for="field_ids"/>
<field name="field_ids"/>
</page>
<page string="Interface">
<label for="view_ids"/>
<field name="view_ids"/>
<label for="menu_ids"/>
<field name="menu_ids"/>
</page>
<page string="Data &amp; Demo">
<label for="data_ids"/>
<field name="data_ids"/>
<label for="demo_ids"/>
<field name="demo_ids"/>
</page>
<page string="Reports">
<label for="report_ids" />
<field name="report_ids" />
</page>
<page string="Security">
<label for="group_ids"/>
<field name="group_ids"/>
<label for="right_ids"/>
<field name="right_ids"/>
<label for="rule_ids"/>
<field name="rule_ids"/>
</page>
<page string="Workflows">
<label for="activity_ids" />
<field name="activity_ids" />
<label for="transition_ids" />
<field name="transition_ids" />
</page>
<page string="Website">
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<group>
<field name="author"
placeholder="ex: Odoo Community Association"/>
<field name="website" widget="url"
placeholder="ex: http://odoo-community.org/"/>
<field name="maintainer"
placeholder="ex: Odoo Community Association"/>
<field name="auto_install"/>
<field name="application"/>
</group>
</group>
<notebook>
<page string="Description">
<field name="description"/>
</page>
<page string="Dependencies">
<field name="dependency_ids"/>
</page>
<page string="Fields">
<label for="field_ids"/>
<field name="field_ids"/>
</page>
<page string="Interface">
<label for="view_ids"/>
<field name="view_ids"/>
<label for="menu_ids"/>
<field name="menu_ids"/>
</page>
<page string="Data &amp; Demo">
<label for="data_ids"/>
<field name="data_ids"/>
<label for="demo_ids"/>
<field name="demo_ids"/>
</page>
<page string="Reports">
<label for="report_ids" />
<field name="report_ids" />
</page>
<page string="Security">
<label for="group_ids"/>
<field name="group_ids"/>
<label for="right_ids"/>
<field name="right_ids"/>
<label for="rule_ids"/>
<field name="rule_ids"/>
</page>
<page string="Workflows">
<label for="activity_ids" />
<field name="activity_ids" />
<label for="transition_ids" />
<field name="transition_ids" />
</page>
<page string="Website">
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="open_module_prototyper_list" model="ir.actions.act_window">
<field name="name">Prototypes</field>
<field name="res_model">module_prototyper</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="module_prototyper_base_tree_view"/>
</record>
<record id="open_module_prototyper_list" model="ir.actions.act_window">
<field name="name">Prototypes</field>
<field name="res_model">module_prototyper</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="module_prototyper_base_tree_view"/>
</record>
<!--Here a menu is created to help user to have all what he needs-->
<!--under his mouse with ease-->
<menuitem id="menu_module_prototyper"
name="Module Prototypes"
parent="base.menu_administration"
sequence="1"/>
<!--Here a menu is created to help user to have all what he needs-->
<!--under his mouse with ease-->
<menuitem id="menu_module_prototyper"
name="Module Prototypes"
parent="base.menu_administration"
sequence="1"/>
<menuitem id="menu_open_module_prototyper"
action="open_module_prototyper_list"
parent="menu_module_prototyper"
sequence="1"
groups="base.group_system"/>
<menuitem id="menu_open_module_prototyper"
action="open_module_prototyper_list"
parent="menu_module_prototyper"
sequence="1"
groups="base.group_system"/>
<menuitem action="base.action_ui_view"
id="menu_action_ui_view"
parent="menu_module_prototyper"
sequence="2"
groups="base.group_system"/>
<menuitem action="base.action_ui_view"
id="menu_action_ui_view"
parent="menu_module_prototyper"
sequence="2"
groups="base.group_system"/>
<menuitem action="base.grant_menu_access"
id="menu_grant_menu_access"
parent="menu_module_prototyper"
sequence="3"
groups="base.group_system"/>
<menuitem action="base.grant_menu_access"
id="menu_grant_menu_access"
parent="menu_module_prototyper"
sequence="3"
groups="base.group_system"/>
<menuitem action="base.action_model_fields"
id="ir_model_model_fields"
parent="menu_module_prototyper"
sequence="4"
groups="base.group_system"/>
<menuitem action="base.action_model_fields"
id="ir_model_model_fields"
parent="menu_module_prototyper"
sequence="4"
groups="base.group_system"/>
</data>
</openerp>
</odoo>

2
module_prototyper/wizard/__init__.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution

25
module_prototyper/wizard/module_prototyper_module_export.py

@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
# ############################################################################# # #############################################################################
# #
# OpenERP, Open Source Management Solution # OpenERP, Open Source Management Solution
@ -26,20 +26,21 @@ import os
import zipfile import zipfile
from collections import namedtuple from collections import namedtuple
from openerp import fields, models, api
from odoo import fields, models, api
class PrototypeModuleExport(models.TransientModel): class PrototypeModuleExport(models.TransientModel):
_name = "module_prototyper.module.export" _name = "module_prototyper.module.export"
def _default_api_version(self):
return self.env.ref('module_prototyper.api_version_100').id
name = fields.Char('File Name', readonly=True) name = fields.Char('File Name', readonly=True)
api_version = fields.Selection(
[
('8.0', '8.0'),
],
'API version',
api_version = fields.Many2one(
comodel_name='module_prototyper.api_version',
string='API version',
required=True, required=True,
default='8.0'
default=_default_api_version
) )
data = fields.Binary('File', readonly=True) data = fields.Binary('File', readonly=True)
state = fields.Selection( state = fields.Selection(
@ -63,8 +64,8 @@ class PrototypeModuleExport(models.TransientModel):
active_model = self._context.get('active_model') active_model = self._context.get('active_model')
# checking if the wizard was called by a prototype. # checking if the wizard was called by a prototype.
msg = '{} has to be called from a "module_prototyper" , not a "{}"'
assert active_model == 'module_prototyper', msg.format(
msg = '%s has to be called from a "module_prototyper" , not a "%s"'
assert active_model == 'module_prototyper', msg % (
self, active_model self, active_model
) )
@ -82,7 +83,7 @@ class PrototypeModuleExport(models.TransientModel):
wizard.write( wizard.write(
{ {
'name': '{}.zip'.format(zip_name),
'name': '%s.zip' % (zip_name,),
'state': 'get', 'state': 'get',
'data': base64.encodestring(zip_details.stringIO.getvalue()) 'data': base64.encodestring(zip_details.stringIO.getvalue())
} }
@ -112,7 +113,7 @@ class PrototypeModuleExport(models.TransientModel):
# setting the jinja environment. # setting the jinja environment.
# They will help the program to find the template to render the # They will help the program to find the template to render the
# files with. # files with.
prototype.set_jinja_env(wizard.api_version)
prototype.setup_env(wizard.api_version)
# generate_files ask the prototype to investigate the input and # generate_files ask the prototype to investigate the input and
# to generate the file templates according to it. zip_files, # to generate the file templates according to it. zip_files,

68
module_prototyper/wizard/module_prototyper_module_export_view.xml

@ -1,43 +1,41 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<openerp>
<data>
<odoo>
<record id="view_module_export_wizard" model="ir.ui.view"> <record id="view_module_export_wizard" model="ir.ui.view">
<field name="name">Export Module</field>
<field name="model">module_prototyper.module.export</field>
<field name="arch" type="xml">
<form string="Export Module">
<field name="name" invisible="1"/>
<field name="state" invisible="1"/>
<group string="Export Settings" states="choose" col="6">
<group colspan="2">
<field name="api_version"/>
</group>
<group colspan="4">
</group>
</group>
<div states="get">
<h2>Export Complete</h2>
<p>Here is the exported module: <field name="data" readonly="1" filename="name"/></p>
</div>
<footer states="choose">
<button name="action_export" string="Export" type="object" class="oe_highlight"/> or
<button special="cancel" string="Cancel" type="object" class="oe_link"/>
</footer>
<footer states="get">
<button special="cancel" string="Close" type="object"/>
</footer>
</form>
</field>
<field name="name">Export Module</field>
<field name="model">module_prototyper.module.export</field>
<field name="arch" type="xml">
<form string="Export Module">
<field name="name" invisible="1"/>
<field name="state" invisible="1"/>
<group string="Export Settings" states="choose" col="6">
<group colspan="2">
<field name="api_version" widget="selection"/>
</group>
<group colspan="4">
</group>
</group>
<div states="get">
<h2>Export Complete</h2>
<p>Here is the exported module: <field name="data" readonly="1" filename="name"/></p>
</div>
<footer states="choose">
<button name="action_export" string="Export" type="object" class="oe_highlight"/> or
<button special="cancel" string="Cancel" type="object" class="oe_link"/>
</footer>
<footer states="get">
<button special="cancel" string="Close" type="object"/>
</footer>
</form>
</field>
</record> </record>
<record id="button_module_export_action" model="ir.actions.act_window"> <record id="button_module_export_action" model="ir.actions.act_window">
<field name="name">Export Module</field>
<field name="res_model">module_prototyper.module.export</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_module_export_wizard"/>
<field name="target">new</field>
<field name="name">Export Module</field>
<field name="res_model">module_prototyper.module.export</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_module_export_wizard"/>
<field name="target">new</field>
</record> </record>
</data>
</openerp>
</odoo>
Loading…
Cancel
Save