Browse Source
[IMP] prototype: added helper fields and placeholders on new fields.
[IMP] prototype: added helper fields and placeholders on new fields.
[IMP] prototype: no more bug when no icon, commented no implemented page in the view. [IMP] prototype: better management of special cases. [IMP] prototype: prototype.py removed print statement and shadowing of "fields". [IMP] prototype -> module_prototyper [IMP] module_prototyper: gathered menuitems that is helpfull to create a prototype under the menu 'Module Prototypes' [IMP] module_prototyper: more comment and docstrings. [IMP] module_prototyper: translations. [FIX] module_prototyper: pep8 [IMP] update module_prototyper: * pump up the version of the module to 0.3 * replace ir.ui.model by ir.ui.view in generated xml views * improve pep8 compatibility of generation of models [IMP] update module_prototyper: update of README with versions.pull/107/head
Jordi Riera
10 years ago
committed by
Maxime Chambreuil
53 changed files with 1543 additions and 1467 deletions
-
4module_prototyper/README.rst
-
59module_prototyper/README.rst~HEAD
-
2module_prototyper/__openerp__.py
-
14module_prototyper/__openerp__.py~HEAD
-
10module_prototyper/i18n/fr.po
-
338module_prototyper/i18n/fr.po~HEAD
-
5module_prototyper/models/__init__.py~HEAD
-
23module_prototyper/models/ir_model_fields.py~HEAD
-
556module_prototyper/models/module_prototyper.py~HEAD
-
3module_prototyper/templates/8.0/__init__.py.template
-
3module_prototyper/templates/8.0/__init__.py.template~HEAD
-
33module_prototyper/templates/8.0/__openerp__.py.template
-
38module_prototyper/templates/8.0/__openerp__.py.template~HEAD
-
13module_prototyper/templates/8.0/data/model_name.xml.template
-
17module_prototyper/templates/8.0/data/model_name.xml.template~HEAD
-
32module_prototyper/templates/8.0/header.template
-
26module_prototyper/templates/8.0/header.template~HEAD
-
7module_prototyper/templates/8.0/models/__init__.py.template
-
9module_prototyper/templates/8.0/models/__init__.py.template~HEAD
-
66module_prototyper/templates/8.0/models/model_name.py.template
-
68module_prototyper/templates/8.0/models/model_name.py.template~HEAD
-
23module_prototyper/templates/8.0/views/model_menus.xml.template
-
29module_prototyper/templates/8.0/views/model_menus.xml.template~HEAD
-
16module_prototyper/templates/8.0/views/model_views.xml.template
-
17module_prototyper/templates/8.0/views/model_views.xml.template~HEAD
-
4module_prototyper/tests/__init__.py~HEAD
-
36module_prototyper/tests/test_prototype.py~HEAD
-
9module_prototyper/tests/test_prototype_module_export.py~HEAD
-
51module_prototyper/views/ir_model_fields_view.xml~HEAD
-
3module_prototyper/views/module_prototyper_view.xml
-
145module_prototyper/views/module_prototyper_view.xml~HEAD
-
3module_prototyper/wizard/module_prototyper_module_export.py
-
59module_prototyper/wizard/module_prototyper_module_export.py~HEAD
-
2prototype/demo/prototype.prototype.csv
-
272prototype/i18n/fr.po
-
268prototype/i18n/prototype.pot
-
339prototype/models/prototype.py
-
2prototype/security/ir.model.access.csv
-
BINprototype/static/description/icon.png
-
8prototype/templates/8.0/data/model_name.xml.template
-
8prototype/templates/8.0/demo/model_name.xml.template
-
22prototype/templates/8.0/header.template
-
6prototype/templates/8.0/models/__init__.py.template
-
21prototype/templates/8.0/models/model_name.py.template
-
4prototype/templates/8.0/security/ir.model.access.csv.template
-
10prototype/templates/8.0/security/model_name.xml.template
-
24prototype/templates/8.0/views/model_menus.xml.template
-
23prototype/templates/8.0/views/model_views.xml.template
-
28prototype/tests/__init__.py
-
30prototype/views/ir_model_fields_view.xml
-
103prototype/views/prototype_view.xml
-
22prototype/wizard/__init__.py
-
43prototype/wizard/prototype_module_export_view.xml
@ -0,0 +1,338 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * module_prototyper |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 8.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2015-01-02 17:07+0000\n" |
||||
|
"PO-Revision-Date: 2015-01-02 12:18-0500\n" |
||||
|
"Last-Translator: Jordi Riera <jordi.riera@savoirfairelinux.com>\n" |
||||
|
"Language-Team: \n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: 8bit\n" |
||||
|
"Plural-Forms: \n" |
||||
|
"X-Generator: Poedit 1.5.4\n" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: selection:module_prototyper.module.export,api_version:0 |
||||
|
msgid "8.0" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper.module.export,api_version:0 |
||||
|
msgid "API version" |
||||
|
msgstr "Version de l'API" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,right_ids:0 |
||||
|
msgid "Access Rights" |
||||
|
msgstr "Liste des contrôles d'accès" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,application:0 |
||||
|
msgid "Application" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,author:0 |
||||
|
msgid "Author" |
||||
|
msgstr "Auteur" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,auto_install:0 |
||||
|
msgid "Auto Install" |
||||
|
msgstr "Installation automatique" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Cancel" |
||||
|
msgstr "Annuler" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,category_id:0 |
||||
|
msgid "Category" |
||||
|
msgstr "Catégorie" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,application:0 |
||||
|
msgid "Check if the module is an Odoo application." |
||||
|
msgstr "Cocher si le module est une application Odoo." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,auto_install:0 |
||||
|
msgid "Check if the module should be install by default." |
||||
|
msgstr "Cocher si le module devrait être installé par défaut." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Close" |
||||
|
msgstr "Fermer" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,create_uid:0 |
||||
|
#: field:module_prototyper.module.export,create_uid:0 |
||||
|
msgid "Created by" |
||||
|
msgstr "Créé par" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,create_date:0 |
||||
|
#: field:module_prototyper.module.export,create_date:0 |
||||
|
msgid "Created on" |
||||
|
msgstr "Créé le" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,data_ids:0 |
||||
|
msgid "Data filters" |
||||
|
msgstr "Filtres pour les données" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,demo_ids:0 |
||||
|
msgid "Demo filters" |
||||
|
msgstr "Filtres pour les données de démo" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view |
||||
|
#: field:module_prototyper,dependency_ids:0 |
||||
|
msgid "Dependencies" |
||||
|
msgstr "Dépendances" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view |
||||
|
#: field:module_prototyper,description:0 |
||||
|
msgid "Description" |
||||
|
msgstr "Descriptions" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Export" |
||||
|
msgstr "Exporter" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Export Complete" |
||||
|
msgstr "Export terminé" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.actions.act_window,name:module_prototyper.button_module_export_action |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Export Module" |
||||
|
msgstr "Exporter le module" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Export Settings" |
||||
|
msgstr "Configuration de l'export" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.model,name:module_prototyper.model_ir_model_fields |
||||
|
#: model:ir.ui.menu,name:module_prototyper.ir_model_model_fields |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view |
||||
|
#: field:module_prototyper,field_ids:0 |
||||
|
msgid "Fields" |
||||
|
msgstr "Champs" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper.module.export,data:0 |
||||
|
msgid "File" |
||||
|
msgstr "Fichier" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper.module.export,name:0 |
||||
|
msgid "File Name" |
||||
|
msgstr "Nom du fichier" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,group_ids:0 |
||||
|
msgid "Groups" |
||||
|
msgstr "Groupes" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:ir.model.fields,helper:0 |
||||
|
msgid "Helper" |
||||
|
msgstr "Texte d'aide" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper.module.export:module_prototyper.view_module_export_wizard |
||||
|
msgid "Here is the exported module:" |
||||
|
msgstr "Voici le module exporté :" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,id:0 field:module_prototyper.module.export,id:0 |
||||
|
msgid "ID" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,icon_image:0 |
||||
|
msgid "Icon" |
||||
|
msgstr "Icône" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view |
||||
|
msgid "Interface" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,write_uid:0 |
||||
|
#: field:module_prototyper.module.export,write_uid:0 |
||||
|
msgid "Last Updated by" |
||||
|
msgstr "Mis à jour par" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,write_date:0 |
||||
|
#: field:module_prototyper.module.export,write_date:0 |
||||
|
msgid "Last Updated on" |
||||
|
msgstr "Mis à jour le" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,licence:0 |
||||
|
msgid "License" |
||||
|
msgstr "Licence" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,maintainer:0 |
||||
|
msgid "Maintainer" |
||||
|
msgstr "Mainteneur" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.ui.menu,name:module_prototyper.menu_grant_menu_access |
||||
|
#: field:module_prototyper,menu_ids:0 |
||||
|
msgid "Menu Items" |
||||
|
msgstr "Éléments du menu" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_form_view |
||||
|
msgid "Module" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,human_name:0 |
||||
|
msgid "Module Name" |
||||
|
msgstr "Nom du module" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.model,name:module_prototyper.model_module_prototyper |
||||
|
msgid "Module Prototyper" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.ui.menu,name:module_prototyper.menu_module_prototyper |
||||
|
msgid "Module Prototypers" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:ir.model:module_prototyper.view_ir_model_form |
||||
|
msgid "Notes" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:ir.model.fields,notes:0 |
||||
|
msgid "Notes to developers" |
||||
|
msgstr "Notes aux développeurs" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:ir.model.fields:module_prototyper.view_ir_model_fields_form |
||||
|
msgid "" |
||||
|
"Notes to help developers to understand the work or advanced features that " |
||||
|
"should be added, ie: onchange, etc." |
||||
|
msgstr "" |
||||
|
"Notes pour aider les développeurs à comprendre le travail effectué ou les " |
||||
|
"ajouts à faire. Exemple: onchanges, etc." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:module_prototyper:module_prototyper.module_prototyper_base_tree_view |
||||
|
msgid "Prototype" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.actions.act_window,name:module_prototyper.open_module_prototyper_list |
||||
|
#: model:ir.ui.menu,name:module_prototyper.menu_open_module_prototyper |
||||
|
msgid "Prototypes" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,rule_ids:0 |
||||
|
msgid "Record Rules" |
||||
|
msgstr "Règles sur les enregistrements" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper.module.export,state:0 |
||||
|
msgid "State" |
||||
|
msgstr "État" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,summary:0 |
||||
|
msgid "Summary" |
||||
|
msgstr "Résumé" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,name:0 |
||||
|
msgid "Technical Name" |
||||
|
msgstr "Nom technique" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: view:ir.model.fields:module_prototyper.view_ir_model_fields_form |
||||
|
msgid "Text that will be set as the helper of the field..." |
||||
|
msgstr "Texte qui sera placé en tant que texte d'aide du champs." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,human_name:0 |
||||
|
msgid "" |
||||
|
"The Module Name will be used as the displayed name of the exported module." |
||||
|
msgstr "Le nom du module sera affiché en tant que nom du module exporté." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,icon_image:0 |
||||
|
msgid "" |
||||
|
"The icon set up here will be used as the icon for the exported module also" |
||||
|
msgstr "L'icône sera utilisé comme icône du module exporté." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,data_ids:0 |
||||
|
msgid "The records matching the filters will be added as data." |
||||
|
msgstr "" |
||||
|
"Les enregistrements correspondant aux critères des filtres seront exportées " |
||||
|
"dans le module comme données." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,demo_ids:0 |
||||
|
msgid "The records matching the filters will be added as demo data." |
||||
|
msgstr "" |
||||
|
"Les enregistrements correspondant aux critères des filtres seront exportées " |
||||
|
"dans le module comme données de démo." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: help:module_prototyper,name:0 |
||||
|
msgid "" |
||||
|
"The technical name will be used to define the name of the exported module, " |
||||
|
"the name of the model." |
||||
|
msgstr "Le nom technique sera utilisé comme nom du module exporté." |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,version:0 |
||||
|
msgid "Version" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: model:ir.ui.menu,name:module_prototyper.menu_action_ui_view |
||||
|
#: field:module_prototyper,view_ids:0 |
||||
|
msgid "Views" |
||||
|
msgstr "Vues" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: field:module_prototyper,website:0 |
||||
|
msgid "Website" |
||||
|
msgstr "Site web" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: selection:module_prototyper.module.export,state:0 |
||||
|
msgid "choose" |
||||
|
msgstr "choisir" |
||||
|
|
||||
|
#. module: module_prototyper |
||||
|
#: selection:module_prototyper.module.export,state:0 |
||||
|
msgid "get" |
||||
|
msgstr "récupérer" |
@ -0,0 +1,556 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
# ############################################################################# |
||||
|
# |
||||
|
# OpenERP, Open Source Management Solution |
||||
|
# This module copyright (C) 2010 - 2014 Savoir-faire Linux |
||||
|
# (<http://www.savoirfairelinux.com>). |
||||
|
# |
||||
|
# 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/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
import base64 |
||||
|
import logging |
||||
|
import lxml.etree |
||||
|
import os |
||||
|
import re |
||||
|
import textwrap |
||||
|
|
||||
|
from collections import namedtuple |
||||
|
from datetime import date |
||||
|
|
||||
|
from jinja2 import Environment, FileSystemLoader |
||||
|
|
||||
|
from openerp import models, api, fields |
||||
|
from openerp.tools.safe_eval import safe_eval |
||||
|
|
||||
|
from .default_description import get_default_description |
||||
|
from . import licenses |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class ModulePrototyper(models.Model): |
||||
|
"""Module Prototyper gathers different information from all over the |
||||
|
database to build a prototype of module. |
||||
|
We are calling it a prototype as it will most likely need to be reviewed |
||||
|
by a developer to fix glitch that would sneak it during the generation of |
||||
|
files but also to add not supported features. |
||||
|
""" |
||||
|
_name = "module_prototyper" |
||||
|
_description = "Module Prototyper" |
||||
|
|
||||
|
license = fields.Selection( |
||||
|
[ |
||||
|
(licenses.GPL3, 'GPL Version 3'), |
||||
|
(licenses.GPL3_L, 'GPL-3 or later version'), |
||||
|
(licenses.LGPL3, 'LGPL-3'), |
||||
|
(licenses.LGPL3_L, 'LGPL-3 or later version'), |
||||
|
(licenses.AGPL3, 'Affero GPL-3'), |
||||
|
(licenses.OSI, 'Other OSI Approved Licence'), |
||||
|
('Other proprietary', 'Other Proprietary') |
||||
|
], |
||||
|
string='License', |
||||
|
default=licenses.AGPL3, |
||||
|
) |
||||
|
name = fields.Char( |
||||
|
'Technical Name', required=True, |
||||
|
help=('The technical name will be used to define the name of ' |
||||
|
'the exported module, the name of the model.') |
||||
|
) |
||||
|
category_id = fields.Many2one('ir.module.category', 'Category') |
||||
|
human_name = fields.Char( |
||||
|
'Module Name', required=True, |
||||
|
help=('The Module Name will be used as the displayed name of the ' |
||||
|
'exported module.') |
||||
|
) |
||||
|
summary = fields.Char('Summary', required=True, |
||||
|
help=('Enter a summary of your module')) |
||||
|
description = fields.Text( |
||||
|
'Description', |
||||
|
required=True, |
||||
|
help=('Enter the description of your module, what it does, how to ' |
||||
|
'install, configure and use it, the roadmap or known issues. ' |
||||
|
'The description will be exported in README.rst'), |
||||
|
default=get_default_description |
||||
|
) |
||||
|
author = fields.Char('Author', required=True, help=('Enter your name')) |
||||
|
maintainer = fields.Char( |
||||
|
'Maintainer', |
||||
|
help=('Enter the name of the person or organization who will ' |
||||
|
'maintain this module') |
||||
|
) |
||||
|
website = fields.Char('Website', help=('Enter the URL of your website')) |
||||
|
icon_image = fields.Binary( |
||||
|
'Icon', |
||||
|
help=('The icon set up here will be used as the icon ' |
||||
|
'for the exported module also') |
||||
|
) |
||||
|
version = fields.Char( |
||||
|
'Version', |
||||
|
size=3, |
||||
|
default='0.1', |
||||
|
help=('Enter the version of your module with 2 digits') |
||||
|
) |
||||
|
auto_install = fields.Boolean( |
||||
|
'Auto Install', |
||||
|
default=False, |
||||
|
help='Check if the module should be install by default.' |
||||
|
) |
||||
|
application = fields.Boolean( |
||||
|
'Application', |
||||
|
default=False, |
||||
|
help='Check if the module is an Odoo application.' |
||||
|
) |
||||
|
# Relations |
||||
|
dependency_ids = fields.Many2many( |
||||
|
'ir.module.module', 'module_prototyper_module_rel', |
||||
|
'module_prototyper_id', 'module_id', |
||||
|
'Dependencies', |
||||
|
help=('Enter the list of required modules that need to be installed ' |
||||
|
'for your module to work properly') |
||||
|
) |
||||
|
data_ids = fields.Many2many( |
||||
|
'ir.filters', |
||||
|
'prototype_data_rel', |
||||
|
'module_prototyper_id', 'filter_id', |
||||
|
'Data filters', |
||||
|
help="The records matching the filters will be added as data." |
||||
|
) |
||||
|
demo_ids = fields.Many2many( |
||||
|
'ir.filters', |
||||
|
'prototype_demo_rel', |
||||
|
'module_prototyper_id', 'filter_id', |
||||
|
'Demo filters', |
||||
|
help="The records matching the filters will be added as demo data." |
||||
|
) |
||||
|
field_ids = fields.Many2many( |
||||
|
'ir.model.fields', 'prototype_fields_rel', |
||||
|
'module_prototyper_id', 'field_id', 'Fields', |
||||
|
help=('Enter the list of fields that you have created or modified ' |
||||
|
'and want to export in this module. New models will be ' |
||||
|
'exported as long as you choose one of his fields.') |
||||
|
) |
||||
|
menu_ids = fields.Many2many( |
||||
|
'ir.ui.menu', 'prototype_menu_rel', |
||||
|
'module_prototyper_id', 'menu_id', 'Menu Items', |
||||
|
help=('Enter the list of menu items that you have created and want ' |
||||
|
'to export in this module. Related windows actions will be ' |
||||
|
'exported as well.') |
||||
|
) |
||||
|
view_ids = fields.Many2many( |
||||
|
'ir.ui.view', 'prototype_view_rel', |
||||
|
'module_prototyper_id', 'view_id', 'Views', |
||||
|
help=('Enter the list of views that you have created and want to ' |
||||
|
'export in this module.') |
||||
|
) |
||||
|
group_ids = fields.Many2many( |
||||
|
'res.groups', 'prototype_groups_rel', |
||||
|
'module_prototyper_id', 'group_id', 'Groups', |
||||
|
help=('Enter the list of groups that you have created and want to ' |
||||
|
'export in this module.') |
||||
|
) |
||||
|
right_ids = fields.Many2many( |
||||
|
'ir.model.access', 'prototype_rights_rel', |
||||
|
'module_prototyper_id', 'right_id', |
||||
|
'Access Rights', |
||||
|
help=('Enter the list of access rights that you have created and ' |
||||
|
'want to export in this module.') |
||||
|
) |
||||
|
rule_ids = fields.Many2many( |
||||
|
'ir.rule', 'prototype_rule_rel', |
||||
|
'module_prototyper_id', 'rule_id', 'Record Rules', |
||||
|
help=('Enter the list of record rules that you have created and ' |
||||
|
'want to export in this module.') |
||||
|
) |
||||
|
report_ids = fields.Many2many( |
||||
|
'ir.actions.report.xml', 'prototype_report_rel', |
||||
|
'module_prototyper_id', 'report_id', 'Reports', |
||||
|
help=('Enter the list of reports 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', |
||||
|
help=('Enter the list of workflow activities that you have created ' |
||||
|
'and want to export in this module') |
||||
|
) |
||||
|
transition_ids = fields.Many2many( |
||||
|
'workflow.transition', 'prototype_wf_transition_rel', |
||||
|
'module_prototyper_id', 'transition_id', 'Transitions', |
||||
|
help=('Enter the list of workflow transitions that you have created ' |
||||
|
'and want to export in this module') |
||||
|
) |
||||
|
|
||||
|
_env = None |
||||
|
_data_files = () |
||||
|
_demo_files = () |
||||
|
_field_descriptions = None |
||||
|
File_details = namedtuple('file_details', ['filename', 'filecontent']) |
||||
|
template_path = '{}/../templates/'.format(os.path.dirname(__file__)) |
||||
|
|
||||
|
@api.model |
||||
|
def set_jinja_env(self, api_version): |
||||
|
"""Set the Jinja2 environment. |
||||
|
The environment will helps the system to find the templates to render. |
||||
|
:param api_version: string, odoo api |
||||
|
:return: jinja2.Environment instance. |
||||
|
""" |
||||
|
if self._env is None: |
||||
|
self._env = Environment( |
||||
|
lstrip_blocks=True, |
||||
|
trim_blocks=True, |
||||
|
loader=FileSystemLoader( |
||||
|
os.path.join(self.template_path, api_version) |
||||
|
) |
||||
|
) |
||||
|
return self._env |
||||
|
|
||||
|
def set_field_descriptions(self): |
||||
|
"""Mock the list of fields into dictionary. |
||||
|
It allows us to add or change attributes of the fields. |
||||
|
|
||||
|
:return: None |
||||
|
""" |
||||
|
for field in self.field_ids: |
||||
|
field_description = {} |
||||
|
# This will mock a field record. |
||||
|
# the mock will allow us to add data or modify the data |
||||
|
# of the field (like for the name) with keeping all the |
||||
|
# attributes of the record. |
||||
|
field_description.update({ |
||||
|
attr_name: getattr(field, attr_name) |
||||
|
for attr_name in dir(field) |
||||
|
if not attr_name[0] == '_' |
||||
|
}) |
||||
|
field_description['name'] = self.unprefix(field.name) |
||||
|
self._field_descriptions[field] = field_description |
||||
|
|
||||
|
@api.model |
||||
|
def generate_files(self): |
||||
|
""" Generates the files from the details of the prototype. |
||||
|
:return: tuple |
||||
|
""" |
||||
|
assert self._env is not None, \ |
||||
|
'Run set_env(api_version) before to generate files.' |
||||
|
|
||||
|
# Avoid sharing these across instances |
||||
|
self._data_files = [] |
||||
|
self._demo_files = [] |
||||
|
self._field_descriptions = {} |
||||
|
self.set_field_descriptions() |
||||
|
file_details = [] |
||||
|
file_details.extend(self.generate_models_details()) |
||||
|
file_details.extend(self.generate_views_details()) |
||||
|
file_details.extend(self.generate_menus_details()) |
||||
|
file_details.append(self.generate_module_init_file_details()) |
||||
|
file_details.extend(self.generate_data_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()) |
||||
|
if self.icon_image: |
||||
|
file_details.append(self.save_icon()) |
||||
|
|
||||
|
return file_details |
||||
|
|
||||
|
@api.model |
||||
|
def save_icon(self): |
||||
|
"""Save the icon of the prototype as a image. |
||||
|
The image is used afterwards as the icon of the exported module. |
||||
|
|
||||
|
:return: FileDetails instance |
||||
|
""" |
||||
|
# TODO: The image is not always a jpg. |
||||
|
# 2 ways to do it: |
||||
|
# * find a way to detect image type from the data |
||||
|
# * add document as a dependency. |
||||
|
# The second options seems to be better, as Document is a base module. |
||||
|
return self.File_details( |
||||
|
os.path.join('static', 'description', 'icon.jpg'), |
||||
|
base64.b64decode(self.icon_image) |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def generate_module_openerp_file_details(self): |
||||
|
"""Wrapper to generate the __openerp__.py file of the module.""" |
||||
|
return self.generate_file_details( |
||||
|
'__openerp__.py', |
||||
|
'__openerp__.py.template', |
||||
|
prototype=self, |
||||
|
data_files=self._data_files, |
||||
|
demo_fiels=self._demo_files, |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def generate_module_init_file_details(self): |
||||
|
"""Wrapper to generate the __init__.py file of the module.""" |
||||
|
return self.generate_file_details( |
||||
|
'__init__.py', |
||||
|
'__init__.py.template', |
||||
|
# no import models if no work of fields in |
||||
|
# the prototype |
||||
|
models=bool(self.field_ids) |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def generate_models_details(self): |
||||
|
""" |
||||
|
Finds the models from the list of fields and generates |
||||
|
the __init__ file and each models files (one by class). |
||||
|
""" |
||||
|
files = [] |
||||
|
# TODO: doesn't work as need to find the module to import |
||||
|
# and it is not necessary the name of the model the fields |
||||
|
# belongs to. |
||||
|
# ie. field.cell_phone is defined in a model inheriting from |
||||
|
# res.partner. |
||||
|
# How do we find the module the field was defined in? |
||||
|
# dependencies = set([dep.id for dep in self.dependencies]) |
||||
|
|
||||
|
relations = {} |
||||
|
field_descriptions = self._field_descriptions or {} |
||||
|
for field in field_descriptions.itervalues(): |
||||
|
model = field.get('model_id') |
||||
|
relations.setdefault(model, []).append(field) |
||||
|
# dependencies.add(model.id) |
||||
|
|
||||
|
# blind update of dependencies. |
||||
|
# self.write({ |
||||
|
# 'dependencies': [(6, 0, [id_ for id_ in dependencies])] |
||||
|
# }) |
||||
|
|
||||
|
files.append(self.generate_models_init_details(relations.keys())) |
||||
|
for model, custom_fields in relations.iteritems(): |
||||
|
files.append(self.generate_model_details(model, custom_fields)) |
||||
|
|
||||
|
return files |
||||
|
|
||||
|
@api.model |
||||
|
def generate_models_init_details(self, ir_models): |
||||
|
"""Wrapper to generate the __init__.py file in models folder.""" |
||||
|
return self.generate_file_details( |
||||
|
'models/__init__.py', |
||||
|
'models/__init__.py.template', |
||||
|
models=[ |
||||
|
self.friendly_name(ir_model.model) |
||||
|
for ir_model in ir_models |
||||
|
] |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def generate_views_details(self): |
||||
|
"""Wrapper to generate the views files.""" |
||||
|
relations = {} |
||||
|
for view in self.view_ids: |
||||
|
relations.setdefault(view.model, []).append(view) |
||||
|
|
||||
|
views_details = [] |
||||
|
for model, views in relations.iteritems(): |
||||
|
filepath = 'views/{}_view.xml'.format( |
||||
|
self.friendly_name(self.unprefix(model)) |
||||
|
) |
||||
|
views_details.append( |
||||
|
self.generate_file_details( |
||||
|
filepath, |
||||
|
'views/model_views.xml.template', |
||||
|
views=views |
||||
|
) |
||||
|
) |
||||
|
self._data_files.append(filepath) |
||||
|
|
||||
|
return views_details |
||||
|
|
||||
|
@api.model |
||||
|
def generate_menus_details(self): |
||||
|
"""Wrapper to generate the menus files.""" |
||||
|
relations = {} |
||||
|
for menu in self.menu_ids: |
||||
|
if menu.action and menu.action.res_model: |
||||
|
model = self.unprefix(menu.action.res_model) |
||||
|
else: |
||||
|
model = 'ir_ui' |
||||
|
relations.setdefault(model, []).append(menu) |
||||
|
|
||||
|
menus_details = [] |
||||
|
for model_name, menus in relations.iteritems(): |
||||
|
model_name = self.unprefix(model_name) |
||||
|
filepath = 'views/{}_menus.xml'.format( |
||||
|
self.friendly_name(model_name) |
||||
|
) |
||||
|
menus_details.append( |
||||
|
self.generate_file_details( |
||||
|
filepath, |
||||
|
'views/model_menus.xml.template', |
||||
|
menus=menus, |
||||
|
) |
||||
|
) |
||||
|
self._data_files.append(filepath) |
||||
|
|
||||
|
return menus_details |
||||
|
|
||||
|
@api.model |
||||
|
def generate_model_details(self, model, field_descriptions): |
||||
|
"""Wrapper to generate the python file for the model. |
||||
|
|
||||
|
:param model: ir.model record. |
||||
|
:param field_descriptions: list of ir.model.fields records. |
||||
|
:return: FileDetails instance. |
||||
|
""" |
||||
|
python_friendly_name = self.friendly_name(self.unprefix(model.model)) |
||||
|
return self.generate_file_details( |
||||
|
'models/{}.py'.format(python_friendly_name), |
||||
|
'models/model_name.py.template', |
||||
|
name=python_friendly_name, |
||||
|
model=model, |
||||
|
fields=field_descriptions, |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def generate_data_files(self): |
||||
|
""" Generate data and demo files """ |
||||
|
data, demo = {}, {} |
||||
|
filters = [ |
||||
|
(data, ir_filter) |
||||
|
for ir_filter in self.data_ids |
||||
|
] + [ |
||||
|
(demo, ir_filter) |
||||
|
for ir_filter in self.demo_ids |
||||
|
] |
||||
|
|
||||
|
for target, ir_filter in filters: |
||||
|
model = ir_filter.model_id |
||||
|
model_obj = self.env[model] |
||||
|
target.setdefault(model, model_obj.browse([])) |
||||
|
target[model] |= model_obj.search(safe_eval(ir_filter.domain)) |
||||
|
|
||||
|
res = [] |
||||
|
for prefix, model_data, file_list in [ |
||||
|
('data', data, self._data_files), |
||||
|
('demo', demo, self._demo_files)]: |
||||
|
for model_name, records in model_data.iteritems(): |
||||
|
fname = self.friendly_name(self.unprefix(model_name)) |
||||
|
filename = '{0}/{1}.xml'.format(prefix, fname) |
||||
|
self._data_files.append(filename) |
||||
|
|
||||
|
res.append(self.generate_file_details( |
||||
|
filename, |
||||
|
'data/model_name.xml.template', |
||||
|
model=model_name, |
||||
|
records=records, |
||||
|
)) |
||||
|
|
||||
|
return res |
||||
|
|
||||
|
@classmethod |
||||
|
def unprefix(cls, name): |
||||
|
if not name: |
||||
|
return name |
||||
|
return re.sub('^x_', '', name) |
||||
|
|
||||
|
@classmethod |
||||
|
def is_prefixed(cls, name): |
||||
|
return bool(re.match('^x_', name)) |
||||
|
|
||||
|
@classmethod |
||||
|
def friendly_name(cls, name): |
||||
|
return name.replace('.', '_') |
||||
|
|
||||
|
@classmethod |
||||
|
def fixup_domain(cls, domain): |
||||
|
""" Fix a domain according to unprefixing of fields """ |
||||
|
res = [] |
||||
|
for elem in domain: |
||||
|
if len(elem) == 3: |
||||
|
elem = list(elem) |
||||
|
elem[0] = cls.unprefix(elem[0]) |
||||
|
res.append(elem) |
||||
|
return res |
||||
|
|
||||
|
@classmethod |
||||
|
def fixup_arch(cls, archstr): |
||||
|
doc = lxml.etree.fromstring(archstr) |
||||
|
for elem in doc.xpath("//*[@name]"): |
||||
|
elem.attrib["name"] = cls.unprefix(elem.attrib["name"]) |
||||
|
|
||||
|
for elem in doc.xpath("//*[@attrs]"): |
||||
|
try: |
||||
|
attrs = safe_eval(elem.attrib["attrs"]) |
||||
|
except Exception: |
||||
|
_logger.error("Unable to eval attribute: %s, skipping", |
||||
|
elem.attrib["attrs"]) |
||||
|
continue |
||||
|
|
||||
|
if isinstance(attrs, dict): |
||||
|
for key, val in attrs.iteritems(): |
||||
|
if isinstance(val, (list, tuple)): |
||||
|
attrs[key] = cls.fixup_domain(val) |
||||
|
elem.attrib["attrs"] = repr(attrs) |
||||
|
|
||||
|
for elem in doc.xpath("//field"): |
||||
|
# Make fields self-closed by removing useless whitespace |
||||
|
if elem.text and not elem.text.strip(): |
||||
|
elem.text = None |
||||
|
|
||||
|
return lxml.etree.tostring(doc) |
||||
|
|
||||
|
@api.model |
||||
|
def generate_file_details(self, filename, template, **kwargs): |
||||
|
""" generate file details from jinja2 template. |
||||
|
:param filename: name of the file the content is related to |
||||
|
:param template: path to the file to render the content |
||||
|
:param kwargs: arguments of the template |
||||
|
:return: File_details instance |
||||
|
""" |
||||
|
template = self._env.get_template(template) |
||||
|
# keywords used in several templates. |
||||
|
kwargs.update( |
||||
|
{ |
||||
|
'export_year': date.today().year, |
||||
|
'author': self.author, |
||||
|
'website': self.website, |
||||
|
'license_text': licenses.get_license_text(self.license), |
||||
|
'cr': self._cr, |
||||
|
# Utility functions |
||||
|
'fixup_arch': self.fixup_arch, |
||||
|
'is_prefixed': self.is_prefixed, |
||||
|
'unprefix': self.unprefix, |
||||
|
'wrap': wrap, |
||||
|
|
||||
|
} |
||||
|
) |
||||
|
return self.File_details(filename, template.render(kwargs)) |
||||
|
|
||||
|
|
||||
|
# Utility functions for rendering templates |
||||
|
def wrap(text, **kwargs): |
||||
|
""" Wrap some text for inclusion in a template, returning lines |
||||
|
|
||||
|
keyword arguments available, from textwrap.TextWrapper: |
||||
|
|
||||
|
width=70 |
||||
|
initial_indent='' |
||||
|
subsequent_indent='' |
||||
|
expand_tabs=True |
||||
|
replace_whitespace=True |
||||
|
fix_sentence_endings=False |
||||
|
break_long_words=True |
||||
|
drop_whitespace=True |
||||
|
break_on_hyphens=True |
||||
|
""" |
||||
|
if not text: |
||||
|
return [] |
||||
|
wrapper = textwrap.TextWrapper(**kwargs) |
||||
|
# We join the lines and split them again to offer a stable api for |
||||
|
# the jinja2 templates, regardless of replace_whitspace=True|False |
||||
|
text = "\n".join(wrapper.wrap(text)) |
||||
|
return text.splitlines() |
@ -1,7 +1,6 @@ |
|||||
{% extends "header.template" %} |
{% extends "header.template" %} |
||||
{% block body %} |
{% block body %} |
||||
{% if models %} |
|
||||
|
|
||||
|
{% if models -%} |
||||
from . import models |
from . import models |
||||
{% endif %} |
{% endif %} |
||||
{% endblock %} |
{% endblock %} |
@ -1,6 +1,7 @@ |
|||||
{% extends "header.template" %} |
{% extends "header.template" %} |
||||
{% block body %} |
{% block body %} |
||||
{% if models -%} |
|
||||
|
{% if models %} |
||||
|
|
||||
from . import models |
from . import models |
||||
{% endif %} |
{% endif %} |
||||
{% endblock %} |
{% endblock %} |
@ -1,56 +1,60 @@ |
|||||
{% extends "header.template" %} |
{% extends "header.template" %} |
||||
{% block body %} |
{% block body %} |
||||
|
|
||||
{ |
{ |
||||
'name': '{{ prototype.name }}', |
|
||||
|
'name': '{{ prototype.human_name }}', |
||||
'version': '{{ prototype.version }}', |
'version': '{{ prototype.version }}', |
||||
|
|
||||
'author': '{{ prototype.author }}', |
'author': '{{ prototype.author }}', |
||||
'maintainer': '{{ prototype.maintainer }}', |
'maintainer': '{{ prototype.maintainer }}', |
||||
'website': '{{ prototype.website }}', |
'website': '{{ prototype.website }}', |
||||
'license': '{{ prototype.licence }}', |
|
||||
|
'license': '{{ prototype.license }}', |
||||
|
|
||||
# Categories can be used to filter modules in modules listing |
# 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 |
|
||||
|
# Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml # noqa |
||||
# for the full list |
# for the full list |
||||
'category': '{{ prototype.category_id.name }}', |
|
||||
|
{# Use with_context({}) to get english category #} |
||||
|
'category': '{{ prototype.with_context({}).category_id.name }}', |
||||
'summary': '{{ prototype.summary }}', |
'summary': '{{ prototype.summary }}', |
||||
'description': """ |
'description': """ |
||||
{{ prototype.description }} |
{{ prototype.description }} |
||||
|
|
||||
* Module exported by the prototype module for version 8.0. |
|
||||
* If you have any questions, please contact Savoir-faire Linux \ |
|
||||
|
* Module exported by the Module Prototyper module for version 8.0. |
||||
|
* If you have any questions, please contact Savoir-faire Linux |
||||
(support@savoirfairelinux.com) |
(support@savoirfairelinux.com) |
||||
""", |
""", |
||||
|
|
||||
# any module necessary for this one to work correctly |
# any module necessary for this one to work correctly |
||||
'depends': [ |
'depends': [ |
||||
{% for dependency in prototype.dependency_ids -%} |
|
||||
|
{% for dependency in prototype.dependency_ids %} |
||||
'{{ dependency.name }}', |
'{{ dependency.name }}', |
||||
{% endfor -%}], |
|
||||
|
{% endfor %} |
||||
|
], |
||||
'external_dependencies': { |
'external_dependencies': { |
||||
'python': [], |
'python': [], |
||||
}, |
}, |
||||
|
|
||||
# always loaded |
# always loaded |
||||
'data': [ |
'data': [ |
||||
{% for data_file in data_files -%} |
|
||||
|
{% for data_file in data_files %} |
||||
'{{ data_file }}', |
'{{ data_file }}', |
||||
{% endfor -%}], |
|
||||
|
{% endfor %} |
||||
|
], |
||||
# only loaded in demonstration mode |
# only loaded in demonstration mode |
||||
'demo': [ |
'demo': [ |
||||
{% for demo_file in prototype.demo_ids -%} |
|
||||
'{{ demo_file.name }}', |
|
||||
{% endfor -%}], |
|
||||
|
{% for demo_file in demo_files %} |
||||
|
'{{ demo_file }}', |
||||
|
{% endfor %} |
||||
|
], |
||||
|
|
||||
# used for Javascript Web CLient Testing with QUnit / PhantomJS |
# used for Javascript Web CLient Testing with QUnit / PhantomJS |
||||
# https://www.odoo.com/documentation/8.0/reference/javascript.html#testing-in-odoo-web-client |
|
||||
|
# https://www.odoo.com/documentation/8.0/reference/javascript.html#testing-in-odoo-web-client # noqa |
||||
'js': [], |
'js': [], |
||||
'css': [], |
'css': [], |
||||
'qweb': [], |
'qweb': [], |
||||
|
|
||||
'installable': True, |
'installable': True, |
||||
# Install this module automatically if all dependency have been previously and independently installed. |
|
||||
# Used for synergetic or glue modules. |
|
||||
|
# Install this module automatically if all dependency have been previously |
||||
|
# and independently installed. Used for synergetic or glue modules. |
||||
'auto_install': {{ prototype.auto_install }}, |
'auto_install': {{ prototype.auto_install }}, |
||||
'application': {{ prototype.application }}, |
'application': {{ prototype.application }}, |
||||
} |
} |
@ -1,17 +1,8 @@ |
|||||
<?xml version="1.0"?> |
<?xml version="1.0"?> |
||||
<openerp> |
<openerp> |
||||
<data> |
<data> |
||||
{% for record in records %} |
|
||||
<!-- |
|
||||
<record id="{{ model }}_{{ loop.index }}" model="{{ model }}"> |
|
||||
{% for key, val in record.read()[0].items() %} |
|
||||
<field name="{{ key }}">{{ val }}</field> |
|
||||
{% endfor %} |
|
||||
</record> |
|
||||
--> |
|
||||
{% if not loop.last %} |
|
||||
|
|
||||
{% endif %} |
|
||||
{% endfor %} |
|
||||
|
{{ data }} |
||||
|
|
||||
</data> |
</data> |
||||
</openerp> |
</openerp> |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
{% for record in records %} |
||||
|
<!-- |
||||
|
<record id="{{ model }}_{{ loop.index }}" model="{{ model }}"> |
||||
|
{% for key, val in record.read()[0].items() %} |
||||
|
<field name="{{ key }}">{{ val }}</field> |
||||
|
{% endfor %} |
||||
|
</record> |
||||
|
--> |
||||
|
{% if not loop.last %} |
||||
|
|
||||
|
{% endif %} |
||||
|
{% endfor %} |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,26 @@ |
|||||
|
# -*- encoding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Odoo, Open Source Management Solution |
||||
|
{% if author %} |
||||
|
# This module copyright (C) {{ export_year }} {{ author }} |
||||
|
{% else %} |
||||
|
# This module copyright (C) {{ export_year }} |
||||
|
{% endif %} |
||||
|
{% if website %} |
||||
|
# ({{ website }}). |
||||
|
{% endif %} |
||||
|
{% if license_text %} |
||||
|
# |
||||
|
{% for line in license_text %} |
||||
|
{% if line.strip() %} |
||||
|
# {{ line }} |
||||
|
{% else %} |
||||
|
# |
||||
|
{% endif %} |
||||
|
{% endfor %} |
||||
|
{% endif %} |
||||
|
# |
||||
|
############################################################################## |
||||
|
{% block body %} |
||||
|
{% endblock %} |
@ -1,9 +1,6 @@ |
|||||
{% extends "header.template" %} |
{% extends "header.template" %} |
||||
{% block body %} |
{% block body %} |
||||
{% for model in models %} |
|
||||
{% if loop.first %} |
|
||||
|
|
||||
{% endif %} |
|
||||
from . import {{ unprefix(model) }} |
|
||||
|
{% for model in models -%} |
||||
|
from . import {{ model }} |
||||
{% endfor %} |
{% endfor %} |
||||
{% endblock %} |
{% endblock %} |
@ -0,0 +1,9 @@ |
|||||
|
{% extends "header.template" %} |
||||
|
{% block body %} |
||||
|
{% for model in models %} |
||||
|
{% if loop.first %} |
||||
|
|
||||
|
{% endif %} |
||||
|
from . import {{ unprefix(model) }} |
||||
|
{% endfor %} |
||||
|
{% endblock %} |
@ -1,68 +1,22 @@ |
|||||
{% extends "header.template" %} |
{% extends "header.template" %} |
||||
{% block body %} |
{% block body %} |
||||
|
|
||||
from openerp import models, fields |
from openerp import models, fields |
||||
from openerp.tools.translate import _ |
from openerp.tools.translate import _ |
||||
|
|
||||
|
|
||||
class {{ unprefix(name) }}(models.Model): |
|
||||
{% if model.state == 'base' and not is_prefixed(model.model) %} |
|
||||
_inherit = "{{ unprefix(model.model) }}" |
|
||||
{% else %} |
|
||||
_name = "{{ unprefix(model.model) }}" |
|
||||
{% endif %} |
|
||||
{% if description %} |
|
||||
_description = "{{ description }}" |
|
||||
{% endif %} |
|
||||
|
class {{ name }}(models.Model): |
||||
|
_inherit = "{{ inherit }}" |
||||
|
{% if description -%}_description = "{{ description }}"{% endif %} |
||||
|
|
||||
{% for field in fields %} |
|
||||
{% for line in wrap(field.notes, replace_whitespace=False) %} |
|
||||
{% if line %} |
|
||||
# {{line}} |
|
||||
{% else %} |
|
||||
# |
|
||||
{% endif %} |
|
||||
{% endfor %} |
|
||||
{{ unprefix(field.name) }} = fields.{{ field.ttype|capitalize }}( |
|
||||
|
{% for field in fields -%} |
||||
|
{% if field.notes -%}# {{ field.notes }}{% endif %} |
||||
|
{{ field.name }} = fields.{{ field.ttype|capitalize }}( |
||||
string=_("{{ field.field_description }}"), |
string=_("{{ field.field_description }}"), |
||||
{% if field.selection %} |
|
||||
selection={{ field.selection }}, |
|
||||
{% endif %} |
|
||||
{% if field.relation %} |
|
||||
comodel_name="{{ unprefix(field.relation) }}", |
|
||||
{% endif %} |
|
||||
{% if field.ttype == 'one2many' %} |
|
||||
inverse_name="{{ unprefix(field.relation_field) }}", |
|
||||
{% endif %} |
|
||||
{% if field.column1 %} |
|
||||
column1="{{ field.column1 }}", |
|
||||
{% endif %} |
|
||||
{% if field.column2 %} |
|
||||
column1="{{ field.column2 }}", |
|
||||
{% endif %} |
|
||||
required={{ field.required }}, |
required={{ field.required }}, |
||||
translate={{ field.translate }}, |
translate={{ field.translate }}, |
||||
readonly={{ field.readonly }}, |
readonly={{ field.readonly }}, |
||||
{% if field.size %} |
|
||||
size={{ field.size }}, |
|
||||
{% endif %} |
|
||||
{% if field.ttype in ('many2one', 'many2many', 'one2many') %} |
|
||||
{% if field.domain %} |
|
||||
domain={{ field.domain }}, |
|
||||
{% endif %} |
|
||||
{% if field.client_context %} |
|
||||
context={{ field.client_context }}, |
|
||||
{% endif %} |
|
||||
{% endif %} |
|
||||
{% if field.limit %} |
|
||||
limit={{ field.limit }}, |
|
||||
{% endif %} |
|
||||
{% if field.ttype == 'many2one' and field.on_delete %} |
|
||||
on_delete="{{ field.on_delete }}", |
|
||||
{% endif %} |
|
||||
{% if field.helper %} |
|
||||
help=_("{{ field.helper }}"), |
|
||||
{% endif %} |
|
||||
) |
|
||||
{% endfor %} |
|
||||
|
{% if field.size -%}size={{ field.size }},{% endif %} |
||||
|
{% if field.helper -%}help=_("{{ field.helper }}"),{% endif %} |
||||
|
){% endfor %} |
||||
|
|
||||
{% endblock %} |
{% endblock %} |
@ -0,0 +1,68 @@ |
|||||
|
{% extends "header.template" %} |
||||
|
{% block body %} |
||||
|
|
||||
|
from openerp import models, fields |
||||
|
from openerp.tools.translate import _ |
||||
|
|
||||
|
|
||||
|
class {{ unprefix(name) }}(models.Model): |
||||
|
{% if model.state == 'base' and not is_prefixed(model.model) %} |
||||
|
_inherit = "{{ unprefix(model.model) }}" |
||||
|
{% else %} |
||||
|
_name = "{{ unprefix(model.model) }}" |
||||
|
{% endif %} |
||||
|
{% if description %} |
||||
|
_description = "{{ description }}" |
||||
|
{% endif %} |
||||
|
|
||||
|
{% for field in fields %} |
||||
|
{% for line in wrap(field.notes, replace_whitespace=False) %} |
||||
|
{% if line %} |
||||
|
# {{line}} |
||||
|
{% else %} |
||||
|
# |
||||
|
{% endif %} |
||||
|
{% endfor %} |
||||
|
{{ unprefix(field.name) }} = fields.{{ field.ttype|capitalize }}( |
||||
|
string=_("{{ field.field_description }}"), |
||||
|
{% if field.selection %} |
||||
|
selection={{ field.selection }}, |
||||
|
{% endif %} |
||||
|
{% if field.relation %} |
||||
|
comodel_name="{{ unprefix(field.relation) }}", |
||||
|
{% endif %} |
||||
|
{% if field.ttype == 'one2many' %} |
||||
|
inverse_name="{{ unprefix(field.relation_field) }}", |
||||
|
{% endif %} |
||||
|
{% if field.column1 %} |
||||
|
column1="{{ field.column1 }}", |
||||
|
{% endif %} |
||||
|
{% if field.column2 %} |
||||
|
column1="{{ field.column2 }}", |
||||
|
{% endif %} |
||||
|
required={{ field.required }}, |
||||
|
translate={{ field.translate }}, |
||||
|
readonly={{ field.readonly }}, |
||||
|
{% if field.size %} |
||||
|
size={{ field.size }}, |
||||
|
{% endif %} |
||||
|
{% if field.ttype in ('many2one', 'many2many', 'one2many') %} |
||||
|
{% if field.domain %} |
||||
|
domain={{ field.domain }}, |
||||
|
{% endif %} |
||||
|
{% if field.client_context %} |
||||
|
context={{ field.client_context }}, |
||||
|
{% endif %} |
||||
|
{% endif %} |
||||
|
{% if field.limit %} |
||||
|
limit={{ field.limit }}, |
||||
|
{% endif %} |
||||
|
{% if field.ttype == 'many2one' and field.on_delete %} |
||||
|
on_delete="{{ field.on_delete }}", |
||||
|
{% endif %} |
||||
|
{% if field.helper %} |
||||
|
help=_("{{ field.helper }}"), |
||||
|
{% endif %} |
||||
|
) |
||||
|
{% endfor %} |
||||
|
{% endblock %} |
@ -1,29 +1,24 @@ |
|||||
<?xml version="1.0"?> |
<?xml version="1.0"?> |
||||
<openerp> |
<openerp> |
||||
<data> |
<data> |
||||
{% for menu in menus %} |
|
||||
|
{% for menu in menus -%} |
||||
<record id="action_{{ menu.action.name }}_{{ menu.action.view_type }}_view" model="{{ menu.action.type }}"> |
<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="name">{{ menu.action.name }}</field> |
||||
<field name="type">{{ menu.action.type }}</field> |
<field name="type">{{ menu.action.type }}</field> |
||||
<field name="res_model">{{ unprefix(menu.action.res_model) }}</field> |
|
||||
|
<field name="res_model">{{ menu.action.res_model }}</field> |
||||
<field name="view_type">{{ menu.action.view_type }}</field> |
<field name="view_type">{{ menu.action.view_type }}</field> |
||||
<field name="view_mode">{{ menu.action.view_mode }}</field> |
<field name="view_mode">{{ menu.action.view_mode }}</field> |
||||
{% if menu.action.help %} |
|
||||
<field name="help" type="html">{{ menu.action.help }} |
|
||||
</field> |
|
||||
{% endif %} |
|
||||
|
{% if menu.action.help %}<field name="help" type="html">{{ menu.action.help }} |
||||
|
</field>{% endif %} |
||||
</record> |
</record> |
||||
|
|
||||
<menuitem action="action_{{ unprefix(menu.action.name) }}_{{ menu.action.view_type }}_view" |
|
||||
|
<menuitem action="action_{{ menu.action.name }}_{{ menu.action.view_type }}_view" |
||||
name="{{ menu.name }}" |
name="{{ menu.name }}" |
||||
id="menu_action_{{ unprefix(menu.name)|replace('.', '_') }}_{{ menu.action.view_type }}" |
|
||||
|
id="menu_action_{{ menu.name|replace('.', '_') }}_{{ menu.action.view_type }}" |
||||
{% if menu.parent_id %}parent="{{ menu.parent_id.get_xml_id(cr,1,1).values()[0] }}"{% endif %} |
{% if menu.parent_id %}parent="{{ menu.parent_id.get_xml_id(cr,1,1).values()[0] }}"{% endif %} |
||||
sequence="{{ menu.sequence }}" |
sequence="{{ menu.sequence }}" |
||||
groups="{% for group in menu.groups_id %}{{ group.get_xml_id(cr,1,1).values()[0] }}{% if not loop.last %},{% endif %}{% endfor %}" |
|
||||
|
groups="{% for group in menu.groups_id %}{{ group.get_xml_id(cr,1,1).values()[0] }},{% endfor %}" |
||||
/> |
/> |
||||
{% if not loop.last %} |
|
||||
|
|
||||
{% endif %} |
|
||||
{% endfor %} |
|
||||
|
{% endfor -%} |
||||
</data> |
</data> |
||||
</openerp> |
</openerp> |
@ -0,0 +1,29 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
{% 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(cr,1,1).values()[0] }}"{% endif %} |
||||
|
sequence="{{ menu.sequence }}" |
||||
|
groups="{% for group in menu.groups_id %}{{ group.get_xml_id(cr,1,1).values()[0] }}{% if not loop.last %},{% endif %}{% endfor %}" |
||||
|
/> |
||||
|
{% if not loop.last %} |
||||
|
|
||||
|
{% endif %} |
||||
|
{% endfor %} |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<!-- 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(cr,1,1).values()[0] }}"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
{{ fixup_arch(view.arch) }} |
||||
|
</field> |
||||
|
</record> |
||||
|
{% endfor %} |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,51 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<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> |
||||
|
</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="//page/field/form/separator[@string='Groups']" |
||||
|
position="before"> |
||||
|
<separator string="Notes"/> |
||||
|
<field name="notes"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,145 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<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> |
||||
|
</div> |
||||
|
<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> |
||||
|
</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 & 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> |
||||
|
</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> |
||||
|
|
||||
|
<!--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 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.action_model_fields" |
||||
|
id="ir_model_model_fields" |
||||
|
parent="menu_module_prototyper" |
||||
|
sequence="4" |
||||
|
groups="base.group_system"/> |
||||
|
|
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
2
prototype/demo/prototype.prototype.csv
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,272 +0,0 @@ |
|||||
# Translation of Odoo Server. |
|
||||
# This file contains the translation of the following modules: |
|
||||
# * prototype |
|
||||
# |
|
||||
msgid "" |
|
||||
msgstr "" |
|
||||
"Project-Id-Version: Odoo Server 8.0\n" |
|
||||
"Report-Msgid-Bugs-To: \n" |
|
||||
"POT-Creation-Date: 2014-10-08 17:58+0000\n" |
|
||||
"PO-Revision-Date: 2014-10-08 14:02-0500\n" |
|
||||
"Last-Translator: Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com>\n" |
|
||||
"Language-Team: \n" |
|
||||
"MIME-Version: 1.0\n" |
|
||||
"Content-Type: text/plain; charset=UTF-8\n" |
|
||||
"Content-Transfer-Encoding: 8bit\n" |
|
||||
"Plural-Forms: \n" |
|
||||
"X-Generator: Poedit 1.5.4\n" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,api_version:0 |
|
||||
msgid "7.0" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,api_version:0 |
|
||||
msgid "8.0" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,api_version:0 |
|
||||
msgid "API version" |
|
||||
msgstr "Version de l'API" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,rights:0 |
|
||||
msgid "Access Rights" |
|
||||
msgstr "Liste des contrôles d'accès" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,author:0 |
|
||||
msgid "Author" |
|
||||
msgstr "Auteur" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,auto_install:0 |
|
||||
msgid "Auto Install" |
|
||||
msgstr "Installation automatique" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Cancel" |
|
||||
msgstr "Annuler" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,category_id:0 |
|
||||
msgid "Category" |
|
||||
msgstr "Catégorie" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Close" |
|
||||
msgstr "Fermer" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,create_uid:0 field:prototype.module.export,create_uid:0 |
|
||||
msgid "Created by" |
|
||||
msgstr "Créé par" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,create_date:0 field:prototype.module.export,create_date:0 |
|
||||
msgid "Created on" |
|
||||
msgstr "Créé le" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Data & Demo" |
|
||||
msgstr "Données et démo" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,data:0 |
|
||||
msgid "Data filters" |
|
||||
msgstr "Filtres pour les données" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,demo:0 |
|
||||
msgid "Demo filters" |
|
||||
msgstr "Filtres pour les données de démo" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form field:prototype,dependencies:0 |
|
||||
msgid "Dependencies" |
|
||||
msgstr "Dépendances" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form field:prototype,description:0 |
|
||||
msgid "Description" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export" |
|
||||
msgstr "Exporter" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export Complete" |
|
||||
msgstr "Export terminé" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: model:ir.actions.act_window,name:prototype.button_module_export_action |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export Module" |
|
||||
msgstr "Exporter le module" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export Settings" |
|
||||
msgstr "Configuration de l'export" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: model:ir.model,name:prototype.model_ir_model_fields |
|
||||
#: field:prototype,fields:0 |
|
||||
msgid "Fields" |
|
||||
msgstr "Champs" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,data:0 |
|
||||
msgid "File" |
|
||||
msgstr "Fichier" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,name:0 |
|
||||
msgid "File Name" |
|
||||
msgstr "Nom du fichier" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,groups:0 |
|
||||
msgid "Groups" |
|
||||
msgstr "Groupes" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Here is the exported module:" |
|
||||
msgstr "Voici le module exporté :" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,id:0 field:prototype.module.export,id:0 |
|
||||
msgid "ID" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,icon_image:0 |
|
||||
msgid "Icon" |
|
||||
msgstr "Icône" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Interface" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,write_uid:0 field:prototype.module.export,write_uid:0 |
|
||||
msgid "Last Updated by" |
|
||||
msgstr "Mis à jour par" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,write_date:0 field:prototype.module.export,write_date:0 |
|
||||
msgid "Last Updated on" |
|
||||
msgstr "Mis à jour le" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,maintainer:0 |
|
||||
msgid "Maintainer" |
|
||||
msgstr "Mainteneur" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,menu:0 |
|
||||
msgid "Menu Items" |
|
||||
msgstr "Éléments du menu" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Models" |
|
||||
msgstr "Modèles" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Module" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,human_name:0 |
|
||||
msgid "Module Name" |
|
||||
msgstr "Nom du module" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:ir.model:prototype.view_ir_model_form field:ir.model.fields,notes:0 |
|
||||
msgid "Notes" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: model:ir.actions.act_window,name:prototype.open_prototype_list |
|
||||
#: model:ir.model,name:prototype.model_prototype |
|
||||
#: model:ir.ui.menu,name:prototype.menu_open_prototype |
|
||||
#: view:prototype:prototype.view_prototype_tree |
|
||||
msgid "Prototype" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,rules:0 |
|
||||
msgid "Record Rules" |
|
||||
msgstr "Règles sur les enregistrements" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Security" |
|
||||
msgstr "Sécurité" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,summary:0 |
|
||||
msgid "Summary" |
|
||||
msgstr "Résumé" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,name:0 |
|
||||
msgid "Technical Name" |
|
||||
msgstr "Nom technique" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: help:prototype,data:0 |
|
||||
msgid "The records matching the filters will be added as data." |
|
||||
msgstr "" |
|
||||
"Les enregistrements correspondant aux critères des filtres seront exportées " |
|
||||
"dans le module comme données." |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: help:prototype,demo:0 |
|
||||
msgid "The records matching the filters will be added as demo data." |
|
||||
msgstr "" |
|
||||
"Les enregistrements correspondant aux critères des filtres seront exportées " |
|
||||
"dans le module comme données de démo." |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,version:0 |
|
||||
msgid "Version" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,views:0 |
|
||||
msgid "Views" |
|
||||
msgstr "Vues" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,website:0 |
|
||||
msgid "Website" |
|
||||
msgstr "Site web" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,state:0 |
|
||||
msgid "choose" |
|
||||
msgstr "choisir" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,state:0 |
|
||||
msgid "get" |
|
||||
msgstr "récupérer" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,state:0 |
|
||||
msgid "unknown" |
|
||||
msgstr "inconnu" |
|
@ -1,268 +0,0 @@ |
|||||
# Translation of Odoo Server. |
|
||||
# This file contains the translation of the following modules: |
|
||||
# * prototype |
|
||||
# |
|
||||
msgid "" |
|
||||
msgstr "" |
|
||||
"Project-Id-Version: Odoo Server 8.0\n" |
|
||||
"Report-Msgid-Bugs-To: \n" |
|
||||
"POT-Creation-Date: 2014-10-08 17:58+0000\n" |
|
||||
"PO-Revision-Date: 2014-10-08 14:00-0500\n" |
|
||||
"Last-Translator: Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com>\n" |
|
||||
"Language-Team: \n" |
|
||||
"MIME-Version: 1.0\n" |
|
||||
"Content-Type: text/plain; charset=UTF-8\n" |
|
||||
"Content-Transfer-Encoding: 8bit\n" |
|
||||
"Plural-Forms: \n" |
|
||||
"X-Generator: Poedit 1.5.4\n" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,api_version:0 |
|
||||
msgid "7.0" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,api_version:0 |
|
||||
msgid "8.0" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,api_version:0 |
|
||||
msgid "API version" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,rights:0 |
|
||||
msgid "Access Rights" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,author:0 |
|
||||
msgid "Author" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,auto_install:0 |
|
||||
msgid "Auto Install" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Cancel" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,category_id:0 |
|
||||
msgid "Category" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Close" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,create_uid:0 field:prototype.module.export,create_uid:0 |
|
||||
msgid "Created by" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,create_date:0 field:prototype.module.export,create_date:0 |
|
||||
msgid "Created on" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Data & Demo" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,data:0 |
|
||||
msgid "Data filters" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,demo:0 |
|
||||
msgid "Demo filters" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form field:prototype,dependencies:0 |
|
||||
msgid "Dependencies" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form field:prototype,description:0 |
|
||||
msgid "Description" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export Complete" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: model:ir.actions.act_window,name:prototype.button_module_export_action |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export Module" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Export Settings" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: model:ir.model,name:prototype.model_ir_model_fields |
|
||||
#: field:prototype,fields:0 |
|
||||
msgid "Fields" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,data:0 |
|
||||
msgid "File" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,name:0 |
|
||||
msgid "File Name" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,groups:0 |
|
||||
msgid "Groups" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype.module.export:prototype.view_module_export_wizard |
|
||||
msgid "Here is the exported module:" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,id:0 field:prototype.module.export,id:0 |
|
||||
msgid "ID" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,icon_image:0 |
|
||||
msgid "Icon" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Interface" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,write_uid:0 field:prototype.module.export,write_uid:0 |
|
||||
msgid "Last Updated by" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,write_date:0 field:prototype.module.export,write_date:0 |
|
||||
msgid "Last Updated on" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,maintainer:0 |
|
||||
msgid "Maintainer" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,menu:0 |
|
||||
msgid "Menu Items" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Models" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Module" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,human_name:0 |
|
||||
msgid "Module Name" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:ir.model:prototype.view_ir_model_form field:ir.model.fields,notes:0 |
|
||||
msgid "Notes" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: model:ir.actions.act_window,name:prototype.open_prototype_list |
|
||||
#: model:ir.model,name:prototype.model_prototype |
|
||||
#: model:ir.ui.menu,name:prototype.menu_open_prototype |
|
||||
#: view:prototype:prototype.view_prototype_tree |
|
||||
msgid "Prototype" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,rules:0 |
|
||||
msgid "Record Rules" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: view:prototype:prototype.view_prototype_form |
|
||||
msgid "Security" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,summary:0 |
|
||||
msgid "Summary" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,name:0 |
|
||||
msgid "Technical Name" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: help:prototype,data:0 |
|
||||
msgid "The records matching the filters will be added as data." |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: help:prototype,demo:0 |
|
||||
msgid "The records matching the filters will be added as demo data." |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,version:0 |
|
||||
msgid "Version" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,views:0 |
|
||||
msgid "Views" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype,website:0 |
|
||||
msgid "Website" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,state:0 |
|
||||
msgid "choose" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: selection:prototype.module.export,state:0 |
|
||||
msgid "get" |
|
||||
msgstr "" |
|
||||
|
|
||||
#. module: prototype |
|
||||
#: field:prototype.module.export,state:0 |
|
||||
msgid "unknown" |
|
||||
msgstr "" |
|
@ -1,339 +0,0 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
# ############################################################################# |
|
||||
# |
|
||||
# OpenERP, Open Source Management Solution |
|
||||
# This module copyright (C) 2010 - 2014 Savoir-faire Linux |
|
||||
# (<http://www.savoirfairelinux.com>). |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
import os |
|
||||
import re |
|
||||
import base64 |
|
||||
from datetime import date |
|
||||
YEAR = date.today().year |
|
||||
|
|
||||
from collections import namedtuple |
|
||||
from jinja2 import Environment, FileSystemLoader |
|
||||
from openerp import models, api, fields |
|
||||
|
|
||||
|
|
||||
class Prototype(models.Model): |
|
||||
_name = "prototype" |
|
||||
_description = "Prototype" |
|
||||
|
|
||||
licence = fields.Char( |
|
||||
'Licence', |
|
||||
default='AGPL-3', |
|
||||
) |
|
||||
name = fields.Char( |
|
||||
'Technical Name', required=True, |
|
||||
help=('The technical name will be used to define the name of ' |
|
||||
'the exported module, the name of the model.') |
|
||||
) |
|
||||
category_id = fields.Many2one('ir.module.category', 'Category') |
|
||||
human_name = fields.Char( |
|
||||
'Module Name', required=True, |
|
||||
help=('The Module Name will be used as the displayed name of the ' |
|
||||
'exported module.') |
|
||||
) |
|
||||
summary = fields.Char('Summary', required=True) |
|
||||
description = fields.Text('Description', required=True) |
|
||||
author = fields.Char('Author', required=True) |
|
||||
maintainer = fields.Char('Maintainer') |
|
||||
website = fields.Char('Website') |
|
||||
icon_image = fields.Binary( |
|
||||
'Icon', |
|
||||
help=('The icon set up here will be used as the icon ' |
|
||||
'for the exported module also') |
|
||||
) |
|
||||
version = fields.Char('Version', size=3, default='0.1') |
|
||||
auto_install = fields.Boolean( |
|
||||
'Auto Install', |
|
||||
default=False, |
|
||||
help='Check if the module should be install by default.' |
|
||||
) |
|
||||
application = fields.Boolean( |
|
||||
'Application', |
|
||||
default=False, |
|
||||
help='Check if the module is an Odoo application.' |
|
||||
) |
|
||||
# Relations |
|
||||
dependency_ids = fields.Many2many( |
|
||||
'ir.module.module', 'prototype_module_rel', |
|
||||
'prototype_id', 'module_id', |
|
||||
'Dependencies' |
|
||||
) |
|
||||
data_ids = fields.Many2many( |
|
||||
'ir.filters', |
|
||||
'prototype_data_rel', |
|
||||
'prototype_id', 'filter_id', |
|
||||
'Data filters', |
|
||||
help="The records matching the filters will be added as data." |
|
||||
) |
|
||||
demo_ids = fields.Many2many( |
|
||||
'ir.filters', |
|
||||
'prototype_demo_rel', |
|
||||
'prototype_id', 'filter_id', |
|
||||
'Demo filters', |
|
||||
help="The records matching the filters will be added as demo data." |
|
||||
) |
|
||||
field_ids = fields.Many2many( |
|
||||
'ir.model.fields', 'prototype_fields_rel', |
|
||||
'prototype_id', 'field_id', 'Fields' |
|
||||
) |
|
||||
menu_ids = fields.Many2many( |
|
||||
'ir.ui.menu', 'prototype_menu_rel', |
|
||||
'prototype_id', 'menu_id', 'Menu Items' |
|
||||
) |
|
||||
view_ids = fields.Many2many( |
|
||||
'ir.ui.view', 'prototype_view_rel', |
|
||||
'prototype_id', 'view_id', 'Views' |
|
||||
) |
|
||||
group_ids = fields.Many2many( |
|
||||
'res.groups', 'prototype_groups_rel', |
|
||||
'prototype_id', 'group_id', 'Groups' |
|
||||
) |
|
||||
right_ids = fields.Many2many( |
|
||||
'ir.model.access', 'prototype_rights_rel', |
|
||||
'prototype_id', 'right_id', |
|
||||
'Access Rights' |
|
||||
) |
|
||||
rule_ids = fields.Many2many( |
|
||||
'ir.rule', 'prototype_rule_rel', |
|
||||
'prototype_id', 'rule_id', 'Record Rules' |
|
||||
) |
|
||||
|
|
||||
__data_files = [] |
|
||||
__field_descriptions = {} |
|
||||
_env = None |
|
||||
File_details = namedtuple('file_details', ['filename', 'filecontent']) |
|
||||
template_path = '{}/../templates/'.format(os.path.dirname(__file__)) |
|
||||
|
|
||||
@api.model |
|
||||
def set_jinja_env(self, api_version): |
|
||||
"""Set the Jinja2 environment. |
|
||||
The environment will helps the system to find the templates to render. |
|
||||
:param api_version: string, odoo api |
|
||||
:return: jinja2.Environment instance. |
|
||||
""" |
|
||||
if self._env is None: |
|
||||
self._env = Environment( |
|
||||
loader=FileSystemLoader( |
|
||||
os.path.join(self.template_path, api_version) |
|
||||
) |
|
||||
) |
|
||||
return self._env |
|
||||
|
|
||||
def set_field_descriptions(self): |
|
||||
"""Mock the list of fields into dictionary. |
|
||||
It allows us to add or change attributes of the fields. |
|
||||
|
|
||||
:return: None |
|
||||
""" |
|
||||
for field in self.field_ids: |
|
||||
field_description = {} |
|
||||
# This will mock a field record. |
|
||||
# the mock will allow us to add data or modify the data |
|
||||
# of the field (like for the name) with keeping all the |
|
||||
# attributes of the record. |
|
||||
field_description.update({ |
|
||||
attr_name: getattr(field, attr_name) |
|
||||
for attr_name in dir(field) |
|
||||
if not attr_name[0] == '_' |
|
||||
}) |
|
||||
# custom fields start with the prefix x_. |
|
||||
# it has to be removed. |
|
||||
field_description['name'] = re.sub(r'^x_', '', field.name) |
|
||||
self.__field_descriptions[field] = field_description |
|
||||
|
|
||||
@api.model |
|
||||
def generate_files(self): |
|
||||
""" Generates the files from the details of the prototype. |
|
||||
:return: tuple |
|
||||
""" |
|
||||
assert self._env is not None, \ |
|
||||
'Run set_env(api_version) before to generate files.' |
|
||||
|
|
||||
self.set_field_descriptions() |
|
||||
file_details = [] |
|
||||
file_details.extend(self.generate_models_details()) |
|
||||
file_details.extend(self.generate_views_details()) |
|
||||
file_details.extend(self.generate_menus_details()) |
|
||||
file_details.append(self.generate_module_init_file_details()) |
|
||||
# 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()) |
|
||||
file_details.append(self.save_icon()) |
|
||||
|
|
||||
return file_details |
|
||||
|
|
||||
@api.model |
|
||||
def save_icon(self): |
|
||||
return self.File_details( |
|
||||
os.path.join('static', 'description', 'icon.jpg'), |
|
||||
base64.b64decode(self.icon_image) |
|
||||
) |
|
||||
|
|
||||
@api.model |
|
||||
def generate_module_openerp_file_details(self): |
|
||||
"""Wrapper to generate the __openerp__.py file of the module.""" |
|
||||
return self.generate_file_details( |
|
||||
'__openerp__.py', |
|
||||
'__openerp__.py.template', |
|
||||
prototype=self, |
|
||||
data_files=self.__data_files, |
|
||||
) |
|
||||
|
|
||||
@api.model |
|
||||
def generate_module_init_file_details(self): |
|
||||
"""Wrapper to generate the __init__.py file of the module.""" |
|
||||
return self.generate_file_details( |
|
||||
'__init__.py', |
|
||||
'__init__.py.template', |
|
||||
# no import models if no work of fields in |
|
||||
# the prototype |
|
||||
models=bool(self.field_ids) |
|
||||
) |
|
||||
|
|
||||
@api.model |
|
||||
def generate_models_details(self): |
|
||||
"""Finds the models from the list of fields and generates |
|
||||
the __init__ file and each models files (one by class). |
|
||||
""" |
|
||||
files = [] |
|
||||
# TODO: doesn't work as need to find the module to import |
|
||||
# and it is not necessary the name of the model the fields |
|
||||
# belongs to. |
|
||||
# ie. field.cell_phone is defined in a model inheriting from |
|
||||
# res.partner. |
|
||||
# How do we find the module the field was defined in? |
|
||||
# dependencies = set([dep.id for dep in self.dependencies]) |
|
||||
|
|
||||
relations = {} |
|
||||
for field in self.__field_descriptions.itervalues(): |
|
||||
model = field.get('model_id') |
|
||||
relations.setdefault(model, []).append(field) |
|
||||
# dependencies.add(model.id) |
|
||||
|
|
||||
# blind update of dependencies. |
|
||||
# self.write({ |
|
||||
# 'dependencies': [(6, 0, [id_ for id_ in dependencies])] |
|
||||
# }) |
|
||||
|
|
||||
files.append(self.generate_models_init_details(relations.keys())) |
|
||||
for model, fields in relations.iteritems(): |
|
||||
files.append(self.generate_model_details(model, fields)) |
|
||||
|
|
||||
return files |
|
||||
|
|
||||
@api.model |
|
||||
def generate_models_init_details(self, ir_models): |
|
||||
"""Wrapper to generate the __init__.py file in models folder.""" |
|
||||
return self.generate_file_details( |
|
||||
'models/__init__.py', |
|
||||
'models/__init__.py.template', |
|
||||
models=[ |
|
||||
self.friendly_name(ir_model.model) |
|
||||
for ir_model in ir_models |
|
||||
] |
|
||||
) |
|
||||
|
|
||||
@api.model |
|
||||
def generate_views_details(self): |
|
||||
"""Wrapper to generate the views files.""" |
|
||||
relations = {} |
|
||||
for view in self.view_ids: |
|
||||
relations.setdefault(view.model, []).append(view) |
|
||||
|
|
||||
views_details = [] |
|
||||
for model, views in relations.iteritems(): |
|
||||
filepath = 'views/{}_view.xml'.format( |
|
||||
self.friendly_name(model) |
|
||||
) |
|
||||
views_details.append( |
|
||||
self.generate_file_details( |
|
||||
filepath, |
|
||||
'views/model_views.xml.template', |
|
||||
views=views |
|
||||
) |
|
||||
) |
|
||||
self.__data_files.append(filepath) |
|
||||
|
|
||||
return views_details |
|
||||
|
|
||||
@api.model |
|
||||
def generate_menus_details(self): |
|
||||
"""Wrapper to generate the menus files.""" |
|
||||
relations = {} |
|
||||
for menu in self.menu_ids: |
|
||||
relations.setdefault(menu.action.res_model, []).append(menu) |
|
||||
|
|
||||
menus_details = [] |
|
||||
for model_name, menus in relations.iteritems(): |
|
||||
filepath = 'views/{}_menus.xml'.format( |
|
||||
self.friendly_name(model_name) |
|
||||
) |
|
||||
menus_details.append( |
|
||||
self.generate_file_details( |
|
||||
filepath, |
|
||||
'views/model_menus.xml.template', |
|
||||
menus=menus, |
|
||||
) |
|
||||
) |
|
||||
self.__data_files.append(filepath) |
|
||||
|
|
||||
return menus_details |
|
||||
|
|
||||
@api.model |
|
||||
def generate_model_details(self, model, field_descriptions): |
|
||||
"""Wrapper to generate the python file for the model. |
|
||||
|
|
||||
:param model: ir.model record. |
|
||||
:param field_descriptions: list of ir.model.fields records. |
|
||||
:return: FileDetails instance. |
|
||||
""" |
|
||||
python_friendly_name = self.friendly_name(model.model) |
|
||||
return self.generate_file_details( |
|
||||
'models/{}.py'.format(python_friendly_name), |
|
||||
'models/model_name.py.template', |
|
||||
name=python_friendly_name, |
|
||||
inherit=model.model, |
|
||||
fields=field_descriptions, |
|
||||
) |
|
||||
|
|
||||
@staticmethod |
|
||||
def friendly_name(name): |
|
||||
return name.replace('.', '_') |
|
||||
|
|
||||
@api.model |
|
||||
def generate_file_details(self, filename, template, **kwargs): |
|
||||
""" generate file details from jinja2 template. |
|
||||
:param filename: name of the file the content is related to |
|
||||
:param template: path to the file to render the content |
|
||||
:param kwargs: arguments of the template |
|
||||
:return: File_details instance |
|
||||
""" |
|
||||
template = self._env.get_template(template) |
|
||||
# keywords used in several templates. |
|
||||
kwargs.update( |
|
||||
{ |
|
||||
'export_year': YEAR, |
|
||||
'author': self.author, |
|
||||
'website': self.website, |
|
||||
'cr': self._cr, |
|
||||
} |
|
||||
) |
|
||||
return self.File_details(filename, template.render(kwargs)) |
|
@ -1,2 +0,0 @@ |
|||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|
||||
access_prototype_admin,prototype_system,model_prototype,base.group_system,1,1,1,1 |
|
Before Width: 500 | Height: 500 | Size: 14 KiB |
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
|
||||
{{ data }} |
|
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
|
||||
{{ demo }} |
|
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,22 +0,0 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
############################################################################## |
|
||||
# |
|
||||
# Odoo, Open Source Management Solution |
|
||||
# This module copyright (C) {{ export_year }} {{ author }} |
|
||||
# ({{ website }}). |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
{% block body %}{% endblock %} |
|
@ -1,6 +0,0 @@ |
|||||
{% extends "header.template" %} |
|
||||
{% block body %} |
|
||||
{% for model in models -%} |
|
||||
from . import {{ model }} |
|
||||
{% endfor %} |
|
||||
{% endblock %} |
|
@ -1,21 +0,0 @@ |
|||||
{% extends "header.template" %} |
|
||||
{% block body %} |
|
||||
from openerp import models, fields |
|
||||
from openerp.tools.translate import _ |
|
||||
|
|
||||
|
|
||||
class {{ name }}(models.Model): |
|
||||
_inherit = "{{ inherit }}" |
|
||||
{% if description %}_description = "{{ description }}"{% endif %} |
|
||||
|
|
||||
{% for field in fields -%} |
|
||||
{{ field.name }} = fields.{{ field.ttype|capitalize }}( |
|
||||
string=_("{{ field.field_description }}"), |
|
||||
required={{ field.required }}, |
|
||||
translate={{ field.translate }}, |
|
||||
readonly={{ field.readonly }}, |
|
||||
help=_('{{ field.notes }}'), |
|
||||
) |
|
||||
{% endfor %} |
|
||||
|
|
||||
{% endblock %} |
|
@ -1,4 +0,0 @@ |
|||||
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 %} |
|
@ -1,10 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
|
||||
{{ groups }} |
|
||||
|
|
||||
{{ rules }} |
|
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,24 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
{% for menu in menus -%} |
|
||||
<record id="action_{{ menu.action.name }}_{{ menu.action.view_type }}_view" model="{{ menu.action.type }}"> |
|
||||
<field name="name">{{ menu.action.name }}</field> |
|
||||
<field name="type">{{ menu.action.type }}</field> |
|
||||
<field name="res_model">{{ 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_{{ menu.action.name }}_{{ menu.action.view_type }}_view" |
|
||||
name="{{ menu.name }}" |
|
||||
id="menu_action_{{ menu.name|replace('.', '_') }}_{{ menu.action.view_type }}" |
|
||||
{% if menu.parent_id %}parent="{{ menu.parent_id.get_xml_id(cr,1,1).values()[0] }}"{% endif %} |
|
||||
sequence="{{ menu.sequence }}" |
|
||||
groups="{% for group in menu.groups_id %}{{ group.get_xml_id(cr,1,1).values()[0] }},{% endfor %}" |
|
||||
/> |
|
||||
{% endfor -%} |
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,23 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
<!-- TODO: put here a reminder on what to do at the first edition --> |
|
||||
|
|
||||
{% for view in views %} |
|
||||
<record id="{{ view.name|replace('.', '_')}}_view" model="ir.ui.model"> |
|
||||
<field name="name">{{ view.name }}.view</field> |
|
||||
<field name="model">{{ view.model }}</field> |
|
||||
<field name="view_type">{{ view.type }}</field> |
|
||||
<field name="inherit_id" ref="{{ view.inherit_id.get_xml_id(cr,1,1).values()[0] }}"/> |
|
||||
<field name="arch" type="xml"> |
|
||||
{# the arch given by odoo start with an xml tag that |
|
||||
will break the xml tree we build. |
|
||||
Be careful, custom field have a x_ prefix that has to be |
|
||||
removed |
|
||||
#} |
|
||||
{{ view.arch|replace('<?xml version="1.0"?>', '')|replace('"x_', '"') }} |
|
||||
</field> |
|
||||
</record> |
|
||||
{% endfor %} |
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,28 +0,0 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
############################################################################## |
|
||||
# |
|
||||
# OpenERP, Open Source Management Solution |
|
||||
# This module copyright (C) 2010 - 2014 Savoir-faire Linux |
|
||||
# (<http://www.savoirfairelinux.com>). |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
from . import test_prototype_module_export |
|
||||
from . import test_prototype |
|
||||
|
|
||||
checks = [ |
|
||||
test_prototype_module_export, |
|
||||
test_prototype, |
|
||||
] |
|
@ -1,30 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
|
||||
<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="notes"/> |
|
||||
<field name="notes"/> |
|
||||
</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="//page/field/form/separator[@string='Groups']" position="before"> |
|
||||
<separator string="Notes"/> |
|
||||
<field name="notes"/> |
|
||||
</xpath> |
|
||||
</field> |
|
||||
</record> |
|
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,103 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
|
||||
<record id="view_prototype_tree" model="ir.ui.view"> |
|
||||
<field name="name">prototype.tree</field> |
|
||||
<field name="model">prototype</field> |
|
||||
<field name="arch" type="xml"> |
|
||||
<tree string="Prototype"> |
|
||||
<field name="human_name"/> |
|
||||
<field name="name"/> |
|
||||
<field name="summary"/> |
|
||||
</tree> |
|
||||
</field> |
|
||||
</record> |
|
||||
|
|
||||
<record id="view_prototype_form" model="ir.ui.view"> |
|
||||
<field name="name">prototype.form</field> |
|
||||
<field name="model">prototype</field> |
|
||||
<field name="arch" type="xml"> |
|
||||
<form string="Module"> |
|
||||
<link rel="stylesheet" |
|
||||
href="/base/static/src/css/description.css"/> |
|
||||
<sheet> |
|
||||
<field name="icon_image" widget="image" |
|
||||
class="oe_avatar oe_left"/> |
|
||||
<div class="oe_title"> |
|
||||
<h1> |
|
||||
<field name="human_name"/> |
|
||||
</h1> |
|
||||
<div> |
|
||||
<button name="%(button_module_export_action)d" |
|
||||
string="Export" type="action"/> |
|
||||
</div> |
|
||||
</div> |
|
||||
<group> |
|
||||
<group> |
|
||||
<field name="name"/> |
|
||||
<field name="summary"/> |
|
||||
<field name="category_id"/> |
|
||||
<field name="version"/> |
|
||||
</group> |
|
||||
<group> |
|
||||
<field name="author"/> |
|
||||
<field name="website" widget="url"/> |
|
||||
<field name="maintainer"/> |
|
||||
<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="Data & Demo"> |
|
||||
<label for="data_ids"/> |
|
||||
<field name="data_ids"/> |
|
||||
<label for="demo_ids"/> |
|
||||
<field name="demo_ids"/> |
|
||||
</page> |
|
||||
<page string="Fields"> |
|
||||
<label for="field_ids"/> |
|
||||
<field name="field_ids"/> |
|
||||
</page> |
|
||||
<page string="Interface"> |
|
||||
<label for="menu_ids"/> |
|
||||
<field name="menu_ids"/> |
|
||||
<label for="view_ids"/> |
|
||||
<field name="view_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> |
|
||||
</notebook> |
|
||||
</sheet> |
|
||||
</form> |
|
||||
</field> |
|
||||
</record> |
|
||||
|
|
||||
<record id="open_prototype_list" model="ir.actions.act_window"> |
|
||||
<field name="name">Prototype</field> |
|
||||
<field name="res_model">prototype</field> |
|
||||
<field name="view_type">form</field> |
|
||||
<field name="view_mode">tree,form</field> |
|
||||
<field name="view_id" ref="view_prototype_tree"/> |
|
||||
</record> |
|
||||
|
|
||||
<menuitem id="menu_open_prototype" |
|
||||
action="open_prototype_list" |
|
||||
parent="base.menu_management" |
|
||||
sequence="30" |
|
||||
groups="base.group_system"/> |
|
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,22 +0,0 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
############################################################################## |
|
||||
# |
|
||||
# OpenERP, Open Source Management Solution |
|
||||
# This module copyright (C) 2010 - 2014 Savoir-faire Linux |
|
||||
# (<http://www.savoirfairelinux.com>). |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
from . import prototype_module_export |
|
@ -1,43 +0,0 @@ |
|||||
<?xml version="1.0"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
|
||||
<record id="view_module_export_wizard" model="ir.ui.view"> |
|
||||
<field name="name">Export Module</field> |
|
||||
<field name="model">prototype.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> |
|
||||
</record> |
|
||||
|
|
||||
<record id="button_module_export_action" model="ir.actions.act_window"> |
|
||||
<field name="name">Export Module</field> |
|
||||
<field name="res_model">prototype.module.export</field> |
|
||||
<field name="view_type">form</field> |
|
||||
<field name="view_id" ref="view_module_export_wizard"/> |
|
||||
<field name="target">new</field> |
|
||||
</record> |
|
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue