[MERGE]: Merged with lp:trunk-dev-framework

bzr revid: jas@tinyerp.com-20101005092713-r9hqmp33utmuro1w
This commit is contained in:
jas
2010-10-05 14:57:13 +05:30
65 changed files with 1124 additions and 1025 deletions
+1 -2
View File
@@ -148,7 +148,6 @@ CREATE TABLE res_users (
context_lang varchar(64) default '',
-- No FK references below, will be added later by ORM
-- (when the destination rows exist)
action_id int,
company_id int,
primary key(id)
);
@@ -345,7 +344,7 @@ CREATE TABLE ir_model_data (
-- Users
---------------------------------
insert into res_users (id,login,password,name,action_id,active,company_id) values (1,'admin','admin','Administrator',NULL,True,1);
insert into res_users (id,login,password,name,active,company_id) values (1,'admin','admin','Administrator',True,1);
insert into ir_model_data (name,module,model,noupdate,res_id) values ('user_root','base','res.users',True,1);
-- Compatibility purpose, to remove V6.0
+4 -3
View File
@@ -1053,8 +1053,6 @@
<field name="address_id" ref="main_address"/>
<field name="company_id" ref="main_company"/>
<field name="company_ids" eval="[(4, ref('main_company'))]"/>
<field name="action_id" ref="action_menu_admin"/>
<field name="menu_id" ref="action_menu_admin"/>
</record>
<record id="main_partner" model="res.partner">
@@ -1375,6 +1373,9 @@
<field name="currency_id" ref="UAH"/>
<field eval="time.strftime('%Y-01-01')" name="name"/>
</record>
<record id="res_bank_1" model="res.bank">
<field name="name">Reserve</field>
<field name="code">RSV</field>
</record>
</data>
</openerp>
-2
View File
@@ -6,8 +6,6 @@
<field name="password">demo</field>
<field name="name">Demo User</field>
<field name="signature">Mr Demo</field>
<field name="action_id" ref="action_menu_admin"/>
<field name="menu_id" ref="action_menu_admin"/>
<field name="address_id" ref="main_address"/>
<field name="company_id" ref="main_company"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user')])]"/>
+5 -4
View File
@@ -5,8 +5,8 @@
<menuitem icon="terp-administration" id="menu_administration_shortcut" parent="menu_administration" name="Custom Shortcuts" sequence="50"/>
<menuitem id="next_id_4" name="Low Level Objects"
parent="base.menu_administration" sequence="3"
groups="base.group_extended"/>
<menuitem id="menu_low_workflow" name="Workflow Items" parent="base.next_id_4" sequence="1"/>
groups="base.group_no_one"/>
<menuitem id="menu_low_workflow" name="Workflows" parent="base.next_id_4"/>
<menuitem id="menu_custom" name="Customization"
parent="base.menu_administration" sequence="2"
groups="base.group_extended"/>
@@ -21,7 +21,8 @@
groups="base.group_extended"/>
<menuitem id="menu_management" name="Modules" parent="base.menu_administration" sequence="10"
groups="base.group_extended"/>
<menuitem icon="terp-graph" id="reporting_menu" name="Reporting" sequence="45"
groups="group_extended"/>
<menuitem id="reporting_menu"
parent="base.menu_custom" name="Reporting" sequence="30"
/>
</data>
</openerp>
+21 -21
View File
@@ -114,29 +114,29 @@
<newline/>
<notebook colspan="4">
<page string="User">
<group colspan="1" col="2">
<separator string="Contact" colspan="2"/>
<field name="company_id" required="1"
context="{'user_id': self, 'user_preference': 1}"
on_change="on_change_company_id(company_id)"
groups="base.group_multi_company"
/>
<field name="address_id" select="1"/>
<field name="user_email" widget="email"/>
</group>
<group colspan="1" col="2" groups="base.group_extended">
<separator string="Action" colspan="2"/>
<field name="action_id" required="True"/>
<field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
<group colspan="1" col="2">
<separator string="Contact" colspan="2"/>
<field name="company_id" required="1"
context="{'user_id': self, 'user_preference': 1}"
on_change="on_change_company_id(company_id)"
groups="base.group_multi_company"
/>
<field name="address_id"/>
<field name="user_email" widget="email"/>
</group>
<group colspan="1" col="2" groups="base.group_extended">
<separator string="Action" colspan="2"/>
<field name="action_id"/>
<field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
</group>
<group colspan="1" col="2">
<separator string="Preferences" colspan="2"/>
<field name="context_lang"/>
<field name="context_tz"/>
<group colspan="2" col="4">
<field name="view" readonly="0"/>
<field name="menu_tips" colspan="2"/>
</group>
<separator string="Preferences" colspan="2"/>
<field name="context_lang"/>
<field name="context_tz"/>
<group colspan="2" col="4">
<field name="view" readonly="0"/>
<field name="menu_tips" colspan="2"/>
</group>
</group>
<newline/>
<group colspan="2" col="2">
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-12 21:46+0000\n"
"Last-Translator: Bojan Markovic <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:03+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:42+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-11 15:00+0000\n"
"Last-Translator: Martin Hood <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:03+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:46+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:38+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-21 14:25+0000\n"
"Last-Translator: Tanel Kurvits <Unknown>\n"
"PO-Revision-Date: 2010-09-29 07:51+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:43+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-16 19:03+0000\n"
"Last-Translator: Olivier Dony (OpenERP) <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:01+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:43+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-19 17:45+0000\n"
"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:28+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:44+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+2 -2
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-13 08:00+0000\n"
"PO-Revision-Date: 2010-09-29 08:13+0000\n"
"Last-Translator: ub121 <ubs121@gmail.com>\n"
"Language-Team: Mongolian <mn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:44+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+25 -17
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-09 18:36+0000\n"
"Last-Translator: Anup (OpenERP) <ach@tinyerp.com>\n"
"PO-Revision-Date: 2010-10-01 11:47+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:42+0000\n"
"X-Launchpad-Export-Date: 2010-10-02 05:05+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@@ -3366,7 +3366,7 @@ msgstr "U kunt het menu opnieuw laden met (Ctrl+t Ctrl+r)."
#: view:ir.ui.view_sc:0
#: field:res.partner.title,shortcut:0
msgid "Shortcut"
msgstr "Sneltoets"
msgstr "Snelkoppeling"
#. module: base
#: field:ir.model.data,date_init:0
@@ -8109,34 +8109,35 @@ msgstr "U kunt niet twee gebruikers hebben met dezelfde gebruikersnaam !"
#. module: base
#: sql_constraint:ir.model.fields:0
msgid "Size of the field can never be less than 1 !"
msgstr ""
msgstr "De veldlengte kan nooit kleiner dan 1 zijn !"
#. module: base
#: sql_constraint:ir.ui.view_sc:0
msgid "Shortcut for this menu already exists!"
msgstr ""
msgstr "Dit menu heeft al een snelkoppeling!"
#. module: base
#: sql_constraint:ir.model.data:0
msgid ""
"You cannot have multiple records with the same id for the same module !"
msgstr ""
"U kunt niet meer records hebben met dezelfde id voor dezelfde module !"
#. module: base
#: sql_constraint:maintenance.contract:0
msgid "Your maintenance contract is already subscribed in the system !"
msgstr ""
msgstr "Uw onderhoudscontract is al ingeschreven in het systeem !"
#. module: base
#: sql_constraint:ir.module.module:0
#: sql_constraint:ir.module.web:0
msgid "The name of the module must be unique !"
msgstr ""
msgstr "De modulenaam moet uniek zijn !"
#. module: base
#: sql_constraint:ir.module.module:0
msgid "The certificate ID of the module must be unique !"
msgstr ""
msgstr "Het kwaliteitscertificaat id van de module moet uniek zijn !"
#. module: base
#: sql_constraint:res.partner.function:0
@@ -8146,38 +8147,38 @@ msgstr ""
#. module: base
#: sql_constraint:res.partner:0
msgid "The name of the Partner must be unique !"
msgstr ""
msgstr "De relatienaam moet uniek zijn !"
#. module: base
#: sql_constraint:res.country:0
msgid "The name of the country must be unique !"
msgstr ""
msgstr "De landnaam moet uniek zijn !"
#. module: base
#: sql_constraint:res.country:0
msgid "The code of the country must be unique !"
msgstr ""
msgstr "De landcode moet uniek zijn !"
#. module: base
#: sql_constraint:res.lang:0
msgid "The name of the language must be unique !"
msgstr ""
msgstr "De taalnaam moet uniek zijn !"
#. module: base
#: sql_constraint:res.lang:0
msgid "The code of the language must be unique !"
msgstr ""
msgstr "De taalcode moet uniek zijn !"
#. module: base
#: sql_constraint:res.groups:0
msgid "The name of the group must be unique !"
msgstr ""
msgstr "De groepsnaam moet uniek zijn !"
#. module: base
#: code:addons/osv/osv.py:0
#, python-format
msgid "Constraint Error"
msgstr ""
msgstr "Voorwaarde Fout"
#. module: base
#: code:addons/osv/osv.py:0
@@ -8188,6 +8189,10 @@ msgid ""
"reference it\n"
"- creation/update: a mandatory field is not correctly set"
msgstr ""
"De bewerking kan niet worden afgerond, waarschijnlijk vanwege:\n"
"- verwijdering: u probeert een record te verwijderen terwijl er nog door een "
"ander aan wordt gerefereerd\n"
"- maken/wijzigen: een verplicht veld is niet correct ingevuld"
#. module: base
#: code:addons/osv/osv.py:0
@@ -8197,12 +8202,15 @@ msgid ""
"\n"
"[object with reference: %s - %s]"
msgstr ""
"\n"
"\n"
"[object met referentie: %s - %s]"
#. module: base
#: code:addons/osv/osv.py:0
#, python-format
msgid "Integrity Error"
msgstr ""
msgstr "Integriteit Fout"
#~ msgid "Main Company"
#~ msgstr "Moederorganisatie"
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-26 10:02+0000\n"
"Last-Translator: Michał Węgrzynek <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:34+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:45+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+2 -2
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: pt_BR\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-09 18:12+0000\n"
"PO-Revision-Date: 2010-09-29 08:12+0000\n"
"Last-Translator: Anup (OpenERP) <ach@tinyerp.com>\n"
"Language-Team: <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:46+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
+3 -3
View File
@@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-09-27 12:19+0000\n"
"Last-Translator: Daniel Stenlöv (XCLUDE) <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:22+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:46+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
-1
View File
@@ -25,7 +25,6 @@ import ir_ui_menu
import ir_ui_view
import ir_default
import ir_actions
import ir_report_custom
import ir_attachment
import ir_cron
import ir_filters
+210 -198
View File
@@ -10,17 +10,41 @@
<field name="priority">20</field>
<field name="arch" type="xml">
<form string="Connect Events to Actions">
<field name="name" required="1"/>
<field name="model_id" on_change="onchange_object_id(model_id)"/>
<field name="action_id" on_change="onchange_action_id(action_id)"/>
<field name="key2" required="1"/>
<field name="object" readonly="1"/>
<field name="res_id"/>
<field name="value_unpickle"/>
<field name="meta_unpickle"/>
<field name="name" required="1"/>
<newline/>
<group col="2" colspan="2">
<separator string="Action Source" colspan="2"/>
<field name="model_id" on_change="onchange_object_id(model_id)"/>
<field name="res_id"/>
<field name="key2" required="1"/>
</group>
<group col="2" colspan="2">
<separator string="Action To Launch" colspan="2"/>
<field name="action_id" on_change="onchange_action_id(action_id)"/>
<field name="object" readonly="1"/>
</group>
<group col="2" colspan="2">
<separator string="Values for Event Type" colspan="2"/>
<label string="client_action_multi, client_action_relate" colspan="2"/>
<label string="tree_but_action, client_print_multi" colspan="2"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Value"/>
<field name="value_unpickle" nolabel="1" colspan="4"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Metadata"/>
<field name="meta_unpickle" nolabel="1"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string=""/>
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</form>
</group>
</form>
</field>
</record>
@@ -47,12 +71,17 @@
<field name="name"/>
<field name="model"/>
<field name="key2"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'key2'}"/>
</group>
</search>
</field>
</record>
<record id="act_values_form_action" model="ir.actions.act_window">
<field name="name">Client Actions</field>
<field name="name">Client Events</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.values</field>
<field name="view_type">form</field>
@@ -63,20 +92,20 @@
</record>
<record model="ir.actions.act_window.view" id="action_values_tree_view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="values_view_tree_action"/>
<field name="act_window_id" ref="act_values_form_action"/>
</record>
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="values_view_tree_action"/>
<field name="act_window_id" ref="act_values_form_action"/>
</record>
<record model="ir.actions.act_window.view" id="action_values_form_view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="values_view_form_action"/>
<field name="act_window_id" ref="act_values_form_action"/>
</record>
<record model="ir.actions.act_window.view" id="action_values_form_view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="values_view_form_action"/>
<field name="act_window_id" ref="act_values_form_action"/>
</record>
<menuitem action="act_values_form_action" id="menu_values_form_action" parent="base.menu_custom_action"/>
<!-- Values -->
@@ -254,7 +283,7 @@
</record>
<record id="ir_sequence_type" model="ir.actions.act_window">
<field name="name">Sequence Types</field>
<field name="name">Sequence Codes</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.sequence.type</field>
<field name="view_type">form</field>
@@ -312,6 +341,7 @@
</record>
<menuitem id="next_id_6" name="Actions" parent="base.next_id_4" sequence="1"/>
<menuitem action="ir_sequence_actions" id="menu_ir_sequence_actions" parent="next_id_6"/>
<menuitem action="act_values_form_action" id="menu_values_form_action" parent="next_id_6"/>
<!--Filters form view-->
@@ -321,10 +351,10 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Filters">
<group colspan="4" >
<group colspan="4" col="6" >
<field name="name"/>
<field name="user_id"/>
<field name="model_id"/>
<field name="user_id"/>
</group>
<group col="4" expand="1">
<separator string="Domain" colspan="2" />
@@ -362,13 +392,14 @@
<field name="arch" type="xml">
<search string="Filters">
<group colspan="4" col="10">
<field name="name"/>
<field name="user_id"/>
</group>
<newline/>
<group expand="0" string="Group By" colspan="4">
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
</group>
<field name="name"/>
<field name="user_id"/>
<field name="model_id"/>
</group>
<newline/>
<group expand="0" string="Group By" colspan="4">
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
</group>
</search>
</field>
</record>
@@ -394,14 +425,13 @@
<field name="model">ir.actions.report.xml</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Report xml">
<form string="Report">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="model" select="1"/>
<field name="type" select="1"/>
<field name="usage"/>
<field name="report_name" select="1"/>
<field name="usage"/>
<field name="report_type"/>
</group>
@@ -472,7 +502,7 @@
</record>
<record id="ir_action_report_xml" model="ir.actions.act_window">
<field name="name">Report Xml</field>
<field name="name">Reports</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.actions.report.xml</field>
<field name="view_type">form</field>
@@ -547,8 +577,6 @@
</group>
</page>
<page string="Security">
<separator colspan="4" string="Select Users" />
<field colspan="4" name="default_user_ids" nolabel="1"/>
<separator colspan="4" string="Select Groups" />
<field name="groups_id" nolabel="1" colspan="4" />
</page>
@@ -615,10 +643,14 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Wizards">
<field name="name"/>
<field name="type"/>
<field name="wiz_name"/>
<field name="multi"/>
<group colspan="4" col="6">
<field name="name"/>
<field name="type"/>
<field name="wiz_name"/>
</group>
<group colspan="2" col="4">
<field name="multi"/>
</group>
<notebook colspan="4">
<page string="Security">
<field colspan="4" name="groups_id" nolabel="1"/>
@@ -777,7 +809,7 @@
<newline/>
<group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
<filter string="Parent" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'parent_id'}"/>
</group>
</group>
</search>
</field>
</record>
@@ -798,21 +830,25 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Views">
<group colspan="2" col="2">
<separator string="General" colspan="2"/>
<field name="name" select="1"/>
<group colspan="4" col="6">
<field name="name" select="1" colspan="6"/>
<field name="type" select="1"/>
<field name="model" select="1"/>
<field name="priority"/>
</group>
<group colspan="2" col="2">
<separator string="Advanced" colspan="2"/>
<field name="field_parent"/>
<field name="inherit_id" select="1"/>
<field name="xml_id" select="1"/>
</group>
<separator string="View architecture" colspan="4"/>
<field colspan="4" nolabel="1" name="arch"/>
<notebook colspan="4">
<page string="Architecture">
<field colspan="4" nolabel="1" name="arch"/>
</page>
<page string="Extra Info">
<separator string="Advanced" colspan="4"/>
<newline/>
<field name="field_parent"/>
<field name="inherit_id" select="1"/>
<field name="xml_id" select="1"/>
</page>
</notebook>
</form>
</field>
</record>
@@ -839,6 +875,18 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Views">
<filter icon="terp-stock_zoom"
string="Search"
domain="[('type', '=', 'search')]"/>
<separator orientation="vertical"/>
<filter icon="gtk-indent"
string="Tree"
domain="[('type', '=', 'tree')]"/>
<separator orientation="vertical"/>
<filter icon="gtk-new"
string="Form"
domain="[('type', '=','form')]"/>
<newline/>
<field name="name"/>
<field name="type"/>
<field name="model"/>
@@ -846,7 +894,7 @@
<field name="xml_id"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Object" icon="terp-stage" domain="[]" context="{'group_by':'model'}"/>
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model'}"/>
<filter string="Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}"/>
</group>
</search>
@@ -868,10 +916,8 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Attachments">
<group colspan="4" col="4">
<field name="name" select="1" />
<field name="type"/>
</group>
<field name="name" />
<field name="type"/>
<notebook colspan="4">
<page string="Attachment">
<group col="4" colspan="4">
@@ -938,7 +984,7 @@
<newline/>
<group expand="0" string="Group By...">
<filter string="Creator" icon="terp-personal" domain="[]" context="{'group_by':'create_uid'}"/>
<filter string="Date" icon="terp-calendar" domain="[]" context="{'group_by':'create_date'}"/>
<filter string="Month" help="Creation Month" icon="terp-go-month" domain="[]" context="{'group_by':'create_date'}"/>
</group>
</search>
</field>
@@ -954,70 +1000,6 @@
</record>
<menuitem action="action_attachment" id="menu_action_attachment" parent="base.next_id_4"/>
<!-- Report -->
<record id="view_report_custom_fields_tree" model="ir.ui.view">
<field name="name">ir.report.custom.fields.tree</field>
<field name="model">ir.report.custom.fields</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Report Fields">
<field name="sequence"/>
<field name="name"/>
<field name="width"/>
<field name="field_child0"/>
<field name="field_child1"/>
<field name="field_child2"/>
<field name="field_child3"/>
</tree>
</field>
</record>
<record id="view_report_custom_fields_form" model="ir.ui.view">
<field name="name">ir.report.custom.fields</field>
<field name="model">ir.report.custom.fields</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Report Fields">
<field name="name"/>
<field name="alignment"/>
<field name="width"/>
<field name="sequence"/>
<newline/>
<field name="bgcolor"/>
<field name="fontcolor"/>
<newline/>
<field name="operation"/>
<field name="groupby"/>
<field name="cumulate"/>
<newline/>
<field domain="[('model_id','=',parent['model_id'])]" name="field_child0" on_change="onchange_field_child0(field_child0)"/>
<field domain="[('model_id','=',parent['model_id'])]" name="fc0_operande"/>
<field name="fc0_op"/>
<field name="fc0_condition"/>
<newline/>
<field name="field_child1" on_change="onchange_field_child1(field_child1)"/>
<field name="fc1_operande"/>
<field name="fc1_op"/>
<field name="fc1_condition"/>
<newline/>
<field name="field_child2" on_change="onchange_field_child2(field_child2)"/>
<field name="fc2_operande"/>
<field name="fc2_op"/>
<field name="fc2_condition"/>
<newline/>
<field name="field_child3"/>
<field name="fc3_operande"/>
<field name="fc3_op"/>
<field name="fc3_condition"/>
</form>
</field>
</record>
<!--
<menuitem name="Administration/Report/Report Custom" action="action_report_custom"/>
-->
<!-- model -->
<record id="view_model_form" model="ir.ui.view">
<field name="name">ir.model.form</field>
@@ -1121,12 +1103,26 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Model Description">
<filter icon="terp-camera_test"
string="In Memory"
domain="[('osv_memory', '=', True)]"/>
<separator orientation="vertical"/>
<filter icon="terp-stock_align_left_24"
string="Custom"
domain="[('state', '=', 'manual')]"/>
<separator orientation="vertical"/>
<filter icon="terp-translate"
string="Base"
domain="[('state', '=', 'base')]"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="model"/>
<field name="osv_memory"/>
<field name="state"/>
<field name="access_ids"/>
<field name="info"/>
<newline/>
</search>
</field>
</record>
@@ -1138,12 +1134,12 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Fields">
<group colspan="4" col="4">
<field name="name" select="1"/>
<group colspan="4" col="6">
<field name="name" select="1" />
<field name="model_id" attrs="{'readonly': [('state','!=', 'manual')]}"/>
<field name="field_description"/>
<field name="state"/>
</group>
</group>
<notebook colspan="4">
<page string="Properties">
<group colspan="2" col="2">
@@ -1193,12 +1189,29 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Fields">
<filter icon="terp-camera_test"
string="Required"
domain="[('required', '=', True)]"/>
<separator orientation="vertical"/>
<filter icon="terp-stock_align_left_24"
string="Readonly"
domain="[('readonly', '=', True)]"/>
<separator orientation="vertical"/>
<filter icon="terp-translate"
string="Translate"
domain="[('translate', '=', True)]"/>
<newline/>
<field name="name"/>
<field name="field_description"/>
<field name="model_id"/>
<field name="ttype"/>
<field name="required"/>
<field name="readonly"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model_id'}"/>
</group>
</search>
</field>
</record>
@@ -1241,6 +1254,10 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Module Data">
<filter icon="terp-camera_test"
string="Updatable"
domain="[('noupdate', '=', False)]"/>
<separator orientation="vertical"/>
<field name="module"/>
<field name="name"/>
<field name="model"/>
@@ -1248,8 +1265,8 @@
<field name="noupdate"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Module" icon="terp-stage" domain="[]" context="{'group_by':'module'}"/>
<filter string="Object" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'model'}"/>
<filter string="Module" icon="terp-folder-blue" domain="[]" context="{'group_by':'module'}"/>
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model'}"/>
</group>
</search>
</field>
@@ -1314,13 +1331,13 @@
<field name="name"/>
<field name="res_id"/>
<group colspan="2" col="2">
<separator string="Source Term" colspan="2"/>
<field name="src" nolabel="1" height="400"/>
</group>
<group colspan="2" col="2">
<separator string="Tranlsation" colspan="2"/>
<field name="value" nolabel="1" height="400"/>
</group>
<separator string="Source Term" colspan="2"/>
<field name="src" nolabel="1" height="400"/>
</group>
<group colspan="2" col="2">
<separator string="Translation" colspan="2"/>
<field name="value" nolabel="1" height="400"/>
</group>
</form>
</field>
@@ -1407,9 +1424,9 @@
</group>
<notebook colspan="4">
<page string="Groups">
<field name="groups_id" colspan="4" nolabel="1"/>
</page>
</notebook>
<field name="groups_id" colspan="4" nolabel="1"/>
</page>
</notebook>
</form>
</field>
</record>
@@ -1420,11 +1437,11 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Menu">
<field name="name" string="Menu" />
<field name="parent_id"/>
</search>
</field>
</record>
<field name="name" string="Menu" />
<field name="parent_id"/>
</search>
</field>
</record>
<record id="grant_menu_access" model="ir.actions.act_window">
<field name="name">Menu Items</field>
@@ -1480,7 +1497,8 @@
<separator string="Action to Trigger" colspan="4"/>
<field name="model" groups="base.group_extended"/>
<field name="function"/>
<field colspan="4" name="args"/>
<separator string="Arguments" colspan="4"/>
<field colspan="4" name="args" nolabel="1"/>
</page>
</notebook>
</form>
@@ -1499,8 +1517,8 @@
<field name="active"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="User" icon="terp-personal-" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Next Call" icon="terp-go-month"
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
<filter string="Execution" icon="terp-go-month"
domain="[]" context="{'group_by':'nextcall'}" />
</group>
</search>
@@ -1529,7 +1547,7 @@
<field name="view_id" ref="ir_cron_view_tree"/>
</record>
<menuitem id="next_id_10" name="Scheduler" parent="base.menu_config"/>
<menuitem id="next_id_10" name="Scheduler" parent="base.menu_config" groups="base.group_extended"/>
<menuitem action="ir_cron_act" id="menu_ir_cron_act" parent="next_id_10"/>
@@ -1556,17 +1574,17 @@
<field name="arch" type="xml">
<form string="Access Controls">
<group col="6" colspan="4">
<field name="name"/>
<field name="model_id"/>
<field name="group_id"/>
</group>
<separator string="Access" colspan="4"/>
<group col="4" colspan="4">
<field name="perm_read"/>
<field name="perm_write"/>
<field name="perm_create"/>
<field name="perm_unlink"/>
</group>
<field name="name"/>
<field name="model_id"/>
<field name="group_id"/>
</group>
<separator string="Access" colspan="4"/>
<group col="4" colspan="4">
<field name="perm_read"/>
<field name="perm_write"/>
<field name="perm_create"/>
<field name="perm_unlink"/>
</group>
</form>
</field>
</record>
@@ -1577,21 +1595,21 @@
<field name="arch" type="xml">
<search string="Access Controls">
<group>
<filter string="Global" icon="terp-stage" domain="[('group_id','=',False)]"/>
<filter string="Global" icon="terp-stage" domain="[('group_id','=',False)]"/>
<separator orientation="vertical"/>
<filter string="Full Access" icon="terp-gtk-select-all" domain="[('perm_read','=',True),('perm_write','=',True),('perm_create','=',True),('perm_unlink','=',True)]"/>
<filter string="Read Access" icon="terp-stock_align_left_24" domain="[('perm_read','=',True),('perm_write','=',False),('perm_create','=',False),('perm_unlink','=',False)]"/>
<filter string="Write Access" icon="terp-tools" domain="[('perm_read','=',False),('perm_write','=',True),('perm_create','=',False),('perm_unlink','=',False)]"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="model_id"/>
<field name="group_id"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
<filter string="Read Access" icon="terp-stock_align_left_24" domain="[('perm_read','=',True)]"/>
<filter string="Write Access" icon="terp-tools" domain="[('perm_write','=',True)]"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="model_id"/>
<field name="group_id"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
<filter string="Group" icon="terp-personal" domain="[]" context="{'group_by':'group_id'}"/>
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model_id'}"/>
</group>
</group>
</search>
</field>
</record>
@@ -1669,21 +1687,21 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Record rules">
<group>
<group>
<filter string="Global" icon="terp-stage" domain="[('global','=',True)]"/>
<separator orientation="vertical"/>
<filter string="Full Access" icon="terp-gtk-select-all" domain="[('perm_read','=',True),('perm_write','=',True),('perm_create','=',True),('perm_unlink','=',True)]"/>
<filter string="Read Access" icon="terp-stock_align_left_24" domain="[('perm_read','=',True),('perm_write','=',False),('perm_create','=',False),('perm_unlink','=',False)]"/>
<filter string="Write Access" icon="terp-tools" domain="[('perm_read','=',False),('perm_write','=',True),('perm_create','=',False),('perm_unlink','=',False)]"/>
<separator orientation="vertical"/>
<field name="model_id"/>
<field name="global"/>
<field name="groups"/>
</group>
<filter string="Read Access" icon="terp-stock_align_left_24" domain="[('perm_read','=',True)]"/>
<filter string="Write Access" icon="terp-tools" domain="[('perm_write','=',True)]"/>
<separator orientation="vertical"/>
<field name="model_id"/>
<field name="global"/>
<field name="groups"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
<filter string="Object" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'model_id'}"/>
</group>
</group>
</search>
</field>
</record>
@@ -1806,13 +1824,13 @@
<field name="arch" type="xml">
<search string="Server Actions">
<group col="10" colspan="4">
<field name="name"/>
<field name="state"/>
<field name="model_id"/>
</group>
<field name="name"/>
<field name="state"/>
<field name="model_id"/>
</group>
<newline/>
<group expand="0" string="Group By" colspan="4" col="4">
<filter string="Action Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'state'}"/>
<filter string="Action Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'state'}"/>
</group>
</search>
</field>
@@ -1828,7 +1846,7 @@
<field name="search_view_id" ref="view_server_action_search"/>
<field name="context">{'key':'server_action'}</field>
</record>
<menuitem action="action_server_action" id="menu_server_action" parent="base.menu_custom_action"/>
<menuitem action="action_server_action" id="menu_server_action" parent="base.next_id_6"/>
<record id="ir_actions_todo_tree" model="ir.ui.view">
<field name="model">ir.actions.todo</field>
@@ -1838,6 +1856,7 @@
<tree editable="bottom" string="Config Wizard Steps">
<field name="sequence"/>
<field name="action_id"/>
<field name="restart"/>
<field name="state" readonly="1"/>
<button name="action_launch" states="open" string="Launch" type="object" icon="gtk-execute" help="Launch Configuration Wizard"/>
<button name="action_open" states="cancel,skip,done"
@@ -1877,8 +1896,8 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Actions">
<filter string="To Do" name="todo" icon="terp-camera_test" domain=" ['|',('state','=','open'),'&amp;',('state','=','skip'),('restart','=','onskip')]" help="Todo State Or (Skip State And Onskip Restart)"/>
<separator orientation="vertical"/>
<filter string="To Do" name="todo" icon="terp-camera_test" domain=" ['|',('state','=','open'),'&amp;',('state','=','skip'),('restart','=','onskip')]" help="Todo State Or (Skip State And Onskip Restart)"/>
<separator orientation="vertical"/>
<field name="state"/>
<field name="restart"/>
</search>
@@ -1893,14 +1912,7 @@
</record>
<menuitem id="next_id_11" name="Configuration Wizards" parent="base.menu_config" sequence="1"/>
<wizard id="wizard_configuration" model="ir.module.module" name="module.configuration" string="Start Configuration"/>
<menuitem action="act_ir_actions_todo_form" id="menu_ir_actions_todo_form"
parent="next_id_11" groups="base.group_extended" sequence="20"/>
<menuitem
action="wizard_configuration" name="Start Configuration"
id="menu_configurator_module" parent="next_id_11"
type="wizard"/>
</data>
</openerp>
+25 -4
View File
@@ -28,15 +28,16 @@ from tools.translate import _
import netsvc
import re
import copy
import sys
import os
from xml import dom
from report.report_sxw import report_sxw, report_rml
class actions(osv.osv):
_name = 'ir.actions.actions'
_table = 'ir_actions'
_columns = {
'name': fields.char('Action Name', required=True, size=64),
'type': fields.char('Action Type', required=True, size=32),
'type': fields.char('Action Type', required=True, size=32,readonly=True),
'usage': fields.char('Action Usage', size=32),
}
_defaults = {
@@ -72,6 +73,27 @@ class report_xml(osv.osv):
res[report.id] = False
return res
def register_all(self, cr):
"""Report registration handler that may be overridden by subclasses to
add their own kinds of report services.
Loads all reports with no manual loaders (auto==True) and
registers the appropriate services to implement them.
"""
opj = os.path.join
cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True,))
result = cr.dictfetchall()
svcs = netsvc.Service._services
for r in result:
if svcs.has_key('report.'+r['report_name']):
continue
if r['report_rml'] or r['report_rml_content_data']:
report_sxw('report.'+r['report_name'], r['model'],
opj('addons',r['report_rml'] or '/'), header=r['header'])
if r['report_xsl']:
report_rml('report.'+r['report_name'], r['model'],
opj('addons',r['report_xml']),
r['report_xsl'] and opj('addons',r['report_xsl']))
_name = 'ir.actions.report.xml'
_table = 'ir_act_report_xml'
_sequence = 'ir_actions_id_seq'
@@ -81,7 +103,7 @@ class report_xml(osv.osv):
'type': fields.char('Action Type', size=32, required=True),
'report_name': fields.char('Service Name', size=64, required=True),
'usage': fields.char('Action Usage', size=32),
'report_type': fields.selection([ ('pdf','pdf'), ('html','html'), ('raw','raw'), ('sxw','sxw'), ('txt','txt'), ('odt','odt'), ('html2html','HTML from HTML'), ('mako2html','HTML from Mako'), ], string='Report Type', required=True),
'report_type': fields.char('Report Type', size=32, required=True, help="Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..."),
'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'),
'multi': fields.boolean('On multiple doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view."),
'attachment': fields.char('Save As Attachment Prefix', size=128, help='This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.'),
@@ -220,7 +242,6 @@ class act_window(osv.osv):
'search_view_id': fields.many2one('ir.ui.view', 'Search View Ref.'),
'filter': fields.boolean('Filter'),
'auto_search':fields.boolean('Auto Search'),
'default_user_ids': fields.many2many('res.users', 'ir_act_window_user_rel', 'act_id', 'uid', 'Users'),
'search_view' : fields.function(_search_view, type='text', method=True, string='Search View'),
'menus': fields.char('Menus', size=4096),
'help': fields.text('Action description',
+7 -7
View File
@@ -47,15 +47,15 @@ class ir_cron(osv.osv, netsvc.Agent):
'name': fields.char('Name', size=60, required=True),
'user_id': fields.many2one('res.users', 'User', required=True),
'active': fields.boolean('Active'),
'interval_number': fields.integer('Interval Number'),
'interval_number': fields.integer('Interval Number',help="Repeat every x."),
'interval_type': fields.selection( [('minutes', 'Minutes'),
('hours', 'Hours'), ('work_days','Work Days'), ('days', 'Days'),('weeks', 'Weeks'), ('months', 'Months')], 'Interval Unit'),
'numbercall': fields.integer('Number of Calls', help='Number of time the function is called,\na negative number indicates that the function will always be called'),
'doall' : fields.boolean('Repeat Missed'),
'nextcall' : fields.datetime('Next Execution Date', required=True),
'model': fields.char('Object', size=64),
'function': fields.char('Function', size=64),
'args': fields.text('Arguments'),
'numbercall': fields.integer('Number of Calls', help='Number of time the function is called,\na negative number indicates no limit'),
'doall' : fields.boolean('Repeat Missed', help="Enable this if you want to execute missed occurences as soon as the server restarts."),
'nextcall' : fields.datetime('Next Execution Date', required=True, help="Next planned execution date for this scheduler"),
'model': fields.char('Object', size=64, help="Name of object whose function will be called when this scheduler will run. e.g. 'res.partener'"),
'function': fields.char('Function', size=64, help="Name of the method to be called on the object when this scheduler is executed."),
'args': fields.text('Arguments', help="Arguments to be passed to the method. e.g. (uid,)"),
'priority': fields.integer('Priority', help='0=Very Urgent\n10=Not urgent')
}
+1 -1
View File
@@ -42,7 +42,7 @@ class ir_filters(osv.osv):
'user_id':fields.many2one('res.users', 'User', help='False means for every user'),
'domain': fields.text('Domain Value', required=True),
'context': fields.text('Context Value', required=True),
'model_id': fields.selection(_list_all_models, 'Model', required=True),
'model_id': fields.selection(_list_all_models, 'Object', required=True),
}
ir_filters()
-103
View File
@@ -1,103 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# 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 osv import fields,osv
from osv.orm import browse_null
import ir
import report.custom
from tools.translate import _
from tools.safe_eval import safe_eval as eval
import netsvc
class report_custom_fields(osv.osv):
_name = 'ir.report.custom.fields'
_columns = {
'name': fields.char('Name', size=64, required=True),
'field_child0': fields.many2one('ir.model.fields', 'Field child0', required=True),
'fc0_operande': fields.many2one('ir.model.fields', 'Constraint'),
'fc0_condition': fields.char('Condition', size=64),
'fc0_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
'field_child1': fields.many2one('ir.model.fields', 'Field child1'),
'fc1_operande': fields.many2one('ir.model.fields', 'Constraint'),
'fc1_condition': fields.char('condition', size=64),
'fc1_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
'field_child2': fields.many2one('ir.model.fields', 'Field child2'),
'fc2_operande': fields.many2one('ir.model.fields', 'Constraint'),
'fc2_condition': fields.char('condition', size=64),
'fc2_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
'field_child3': fields.many2one('ir.model.fields', 'Field child3'),
'fc3_operande': fields.many2one('ir.model.fields', 'Constraint'),
'fc3_condition': fields.char('condition', size=64),
'fc3_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
'alignment': fields.selection((('left','left'),('right','right'),('center','center')), 'Alignment', required=True),
'sequence': fields.integer('Sequence', required=True),
'width': fields.integer('Fixed Width'),
'operation': fields.selection((('none', 'None'),('calc_sum','Calculate Sum'),('calc_avg','Calculate Average'),('calc_count','Calculate Count'),('calc_max', 'Get Max'))),
'groupby' : fields.boolean('Group By'),
'bgcolor': fields.char('Background Color', size=64),
'fontcolor': fields.char('Font color', size=64),
'cumulate': fields.boolean('Accumulate')
}
_defaults = {
'alignment': lambda *a: 'left',
'bgcolor': lambda *a: 'white',
'fontcolor': lambda *a: 'black',
'operation': lambda *a: 'none',
}
_order = "sequence"
def onchange_any_field_child(self, cr, uid, ids, field_id, level):
if not(field_id):
return {}
next_level_field_name = 'field_child%d' % (level+1)
next_level_operande = 'fc%d_operande' % (level+1)
field = self.pool.get('ir.model.fields').browse(cr, uid, [field_id])[0]
res = self.pool.get(field.model).fields_get(cr, uid, field.name)
if res[field.name].has_key('relation'):
cr.execute('select id from ir_model where model=%s', (res[field.name]['relation'],))
(id,) = cr.fetchone() or (False,)
if id:
return {
'domain': {
next_level_field_name: [('model_id', '=', id)],
next_level_operande: [('model_id', '=', id)]
},
'required': {
next_level_field_name: True
}
}
else:
netsvc.Logger().notifyChannel('web-services', netsvc.LOG_WARNING, _("Using a relation field which uses an unknown object"))
return {'required': {next_level_field_name: True}}
else:
return {'domain': {next_level_field_name: []}}
def get_field_child_onchange_method(level):
return lambda self, cr, uid, ids, field_id: self.onchange_any_field_child(cr, uid, ids, field_id, level)
onchange_field_child0 = get_field_child_onchange_method(0)
onchange_field_child1 = get_field_child_onchange_method(1)
onchange_field_child2 = get_field_child_onchange_method(2)
report_custom_fields()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+2 -1
View File
@@ -137,7 +137,8 @@ class ir_rule(osv.osv):
def domain_get(self, cr, uid, model_name, mode='read', context={}):
dom = self._compute_domain(cr, uid, model_name, mode=mode)
if dom:
return self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
query = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
return query.where_clause, query.where_clause_params, query.tables
return [], [], ['"'+self.pool.get(model_name)._table+'"']
def unlink(self, cr, uid, ids, context=None):
+1 -1
View File
@@ -176,7 +176,7 @@ class ir_values(osv.osv):
where.append('res_id=%s')
params.append(res_id)
where.append('(user_id=%s or (user_id IS NULL))')
where.append('(user_id=%s or (user_id IS NULL)) order by id')
params.append(uid)
clause = ' and '.join(where)
cr.execute('select id,name,value,object,meta, key from ir_values where ' + clause, params)
+1
View File
@@ -19,6 +19,7 @@
#
##############################################################################
import wizard_menu
import wizard_screen
import create_action
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2010 OpenERP s.a. (<http://www.openerp.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 os
import random
import tools
from osv import fields,osv
# Simple base class for wizards that wish to use random images on the left
# side of the form.
class wizard_screen(osv.osv_memory):
_name = 'ir.wizard.screen'
def _get_image(self, cr, uid, context=None):
path = os.path.join('base','res','config_pixmaps','%d.png'%random.randrange(1,4))
file_data = tools.file_open(path,'rb').read()
return base64.encodestring(file_data)
def _get_image_fn(self, cr, uid, ids, name, args, context=None):
image = self._get_image(cr, uid, context)
return dict.fromkeys(ids, image) # ok to use .fromkeys() as the image is same for all
_columns = {
'config_logo': fields.function(_get_image_fn, string='Image', type='binary', method=True),
}
_defaults = {
'config_logo': _get_image
}
wizard_screen()
+1 -1
View File
@@ -171,7 +171,6 @@ class wkf_instance(osv.osv):
_log_access = False
_columns = {
'wkf_id': fields.many2one('workflow', 'Workflow', ondelete='cascade', select=True),
'uid': fields.integer('User ID'),
'res_id': fields.integer('Resource ID', select=True),
'res_type': fields.char('Resource Object', size=64, select=True),
'state': fields.char('State', size=32, select=True),
@@ -194,6 +193,7 @@ class wkf_workitem(osv.osv):
_rec_name = 'state'
_columns = {
'act_id': fields.many2one('workflow.activity', 'Activity', required=True, ondelete="cascade", select=True),
'wkf_id': fields.related('act_id','wkf_id', type='many2one', relation='workflow', string='Workflow'),
'subflow_id': fields.many2one('workflow.instance', 'Subflow', ondelete="cascade", select=True),
'inst_id': fields.many2one('workflow.instance', 'Instance', required=True, ondelete="cascade", select=True),
'state': fields.char('State', size=64, select=True),
+31 -25
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem id="menu_workflow_root" name="Workflow Definitions" parent="base.menu_custom" groups="base.group_extended"/>
<menuitem id="menu_workflow_root" name="Workflows" parent="base.menu_custom" groups="base.group_extended"/>
<!--
================================
@@ -15,11 +15,11 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Workflow">
<group col="6" colspan="4" >
<field name="name"/>
<field name="osv"/>
<field name="on_create"/>
</group>
<group col="6" colspan="4" >
<field name="name"/>
<field name="osv"/>
<field name="on_create"/>
</group>
<separator colspan="4" string="Activities"/>
<field colspan="4" name="activities" nolabel="1"/>
</form>
@@ -94,10 +94,10 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Activity">
<group col="6" colspan="4">
<field name="name"/>
<field name="wkf_id"/>
<field name="kind"/>
<group col="6" colspan="4">
<field name="name"/>
<field name="wkf_id"/>
<field name="kind"/>
</group>
<group colspan="2">
<field name="flow_start"/>
@@ -181,9 +181,9 @@
<field name="action_id"/>
<field name="action"/>
<newline/>
<group expand="0" string="Group By...">
<filter string="Workflow" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'wkf_id'}"/>
</group>
<group expand="0" string="Group By...">
<filter string="Workflow" icon="terp-stock_align_left_24" domain="[]" context="{'group_by':'wkf_id'}"/>
</group>
</search>
</field>
</record>
@@ -210,14 +210,14 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Transition">
<group col="6" colspan ="4">
<field name="act_from"/>
<field name="act_to"/>
<field name="signal"/>
<field name="condition"/>
<field name="trigger_model"/>
<field name="trigger_expr_id"/>
<field name="role_id"/>
<group col="6" colspan ="4">
<field name="act_from"/>
<field name="act_to"/>
<field name="signal"/>
<field name="condition"/>
<field name="trigger_model"/>
<field name="trigger_expr_id"/>
<field name="role_id"/>
</group>
</form>
</field>
@@ -272,7 +272,6 @@
<field name="arch" type="xml">
<form string="Workflow Instances">
<field name="wkf_id" readonly="1"/>
<field name="uid" readonly="1"/>
<field name="res_id" readonly="1"/>
<field name="res_type" readonly="1"/>
<field name="state" readonly="1"/>
@@ -286,7 +285,6 @@
<field name="arch" type="xml">
<tree string="Workflow Instances">
<field name="wkf_id"/>
<field name="uid"/>
<field name="res_id"/>
<field name="res_type"/>
<field name="state"/>
@@ -299,8 +297,9 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Workflow Instances">
<field name="wkf_id"/>
<field name="uid"/>
<filter icon="terp-camera_test" string="Active" domain="[('state','=','active')]" name="active"/>
<separator orientation="vertical"/>
<field name="wkf_id" widget="selection"/>
<field name="res_id"/>
<field name="res_type"/>
<field name="state"/>
@@ -313,6 +312,7 @@
<field name="res_model">workflow.instance</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_workflow_instance_tree"/>
<field name="context">{'search_default_active':1}</field>
<field name="search_view_id" ref="view_workflow_instance_search"/>
</record>
<menuitem action="action_workflow_instance_form" id="menu_workflow_instance" parent="base.menu_low_workflow"/>
@@ -329,6 +329,7 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Workflow Workitems">
<field name="wkf_id" readonly="1"/>
<field name="act_id" readonly="1"/>
<field name="subflow_id" readonly="1"/>
<field name="inst_id" readonly="1"/>
@@ -342,6 +343,7 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Workflow Workitems">
<field name="wkf_id"/>
<field name="act_id"/>
<field name="subflow_id"/>
<field name="inst_id"/>
@@ -355,6 +357,9 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Workflow Workitems">
<filter icon="terp-camera_test" string="Active" name="active" domain="[('state','=','active')]"/>
<separator orientation="vertical"/>
<field name="wkf_id" widget="selection"/>
<field name="act_id"/>
<field name="subflow_id"/>
<field name="inst_id"/>
@@ -368,6 +373,7 @@
<field name="res_model">workflow.workitem</field>
<field name="view_type">form</field>
<field name="view_id" ref="view_workflow_workitem_tree"/>
<field name="context">{'search_default_active':1}</field>
<field name="search_view_id" ref="view_workflow_workitem_search"/>
</record>
<menuitem action="action_workflow_workitem_form" id="menu_workflow_workitem" parent="base.menu_low_workflow"/>
@@ -22,7 +22,6 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Maintenance Contract">
<separator string="Information" colspan="4"/>
<group col="6" colspan="4">
<field name="name"/>
<field name="date_start"/>
+23 -19
View File
@@ -19,27 +19,24 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import tarfile
import re
import urllib
import os
import imp
import logging
import tools
from osv import fields, osv, orm
import zipfile
import release
import os
import re
import urllib
import zipimport
import wizard
import addons
import pooler
import netsvc
import pooler
import release
import tools
from tools.parse_version import parse_version
from tools.translate import _
from osv import fields, osv, orm
class module_category(osv.osv):
_name = "ir.module.category"
_description = "Module Category"
@@ -80,8 +77,9 @@ class module(osv.osv):
info = addons.load_information_from_description_file(name)
if 'version' in info:
info['version'] = release.major_version + '.' + info['version']
except:
pass
except Exception:
self.__logger.debug('Error when trying to fetch informations for '
'module %s', name, exc_info=True)
return info
def _get_latest_version(self, cr, uid, ids, field_name=None, arg=None, context={}):
@@ -116,17 +114,21 @@ class module(osv.osv):
v = view_obj.browse(cr,uid,data_id.res_id)
aa = v.inherit_id and '* INHERIT ' or ''
res[mnames[data_id.module]]['views_by_module'] += aa + v.name + ' ('+v.type+')\n'
except:
pass
except Exception:
self.__logger.debug(
'Unknown error while browsing ir.ui.view[%s]',
data_id.res_id, exc_info=True)
elif key=='ir.actions.report.xml':
res[mnames[data_id.module]]['reports_by_module'] += report_obj.browse(cr,uid,data_id.res_id).name + '\n'
elif key=='ir.ui.menu':
try:
m = menu_obj.browse(cr,uid,data_id.res_id)
res[mnames[data_id.module]]['menus_by_module'] += m.complete_name + '\n'
except:
pass
except KeyError, e:
except Exception:
self.__logger.debug(
'Unknown error while browsing ir.ui.menu[%s]',
data_id.res_id, exc_info=True)
except KeyError:
pass
return res
@@ -393,7 +395,9 @@ class module(osv.osv):
fp = file(fname, 'wb')
fp.write(zipfile)
fp.close()
except Exception, e:
except Exception:
self.__logger.exception('Error when trying to create module '
'file %s', fname)
raise orm.except_orm(_('Error'), _('Can not create the module file:\n %s') % (fname,))
terp = self.get_module_info(mod.name)
self.write(cr, uid, mod.id, self.get_values_from_terp(terp))
@@ -68,6 +68,7 @@ class base_language_export(osv.osv_memory):
return self.write(cr, uid, ids, {'state':'get', 'data':out, 'advice':this.advice, 'name':this.name}, context=context)
_name = "base.language.export"
_inherit = "ir.wizard.screen"
_columns = {
'name': fields.char('Filename', 16, readonly=True),
'lang': fields.selection(_get_languages, 'Language', help='To export a new language, do not select a language.'), # not required: unset = new language
@@ -78,11 +79,11 @@ class base_language_export(osv.osv_memory):
'state': fields.selection( ( ('choose','choose'), # choose language
('get','get'), # get the file
) ),
}
_defaults = { 'state': lambda *a: 'choose',
'name': lambda *a: 'lang.tar.gz'
}
}
_defaults = {
'state': lambda *a: 'choose',
'name': lambda *a: 'lang.tar.gz'
}
base_language_export()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -3,54 +3,56 @@
<data>
<record id="wizard_lang_export" model="ir.ui.view">
<field name="name">Export a Translation File</field>
<field name="name">Export Translations</field>
<field name="model">base.language.export</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Export Translation File">
<group colspan="3">
<group colspan="1">
<label align="0.0" colspan="4" string="The official translations pack of all OpenERP/OpenObjects module are managed through launchpad. We use their online interface to synchronize all translations efforts."/>
<label align="0.0" colspan="4" string=""/>
<label align="0.0" colspan="4" string="To improve some terms of the official translations of OpenERP, you should modify the terms directly on the launchpad interface. If you made lots of translations for your own module, you can also publish all your translation at once."/>
<label align="0.0" colspan="4" string=""/>
<label align="0.0" colspan="4" string="To browse official translations, you can visit this link: "/>
<label align="0.0" colspan="4" string="https://translations.launchpad.net/openobject"/>
</group>
<group colspan="1">
<separator orientation="vertical" rowspan="15"/>
</group>
<group colspan="1">
<group colspan="4" states="choose">
<separator colspan="4" string="Export Translation File"/>
<field name="lang" required="1"/>
<field name="format" required="1"/>
<field height="200" name="modules" nolabel="1" colspan="4"/>
<field invisible="1" name="state"/>
</group>
<group colspan="4" states="get">
<separator string="Export done" colspan="4"/>
<field name="name" invisible="1" colspan="4"/>
<field name="data" nolabel="1" readonly="1" fieldname="name" colspan="4"/>
<field height="80" name="advice" nolabel="1" colspan="4"/>
</group>
<separator string="" colspan="4"/>
<group colspan="2" col="2">
</group>
<group col="2" colspan="2">
<button icon="gtk-cancel" name="act_cancel" special="cancel" states="choose" string="_Close" type="object"/>
<button icon="gtk-ok" name="act_getfile" states="choose" string="_Export" type="object"></button>
<button icon="gtk-close" name="act_destroy" special="cancel" states="get" string="_Close" type="object"/>
</group>
<form string="Export Translations">
<group col="8">
<group colspan="3">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label colspan="4" width="220" string="OpenERP translations (core, modules, clients) are managed through Launchpad.net, our open source project management facility. We use their online interface to synchronize all translations efforts."/>
<label colspan="4" width="220" string="To improve or expand the official translations, you should use directly Lauchpad's web interface (Rosetta). If you need to perform mass translation, Launchpad also allows uploading full .po files at once"/>
<label colspan="4" width="220"/>
<label colspan="4" width="220" string="To browse official translations, you can start with these links:"/>
<label colspan="4" width="220" string="https://help.launchpad.net/Translations"/>
<label colspan="4" width="220" string="https://translations.launchpad.net/openobject"/>
</group>
<separator orientation="vertical" rowspan="15"/>
<group colspan="4">
<group colspan="4" states="choose">
<separator colspan="4" string="Export Translation"/>
<field name="lang"/>
<field name="format" required="1"/>
<field height="200" name="modules" nolabel="1" colspan="4"/>
<field invisible="1" name="state"/>
</group>
<group colspan="4" states="get">
<separator string="Export done" colspan="4"/>
<field name="name" invisible="1" colspan="4"/>
<field name="data" nolabel="1" readonly="1" fieldname="name" colspan="4"/>
<field height="80" name="advice" nolabel="1" colspan="4"/>
</group>
</group>
<group colspan="8" col="8" states="choose">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button icon="gtk-cancel" name="act_cancel" special="cancel" string="_Close" type="object"/>
<button icon="gtk-ok" name="act_getfile" string="_Export" type="object"/>
</group>
<group colspan="8" col="8" states="get">
<separator string="" colspan="8"/>
<label colspan="7" width="220"/>
<button icon="gtk-close" name="act_destroy" special="cancel" string="_Close" type="object"/>
</group>
</group>
</form>
</field>
</record>
<record id="action_wizard_lang_export" model="ir.actions.act_window">
<field name="name">Export a Translation File</field>
<field name="name">Export Translation</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base.language.export</field>
<field name="view_type">form</field>
@@ -21,7 +21,6 @@
import tools
import base64
import pooler
from tempfile import TemporaryFile
from osv import osv, fields
@@ -30,6 +29,7 @@ class base_language_import(osv.osv_memory):
_name = "base.language.import"
_description = "Language Import"
_inherit = "ir.wizard.screen"
_columns = {
'name': fields.char('Language Name',size=64 , required=True),
@@ -3,44 +3,42 @@
<data>
<record id="view_base_import_language" model="ir.ui.view">
<field name="name">Import Language</field>
<field name="name">Import Translation</field>
<field name="model">base.language.import</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import Translation File">
<group colspan="3">
<group colspan="1">
<label string="You have to import a .CSV file which is encoded in UTF-8."/>
<label string="Please check that the first line of your file is one of the following:" colspan="4" align="0.0"/>
<label string="type,name,res_id,src,value" colspan="4"/>
<label string="module,type,name,res_id,src,value" colspan="4"/>
<label string="You can also import .po files." colspan="4" align="0.0"/>
</group>
<group colspan="1">
<separator orientation="vertical" rowspan="8"/>
</group>
<group colspan="1">
<group colspan="4" col="4">
<separator string="Import Translation File" colspan="4"/>
<field name="name" width="200"/>
<field name="code"/>
<field name="data" colspan="4"/>
<form string="Import Translation">
<group col="8">
<group colspan="3">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label colspan="4" width="220" string="Supported file formats: *.csv (Comma-separated values) or *.po (GetText Portable Objects)"/>
<label colspan="4" width="220" string="Please double-check that the file encoding is set to UTF-8 (sometimes called Unicode) when the translator exports it."/>
<label colspan="4" width="220"/>
<label colspan="4" width="220" string="When using CSV format, please also check that the first line of your file is one of the following:"/>
<label colspan="4" width="220" string="- type,name,res_id,src,value"/>
<label colspan="4" width="220" string="- module,type,name,res_id,src,value"/>
</group>
<separator orientation="vertical" rowspan="15"/>
<group colspan="4" col="4">
<separator string="Import Translation" colspan="4"/>
<field name="name" width="200"/>
<field name="code"/>
<field name="data" colspan="4"/>
</group>
<group colspan="8" col="8">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="_Close" icon="gtk-cancel"/>
<button name="import_lang" string="_Import" type="object" icon="gtk-ok"/>
</group>
</group>
<separator string="" colspan="4"/>
<group colspan="2" col="2">
</group>
<group colspan="2" col="2">
<button special="cancel" string="_Close" icon="gtk-cancel"/>
<button name="import_lang" string="_Import" type="object" icon="gtk-ok"/>
</group>
</group>
</group>
</form>
</form>
</field>
</record>
<record id="action_view_base_import_language" model="ir.actions.act_window">
<field name="name">Import Language</field>
<field name="name">Import Translation</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base.language.import</field>
<field name="view_type">form</field>
@@ -49,7 +47,6 @@
</record>
<menuitem
name="Import a Translation File"
action="action_view_base_import_language"
id="menu_view_base_import_language"
parent="menu_translation_export"/>
@@ -20,17 +20,22 @@
##############################################################################
import tools
import pooler
from osv import osv, fields
class base_language_install(osv.osv_memory):
""" Install Language"""
_name = "base.language.install"
_inherit = "ir.wizard.screen"
_description = "Install Language"
_columns = {
'lang': fields.selection(tools.scan_languages(),'Language'),
'lang': fields.selection(tools.scan_languages(),'Language', required=True),
'state':fields.selection([('init','init'),('done','done')], 'state', readonly=True),
}
_defaults = {
'state': 'init',
}
def lang_install(self, cr, uid, ids, context):
@@ -40,30 +45,9 @@ class base_language_install(osv.osv_memory):
modobj = self.pool.get('ir.module.module')
mids = modobj.search(cr, uid, [('state', '=', 'installed')])
modobj.update_translations(cr, uid, mids, lang)
data_obj = self.pool.get('ir.model.data')
id2 = data_obj._get_id(cr, uid, 'base', 'view_base_language_install_msg')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'base.module.import.msg',
'views': [(id2, 'form')],
'view_id': False,
'type': 'ir.actions.act_window',
'target': 'new',
}
self.write(cr, uid, ids, {'state': 'done'}, context=context)
return False
base_language_install()
class base_language_install_msg(osv.osv_memory):
""" Install Language"""
_name = "base.language.install.msg"
_description = "Install Language"
base_language_install_msg()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -8,13 +8,38 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Load Official Translation">
<separator string="Load an Official Translation" colspan="4"/>
<group colspan="4"><field name="lang"/></group>
<label string="" colspan="4"/>
<label string="Please be patient, as this operation may take a few minutes..." colspan="4"/>
<separator string="" colspan="4"/>
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="lang_install" string="Load" type="object" icon="gtk-ok"/>
<group col="8">
<group colspan="3">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label colspan="4" width="220" string="This wizard helps you add a new language to your OpenERP system. After loading a new language it becomes available as default interface language for users and partners."/>
<label colspan="4" width="220"/>
<label colspan="4" width="220" string="Please be patient, this operation may take a few minutes (depending on the number of modules currently installed)..."/>
<field name="state" invisible="1"/>
</group>
<separator orientation="vertical" rowspan="15"/>
<group colspan="4">
<separator string="Load Official Translation" colspan="4"/>
<group states="init" colspan="4">
<field name="lang" colspan="4"/>
</group>
<group states="done" colspan="4">
<label string="The selected language has been successfully installed.
You must change the preferences of the user and open a new menu to view the changes." colspan="4"/>
</group>
</group>
<group colspan="8" col="8" states="init">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="lang_install" string="Load" type="object" icon="gtk-ok"/>
</group>
<group colspan="8" col="8" states="done">
<separator string="" colspan="8"/>
<label colspan="7" width="220"/>
<button special="cancel" string="Close" icon="gtk-ok"/>
</group>
</group>
</form>
</field>
</record>
@@ -32,30 +57,7 @@
name="Load an Official Translation"
action="action_view_base_language_install"
id="menu_view_base_language_install"
parent="menu_translation"/>
<record id="view_base_language_install_msg" model="ir.ui.view">
<field name="name">Official Translation Loaded</field>
<field name="model">base.module.import.msg</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Official Translation Loaded">
<separator string="Official Translation Loaded" colspan="4"/>
<label string="The selected language has been successfully installed.\nYou must change the preferences of the user and open a new menu to view the changes." colspan="4"/>
<separator string="" colspan="4"/>
<button special="cancel" string="OK" icon="gtk-ok"/>
</form>
</field>
</record>
<record id="action_view_base_language_install_msg" model="ir.actions.act_window">
<field name="name">Official Translation Loaded</field>
<field name="res_model">base.module.import.msg</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_base_language_install"/>
<field name="target">new</field>
</record>
parent="menu_translation" sequence="2"/>
</data>
</openerp>
@@ -26,7 +26,7 @@
<menuitem name="Start Configuration"
action="action_start_configurator"
id="menu_view_base_module_configuration" parent="next_id_11"
id="menu_view_base_module_configuration" parent="base.menu_config"
type="server" icon="STOCK_EXECUTE" sequence="100" />
<record model="ir.values" id="action_todo_config">
@@ -38,6 +38,6 @@
<field name="key">action</field>
<field name="model">ir.actions.todo</field>
</record>
</data>
</openerp>
@@ -19,8 +19,6 @@
#
##############################################################################
import pooler
import os
import tools
@@ -34,19 +32,24 @@ class base_module_import(osv.osv_memory):
""" Import Module """
_name = "base.module.import"
_inherit = "ir.wizard.screen"
_description = "Import Module"
_columns = {
'module_file': fields.binary('Module .ZIP file', required=True),
'state':fields.selection([('init','init'),('done','done')], 'state', readonly=True),
'module_name': fields.char('Module Name', size=128),
}
_defaults = {
'state': 'init',
}
def importzip(self, cr, uid, ids, context):
module_obj= self.pool.get('ir.module.module')
active_ids = context and context.get('active_ids', False)
data = self.browse(cr, uid, ids , context=context)[0]
(data,) = self.browse(cr, uid, ids , context=context)
module_data = data.module_file
val =base64.decodestring(module_data)
val = base64.decodestring(module_data)
fp = StringIO()
fp.write(val)
fdata = zipfile.ZipFile(fp, 'r')
@@ -55,62 +58,30 @@ class base_module_import(osv.osv_memory):
ad = tools.config['addons_path']
fname = os.path.join(ad,module_name+'.zip')
fname = os.path.join(ad, module_name+'.zip')
try:
fp = file(fname, 'wb')
fp.write(val)
fp.close()
except IOError, e:
except IOError:
raise osv.except_osv(_('Error !'), _('Can not create the module file: %s !') % (fname,) )
module_obj.update_list(cr, uid,{'module_name': module_name,})
data_obj = self.pool.get('ir.model.data')
id2 = data_obj._get_id(cr, uid, 'base', 'view_base_module_import_msg')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
module_name = module_obj.browse(cr, uid, ids, context=context)
return {
'domain': str([('name', '=', module_name)]),
'name': 'Message',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'base.module.import.msg',
'views': [(id2, 'form')],
'view_id': False,
'type': 'ir.actions.act_window',
'target': 'new',
}
base_module_import()
class base_module_import_msg(osv.osv_memory):
""" message """
_name = "base.module.import.msg"
_description = "Message"
self.pool.get('ir.module.module').update_list(cr, uid, {'module_name': module_name,})
self.write(cr, uid, ids, {'state':'done', 'module_name': module_name}, context)
return False
def action_module_open(self, cr, uid, ids, context):
module_obj = self.pool.get('base.module.import')
data = module_obj.browse(cr, uid, ids , context=context)[0]
module_data = data.module_file
val =base64.decodestring(module_data)
fp = StringIO()
fp.write(val)
fdata = zipfile.ZipFile(fp, 'r')
fname = fdata.namelist()[0]
module_name = os.path.split(fname)[0]
(data,) = self.browse(cr, uid, ids , context=context)
return {
'domain': str([('name', '=', module_name)]),
'name': 'Module List',
'domain': str([('name', '=', data.module_name)]),
'name': 'Modules',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'ir.module.module',
'type': 'ir.actions.act_window',
}
base_module_import_msg()
base_module_import()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -7,17 +7,41 @@
<field name="model">base.module.import</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import module">
<separator string="Module Import" colspan="4"/>
<label string="Please give your module .ZIP file to import." colspan="4"/>
<field name="module_file"/>
<separator string="" colspan="4" />
<newline/>
<group colspan="6" >
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="importzip" string="Import module" type="object" icon="gtk-ok"/>
</group>
</form>
<form string="Import module">
<group col="8">
<group colspan="3">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label colspan="4" width="220" string="This wizard helps you add a new language to you OpenERP system. After loading a new language it becomes available as default interface language for users and partners."/>
<label colspan="4" width="220"/>
<label colspan="4" width="220" string="Please be patient, this operation may take a few minutes (depending on the number of modules currently installed)..."/>
<field name="state" invisible="1"/>
</group>
<separator orientation="vertical" rowspan="15"/>
<group colspan="4">
<separator string="Module Import" colspan="4"/>
<group states="init" colspan="4" col="4">
<label string="Select module package to import (.zip file):" colspan="4"/>
<field name="module_file" colspan="4"/>
</group>
<group states="done" colspan="4" col="4">
<label string="Module file successfully imported!" colspan="4"/>
</group>
</group>
<group colspan="8" col="8" states="init">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="importzip" string="Import module" type="object" icon="gtk-apply"/>
</group>
<group colspan="8" col="8" states="done">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Close" icon="gtk-ok"/>
<button name="action_module_open" string="Open Modules" type="object" icon="gtk-go-forward"/>
</group>
</group>
</form>
</field>
</record>
@@ -31,36 +55,12 @@
</record>
<menuitem
name="Import Module"
action="action_view_base_module_import"
id="menu_view_base_module_import"
parent="menu_management"
sequence="1"/>
name="Import Module"
action="action_view_base_module_import"
id="menu_view_base_module_import"
parent="menu_management"
sequence="1"/>
<record id="view_base_module_import_msg" model="ir.ui.view">
<field name="name">Module Import Message</field>
<field name="model">base.module.import.msg</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Message">
<label string="Module successfully imported !"/>
<separator string="" colspan="4"/>
<newline/>
<group>
<button name="action_module_open" string="Cancel" type="object" icon="gtk-cancel"/>
</group>
</form>
</field>
</record>
<record id="action_view_base_module_import_msg" model="ir.actions.act_window">
<field name="name">Module Import Message</field>
<field name="res_model">base.module.import.msg</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_base_module_import"/>
<field name="target">new</field>
</record>
</data>
</openerp>
@@ -19,16 +19,13 @@
#
##############################################################################
import os
import re
import glob
import time
import imp
import tools
import pooler
import zipfile
from osv import osv, fields
from osv import osv
class base_module_scan(osv.osv_memory):
""" scan module """
@@ -18,8 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import netsvc
import pooler
from osv import osv, fields
class base_module_update(osv.osv_memory):
@@ -27,69 +25,25 @@ class base_module_update(osv.osv_memory):
_name = "base.module.update"
_description = "Update Module"
def update_module(self, cr, uid, ids, context):
"""
Update Module
@param cr: the current row, from the database cursor.
@param uid: the current user’s ID for security checks.
@param ids: the ID or list of IDs
@param context: A standard dictionary
"""
data_obj = self.pool.get('ir.model.data')
id2 = data_obj._get_id(cr, uid, 'base', 'view_base_module_update_open')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
return {
'view_type': 'form',
'view_mode': 'form',
'res_model': 'base.module.update.open',
'views': [(id2, 'form')],
'view_id': False,
'type': 'ir.actions.act_window',
'target': 'new',
}
base_module_update()
class base_module_update_open(osv.osv_memory):
""" Update Module Open """
_name = "base.module.update.open"
_description = "Update Module Open"
def default_get(self, cr, uid, fields, context=None):
"""
This function gets default values
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param fields: List of fields for default value
@param context: A standard dictionary for contextual values
@return : default values of fields.
"""
module_obj = self.pool.get('ir.module.module')
update, add = module_obj.update_list(cr, uid,)
return {'update': update, 'add': add}
_inherit = "ir.wizard.screen"
_columns = {
'update': fields.integer('Number of modules updated', readonly=True),
'add': fields.integer('Number of modules added', readonly=True),
'update': fields.integer('Number of modules updated', readonly=True),
'add': fields.integer('Number of modules added', readonly=True),
'state':fields.selection([('init','init'),('done','done')], 'state', readonly=True),
}
def action_module_open(self, cr, uid, ids, context):
"""
Update Module List Open
_defaults = {
'state': 'init',
}
@param cr: the current row, from the database cursor.
@param uid: the current user’s ID for security checks.
@param ids: the ID or list of IDs
@param context: A standard dictionary
"""
def update_module(self, cr, uid, ids, context=None):
module_obj = self.pool.get('ir.module.module')
update, add = module_obj.update_list(cr, uid,)
self.write(cr, uid, ids, {'update': update, 'add': add, 'state': 'done'}, context=context)
return False
def action_module_open(self, cr, uid, ids, context):
res = {
'domain': str([]),
'name': 'Modules',
@@ -99,13 +53,9 @@ class base_module_update_open(osv.osv_memory):
'view_id': False,
'type': 'ir.actions.act_window',
}
view_obj = self.pool.get('ir.ui.view')
search_view_id = view_obj.search(cr, uid, [('name','=','ir.module.module.list.select')], context=context)
if search_view_id:
res.update({'search_view_id' : search_view_id[0]})
return res
base_module_update_open()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
base_module_update()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -7,15 +7,41 @@
<field name="model">base.module.update</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Scan for new modules">
<label string="This wizard will scan all module repositories (on the server side) to detect any new or updated modules. Please be patient as this operation may take a few seconds..." colspan="4" align="0.0"/>
<separator string="" colspan="4" />
<newline/>
<group colspan="6" >
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="update_module" string="Check new modules" type="object" icon="gtk-ok"/>
</group>
</form>
<form string="Update Module List">
<group col="8">
<group colspan="3">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label colspan="4" width="220" string="This wizard will scan all module repositories on the server side to detect newly added modules as well as any change to existing modules."/>
<label colspan="4" width="220"/>
<label colspan="4" width="220" string="Please be patient, as this operation may take a few seconds..."/>
<field name="state" invisible="1"/>
</group>
<separator orientation="vertical" rowspan="15"/>
<group colspan="4">
<separator string="Module update result" colspan="4"/>
<group states="init" colspan="4">
<label string="Click on Update below to start the process..." colspan="4"/>
</group>
<group states="done" colspan="4">
<field name="update" colspan="4"/>
<field name="add" colspan="4"/>
</group>
</group>
<group colspan="8" col="8" states="init">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="update_module" string="Update" type="object" icon="gtk-ok"/>
</group>
<group colspan="8" col="8" states="done">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Close" icon="gtk-ok"/>
<button name="action_module_open" string="Open Modules" type="object" icon="gtk-go-forward"/>
</group>
</group>
</form>
</field>
</record>
@@ -36,33 +62,5 @@
sequence="2"
icon="STOCK_CONVERT"/>
<record id="view_base_module_update_open" model="ir.ui.view">
<field name="name">Update ModuleList</field>
<field name="model">base.module.update.open</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="New modules">
<field name="update" colspan="4"/>
<field name="add" colspan="4"/>
<separator string="" colspan="4" />
<newline/>
<group colspan="6" >
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="action_module_open" string="OK" type="object" icon="gtk-ok"/>
</group>
</form>
</field>
</record>
<record id="action_view_base_module_update_open" model="ir.actions.act_window">
<field name="name">Update ModuleList</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base.module.update.open</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_base_module_update"/>
<field name="target">new</field>
</record>
</data>
</openerp>
@@ -20,8 +20,6 @@
##############################################################################
import pooler
import os
import tools
from osv import osv, fields
class base_module_upgrade(osv.osv_memory):
@@ -98,7 +96,7 @@ class base_module_upgrade(osv.osv_memory):
raise osv.except_osv('Unmet dependency !', 'Following modules are uninstalled or unknown. \n\n'+'\n'.join(unmet_packages))
mod_obj.download(cr, uid, ids, context=context)
cr.commit()
db, pool = pooler.restart_pool(cr.dbname, update_module=True)
_, pool = pooler.restart_pool(cr.dbname, update_module=True)
id2 = data_obj._get_id(cr, uid, 'base', 'view_base_module_upgrade_install')
if id2:
@@ -35,7 +35,7 @@ class base_update_translations(osv.osv_memory):
lang_obj=pooler.get_pool(cr.dbname).get('res.lang')
ids=lang_obj.search(cr, uid, [('code', '=', lang_code)])
if not ids:
raise osv.orm_except('Bad lang')
raise osv.except_osv(_('No language with code "%s" exists') % lang_code)
lang = lang_obj.browse(cr, uid, ids[0])
return lang.name
def act_cancel(self, cr, uid, ids, context=None):
@@ -51,14 +51,17 @@ class base_update_translations(osv.osv_memory):
return {'type': 'ir.actions.act_window_close'}
def default_get(self, cr, uid, fields, context=None):
lang_obj = self.pool.get('res.lang')
res = super(base_update_translations, self).default_get(cr, uid, fields, context=context)
record_id = context and context.get('active_id', False) or False
lang=lang_obj.browse(cr,uid,record_id).code
return {'lang':lang}
if record_id:
lang = self.pool.get('res.lang').browse(cr, uid, record_id).code
res.update(lang=lang)
return res
_name = 'base.update.translations'
_inherit = "ir.wizard.screen"
_columns = {
'lang': fields.selection(_get_languages, 'Language', required=True),
}
base_update_translations()
base_update_translations()
@@ -2,23 +2,34 @@
<openerp>
<data>
<record id="wizard_update_translations" model="ir.ui.view">
<field name="name">Update Translations</field>
<field name="name">Synchronize Translations</field>
<field name="model">base.update.translations</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form col="3" string="Update Translations">
<field name="lang"/>
<label align="0.0" colspan="4" string="This wizard will detect new terms in the application so that you can update them manually."/>
<separator colspan="4"/>
<group col="2" colspan="4" fill="0">
<button icon="gtk-cancel" name="act_cancel" special="cancel" string="Cancel" type="object"/>
<button icon="gtk-ok" name="act_update" string="Update" type="object"/>
<form string="Synchronize Translations">
<group col="8">
<group colspan="3">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label colspan="4" width="220" string="This wizard will detect new terms to translate in the application, so that you can then add translations manually or perform a complete export (as a template for a new language example)."/>
</group>
<separator orientation="vertical" rowspan="15"/>
<group colspan="4">
<separator string="Synchronize Translation" colspan="4"/>
<field name="lang" colspan="4"/>
</group>
<group colspan="8" col="8">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button icon="gtk-cancel" name="act_cancel" special="cancel" string="Cancel" type="object"/>
<button icon="gtk-ok" name="act_update" string="Update" type="object"/>
</group>
</group>
</form>
</field>
</record>
<record id="action_wizard_update_translations" model="ir.actions.act_window">
<field name="name">Resynchronise Terms</field>
<field name="name">Synchronize Translations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">base.update.translations</field>
<field name="view_type">form</field>
+1 -1
View File
@@ -73,7 +73,7 @@
<field name="view_type">form</field>
<field name="view_id" ref="ir_property_view_tree"/>
</record>
<menuitem id="next_id_15" name="Parameters" parent="base.menu_config"/>
<menuitem id="next_id_15" name="Parameters" parent="base.menu_config" groups="base.group_extended" />
<menuitem action="ir_property_form" id="menu_ir_property_form_all" parent="base.next_id_15"/>
</data>
</openerp>
+1 -1
View File
@@ -392,7 +392,7 @@ class res_partner_bank(osv.osv):
_columns = {
'name': fields.char('Description', size=128),
'acc_number': fields.char('Account Number', size=64, required=False),
'bank': fields.many2one('res.bank', 'Bank'),
'bank': fields.many2one('res.bank', 'Bank', required=True),
'owner_name': fields.char('Account Owner', size=64),
'street': fields.char('Street', size=128),
'zip': fields.char('Zip', change_default=True, size=24),
+4 -15
View File
@@ -19,19 +19,14 @@
#
##############################################################################
import os
import base64
import random
from operator import attrgetter
from osv import osv, fields
import tools
from tools.translate import _
import netsvc
import pooler
class res_config_configurable(osv.osv_memory):
''' Base classes for new-style configuration items
@@ -40,6 +35,7 @@ class res_config_configurable(osv.osv_memory):
their view inherit from the related res_config_view_base view.
'''
_name = 'res.config'
_inherit = 'ir.wizard.screen'
logger = netsvc.Logger()
def get_current_progress(self, cr, uid, context=None):
@@ -57,20 +53,13 @@ class res_config_configurable(osv.osv_memory):
return round(closed*100./total)
return 100.
def _get_image(self, cr, uid, context=None):
file_no = str(random.randint(1,3))
path = os.path.join('base','res','config_pixmaps/%s.png'%file_no)
file_data = tools.file_open(path,'rb').read()
return base64.encodestring(file_data)
_columns = dict(
progress = fields.float('Configuration Progress', readonly=True),
config_logo = fields.binary('Image', readonly=True),
)
)
_defaults = dict(
progress = _progress,
config_logo = _get_image
)
)
def _next_action(self, cr, uid, context=None):
todos = self.pool.get('ir.actions.todo')
+4 -3
View File
@@ -21,7 +21,7 @@
from osv import fields, osv
import tools
import time
class res_log(osv.osv_memory):
_name = 'res.log'
_columns = {
@@ -33,9 +33,10 @@ class res_log(osv.osv_memory):
'create_date': fields.datetime('Created Date', readonly=True),
}
_defaults = {
'user_id': lambda self,cr,uid,ctx: uid
'user_id': lambda self,cr,uid,ctx: uid,
'create_date': time.strftime('%Y-%m-%d %H:%M:%S')
}
_order='date desc'
_order='create_date desc'
# TODO: do not return secondary log if same object than in the model (but unlink it)
def get(self, cr, uid, context={}):
+5 -4
View File
@@ -12,6 +12,7 @@
<field name="name"/>
<field name="user_id"/>
<field name="res_model"/>
<field name="create_date"/>
</search>
</field>
</record>
@@ -21,9 +22,9 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Logs">
<field name="create_date"/>
<field name="name"/>
<field name="user_id"/>
<field name="create_date"/>
</tree>
</field>
</record>
@@ -33,12 +34,12 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Logs">
<field name="name"/>
<group colspan="4" col="8">
<field name="name"/>
<field name="create_date"/>
<group colspan="4" col="6">
<field name="user_id" />
<field name="res_model"/>
<field name="res_id"/>
<field name="create_date" colspan="1"/>
</group>
</form>
</field>
+4 -4
View File
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
@@ -15,7 +15,7 @@
# 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/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@@ -50,7 +50,7 @@ class res_request(osv.osv):
return True
def request_close(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state':'closed', 'active':False})
self.write(cr, uid, ids, {'state':'closed'})
return True
def request_get(self, cr, uid):
@@ -113,7 +113,7 @@ class res_request_history(osv.osv):
'name': lambda *a: 'NoName',
'act_from': lambda obj,cr,uid,context={}: uid,
'act_to': lambda obj,cr,uid,context={}: uid,
'date_sent': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'date_sent': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
res_request_history()
+20 -13
View File
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem name="Requests" id="menu_resquest_ref" parent="base.next_id_4" sequence="1"/>
<record id="res_request_tree-view" model="ir.ui.view">
<field name="name">res.request.tree</field>
<field name="model">res.request</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Requests" colors="blue:state in ('draft');gray:state in ('closed')">
<tree string="Requests" colors="blue:state in ('waiting');gray:state in ('closed')">
<field name="create_date"/>
<field name="act_from"/>
<field name="act_to"/>
@@ -40,9 +42,9 @@
<field colspan="4" name="body" nolabel="1"/>
<group col="5" colspan="4">
<field name="state"/>
<button name="request_close" states="waiting,draft,active" string="End of Request" type="object"/>
<button name="request_send" states="draft,active" string="Send" type="object"/>
<button name="request_reply" states="waiting" string="Reply" type="object"/>
<button name="request_close" states="waiting,draft,active" string="Close" type="object" icon="gtk-close"/>
<button name="request_send" states="draft,active" string="Send" type="object" icon="terp-camera_test"/>
<button name="request_reply" states="waiting" string="Reply" type="object" icon="gtk-undo"/>
</group>
</page>
<page string="References" groups="base.group_extended">
@@ -75,12 +77,15 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Requests">
<group colspan="4" col="10">
<field name="act_from"/>
<field name="act_to" select="1"/>
<field name="name"/>
<field name="state"/>
</group>
<filter string="Current" icon="terp-camera_test" domain="['|',('state','=','draft'),('state','=','active')]"
help="Draft and Active"/>
<separator orientation="vertical"/>
<filter string="Waiting" icon="terp-gtk-media-pause" domain="[('state','=','waiting')]"/>
<separator orientation="vertical"/>
<field name="act_from"/>
<field name="act_to" select="1"/>
<field name="name"/>
<field name="state"/>
<newline/>
<group expand="0" string="Group By" colspan="4">
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
@@ -108,7 +113,7 @@
<field name="search_view_id" ref="res_request_search_view"/>
<field name="context">{"search_default_act_to":uid}</field>
</record>
<menuitem action="res_request-act" id="menu_res_request_act" parent="base.next_id_4" sequence="1"/>
<menuitem action="res_request-act" id="menu_res_request_act" parent="menu_resquest_ref" />
<record id="res_request_link-view" model="ir.ui.view">
<field name="name">res.request.link.form</field>
@@ -146,14 +151,16 @@
</record>
<record id="res_request_link-act" model="ir.actions.act_window">
<field name="name">References Link</field>
<field name="name">Request Reference Types</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.request.link</field>
<field name="view_type">form</field>
<field name="view_id" eval="False"/>
<field name="search_view_id" ref="res_request_link_search_view"/>
</record>
<menuitem action="res_request_link-act" id="menu_res_request_link_act" parent="base.next_id_4" sequence="4"/>
<menuitem action="res_request_link-act" id="menu_res_request_link_act" parent="menu_resquest_ref" />
<record id="res_request_history_tree-view" model="ir.ui.view">
+11 -34
View File
@@ -47,7 +47,7 @@ class groups(osv.osv):
def copy(self, cr, uid, id, default=None, context={}):
group_name = self.read(cr, uid, [id], ['name'])[0]['name']
default.update({'name': group_name +' (copy)'})
default.update({'name': _('%s (copy)')%group_name})
return super(groups, self).copy(cr, uid, id, default, context)
def write(self, cr, uid, ids, vals, context=None):
@@ -75,14 +75,6 @@ class groups(osv.osv):
aid.write({'groups_id': [(4, gid)]})
return gid
def copy(self, cr, uid, id, default={}, context={}, done_list=[], local=False):
group = self.browse(cr, uid, id, context=context)
default = default.copy()
if not 'name' in default:
default['name'] = group['name']
default['name'] = default['name'] + _(' (copy)')
return super(groups, self).copy(cr, uid, id, default, context=context)
def get_extended_interface_group(self, cr, uid, context=None):
data_obj = self.pool.get('ir.model.data')
extended_group_data_id = data_obj._get_id(cr, uid, 'base', 'group_extended')
@@ -153,10 +145,8 @@ class users(osv.osv):
return self.WELCOME_MAIL_BODY
def get_current_company(self, cr, uid):
res=[]
cr.execute('select company_id, res_company.name from res_users left join res_company on res_company.id = company_id where res_users.id=%s' %uid)
res = cr.fetchall()
return res
return cr.fetchall()
def send_welcome_email(self, cr, uid, id, context=None):
logger= netsvc.Logger()
@@ -241,10 +231,10 @@ class users(osv.osv):
" aren't configured, it won't be possible to email new "
"users."),
'signature': fields.text('Signature', size=64),
'address_id': fields.many2one('res.partner.address', 'Company Address'),
'address_id': fields.many2one('res.partner.address', 'Address'),
'active': fields.boolean('Active'),
'action_id': fields.many2one('ir.actions.actions', 'Home Action'),
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action'),
'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."),
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."),
'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'),
'roles_id': fields.many2many('res.roles', 'res_roles_users_rel', 'uid', 'rid', 'Roles'),
@@ -289,15 +279,6 @@ class users(osv.osv):
result = override_password(result)
else:
result = map(override_password, result)
if isinstance(result, list):
for rec in result:
if not rec.get('action_id',True):
rec['action_id'] = (self._get_menu(cr, uid),'Menu')
else:
if not result.get('action_id',True):
result['action_id'] = (self._get_menu(cr, uid),'Menu')
return result
@@ -328,10 +309,6 @@ class users(osv.osv):
self.__admin_ids[cr.dbname] = ir_model_data_obj.read(cr, 1, [mdid], ['res_id'])[0]['res_id']
return self.__admin_ids[cr.dbname]
def _get_action(self,cr, uid, context={}):
ids = self.pool.get('ir.ui.menu').search(cr, uid, [('usage','=','menu')])
return ids and ids[0] or False
def _get_company(self,cr, uid, context=None, uid2=False):
if not uid2:
uid2 = uid
@@ -345,20 +322,20 @@ class users(osv.osv):
return [c]
return False
def _get_menu(self,cr, uid, context={}):
ids = self.pool.get('ir.actions.act_window').search(cr, uid, [('usage','=','menu')])
def _get_menu(self,cr, uid, context=None):
ids = self.pool.get('ir.actions.act_window').search(cr, uid, [('usage','=','menu')], context=context)
return ids and ids[0] or False
def _get_group(self,cr, uid, context={}):
ids = self.pool.get('res.groups').search(cr, uid, [('name','=','Employee')])
return ids or False
def _get_group(self,cr, uid, context=None):
dataobj = self.pool.get('ir.model.data')
data_id = dataobj._get_id(cr, 1, 'base', 'group_user')
return data_id and [data_id] or False
_defaults = {
'password' : lambda *a : '',
'context_lang': lambda *args: 'en_US',
'active' : lambda *a: True,
'menu_id': _get_menu,
'action_id': _get_menu,
'company_id': _get_company,
'company_ids': _get_companies,
'groups_id': _get_group,
+1 -1
View File
@@ -14,7 +14,7 @@
</record>
<record model="res.groups" id="group_user">
<field name="name">Employee</field>
<field name="name">Internal User</field>
</record>
<record model="res.groups" context="{'noadmin':True}" id="group_multi_company">
+1 -1
View File
@@ -16,10 +16,10 @@
"access_ir_model_fields_all","ir_model_fields all","model_ir_model_fields",,1,0,0,0
"access_ir_module_category_group_user","ir_module_category group_user","model_ir_module_category","group_system",1,0,0,0
"access_ir_module_module_group_user","ir_module_module group_user","model_ir_module_module","group_system",1,1,1,1
"access_ir_module_module_user","ir_module_module user","model_ir_module_module",,1,0,0,0
"access_ir_module_module_dependency_group_system","ir_module_module_dependency group_system","model_ir_module_module_dependency","group_system",1,1,1,1
"access_ir_property_group_user","ir_property group_user","model_ir_property",,1,0,0,0
"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,0
"access_ir_report_custom_fields_group_system","ir_report_custom_fields group_system","model_ir_report_custom_fields",,1,0,0,0
"access_ir_rule_group_user","ir_rule group_user","model_ir_rule",,1,0,0,0
"access_ir_rule_group_erp_manager","ir_rule group_erp_manager","model_ir_rule","group_erp_manager",1,1,1,1
"access_ir_sequence_group_user","ir_sequence group_user","model_ir_sequence",,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
16 access_ir_model_fields_all ir_model_fields all model_ir_model_fields 1 0 0 0
17 access_ir_module_category_group_user ir_module_category group_user model_ir_module_category group_system 1 0 0 0
18 access_ir_module_module_group_user ir_module_module group_user model_ir_module_module group_system 1 1 1 1
19 access_ir_module_module_user ir_module_module user model_ir_module_module 1 0 0 0
20 access_ir_module_module_dependency_group_system ir_module_module_dependency group_system model_ir_module_module_dependency group_system 1 1 1 1
21 access_ir_property_group_user ir_property group_user model_ir_property 1 0 0 0
22 access_ir_property_group_user_manager ir_property group_manager model_ir_property base.group_partner_manager 1 1 1 0
access_ir_report_custom_fields_group_system ir_report_custom_fields group_system model_ir_report_custom_fields 1 0 0 0
23 access_ir_rule_group_user ir_rule group_user model_ir_rule 1 0 0 0
24 access_ir_rule_group_erp_manager ir_rule group_erp_manager model_ir_rule group_erp_manager 1 1 1 1
25 access_ir_sequence_group_user ir_sequence group_user model_ir_sequence 1 0 0 0
+88 -120
View File
@@ -54,6 +54,7 @@ from tools.config import config
from tools.translate import _
import fields
from query import Query
import tools
from tools.safe_eval import safe_eval as eval
@@ -914,7 +915,7 @@ class orm_template(object):
nbrmax = max(nbrmax, max2)
warning = warning + w2
reduce(lambda x, y: x and y, newrow)
row[field] = (reduce(lambda x, y: x or y, newrow.values()) and \
row[field] = newrow and (reduce(lambda x, y: x or y, newrow.values()) and \
[(0, 0, newrow)]) or []
i = max2
while (position+i) < len(datas):
@@ -929,7 +930,7 @@ class orm_template(object):
(newrow, max2, w2, translate2, data_id2, data_res_id2) = process_liness(
self, datas, prefix+[field], current_module, relation_obj._name, newfd, position+i)
warning = warning + w2
if reduce(lambda x, y: x or y, newrow.values()):
if newrow and reduce(lambda x, y: x or y, newrow.values()):
row[field].append((0, 0, newrow))
i += max2
nbrmax = max(nbrmax, i)
@@ -2203,35 +2204,15 @@ class orm(orm_template):
if not fields:
fields = self._columns.keys()
# compute the where, order by, limit and offset clauses
(where_clause, where_clause_params, tables) = self._where_calc(cr, uid, domain, context=context)
# apply direct ir.rules from current model
self._apply_ir_rules(cr, uid, where_clause, where_clause_params, tables, 'read', context=context)
# then apply the ir.rules from the parents (through _inherits), adding the appropriate JOINs if needed
for inherited_model in self._inherits:
previous_tables = list(tables)
if self._apply_ir_rules(cr, uid, where_clause, where_clause_params, tables, 'read', model_name=inherited_model, context=context):
# if some rules were applied, need to add the missing JOIN for them to make sense, passing the previous
# list of table in case the inherited table was not in the list before (as that means the corresponding
# JOIN(s) was(were) not present)
self._inherits_join_add(inherited_model, previous_tables, where_clause)
tables = list(set(tables).union(set(previous_tables)))
query = self._where_calc(cr, uid, domain, context=context)
self._apply_ir_rules(cr, uid, query, 'read', context=context)
# Take care of adding join(s) if groupby is an '_inherits'ed field
groupby_list = groupby
if groupby:
if isinstance(groupby, list):
groupby = groupby[0]
tables, where_clause, qfield = self._inherits_join_calc(groupby, tables, where_clause)
if len(where_clause):
where_clause = ' where ' + ' and '.join(where_clause)
else:
where_clause = ''
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
self._inherits_join_calc(groupby, query)
assert not groupby or groupby in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)"
@@ -2263,8 +2244,13 @@ class orm(orm_template):
flist += ','
flist += operator+'('+f+') as '+f
gb = groupby and (' group by '+groupby) or ''
cr.execute('select min(%s.id) as id,' % self._table + flist + ' from ' + ','.join(tables) + where_clause + gb + limit_str + offset_str, where_clause_params)
gb = groupby and (' GROUP BY '+groupby) or ''
from_clause, where_clause, where_clause_params = query.get_sql()
where_clause = where_clause and ' WHERE ' + where_clause
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
cr.execute('SELECT min(%s.id) AS id,' % self._table + flist + ' FROM ' + from_clause + where_clause + gb + limit_str + offset_str, where_clause_params)
alldata = {}
groupby = group_by
for r in cr.dictfetchall():
@@ -2303,43 +2289,37 @@ class orm(orm_template):
del d['id']
return data
def _inherits_join_add(self, parent_model_name, tables, where_clause):
def _inherits_join_add(self, parent_model_name, query):
"""
Add missing table SELECT and JOIN clause for reaching the parent table (no duplicates)
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
:param parent_model_name: name of the parent model for which the clauses should be added
:param tables: list of table._table names enclosed in double quotes as returned
by _where_calc()
:param where_clause: current list of WHERE clause params
:param query: query object on which the JOIN should be added
"""
inherits_field = self._inherits[parent_model_name]
parent_model = self.pool.get(parent_model_name)
parent_table_name = parent_model._table
quoted_parent_table_name = '"%s"' % parent_table_name
if quoted_parent_table_name not in tables:
tables.append(quoted_parent_table_name)
where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name))
return (tables, where_clause)
if quoted_parent_table_name not in query.tables:
query.tables.append(quoted_parent_table_name)
query.where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name))
def _inherits_join_calc(self, field, tables, where_clause):
def _inherits_join_calc(self, field, query):
"""
Adds missing table select and join clause(s) for reaching
Adds missing table select and join clause(s) to ``query`` for reaching
the field coming from an '_inherits' parent table (no duplicates).
:param tables: list of table._table names enclosed in double quotes as returned
by _where_calc()
:param where_clause: current list of WHERE clause params
:return: (tables, where_clause, qualified_field) where ``tables`` and ``where_clause`` are the updated
versions of the parameters, and ``qualified_field`` is the qualified name of ``field``
in the form ``table.field``, to be referenced in queries.
:param field: name of inherited field to reach
:param query: query object on which the JOIN should be added
:return: qualified name of field, to be used in SELECT clause
"""
current_table = self
while field in current_table._inherit_fields and not field in current_table._columns:
parent_model_name = current_table._inherit_fields[field][0]
parent_table = self.pool.get(parent_model_name)
self._inherits_join_add(parent_model_name, tables, where_clause)
self._inherits_join_add(parent_model_name, query)
current_table = parent_table
return (tables, where_clause, '"%s".%s' % (current_table._table, field))
return '"%s".%s' % (current_table._table, field)
def _parent_store_compute(self, cr):
if not self._parent_store:
@@ -3899,84 +3879,87 @@ class orm(orm_template):
raise NotImplementedError(_('This method does not exist anymore'))
# TODO: ameliorer avec NULL
def _where_calc(self, cr, user, args, active_test=True, context=None):
def _where_calc(self, cr, user, domain, active_test=True, context=None):
"""Computes the WHERE clause needed to implement an OpenERP domain.
:param args: the domain to compute
:type args: list
:param domain: the domain to compute
:type domain: list
:param active_test: whether the default filtering of records with ``active``
field set to ``False`` should be applied.
:return: tuple with 3 elements: (where_clause, where_clause_params, tables) where
``where_clause`` contains a list of where clause elements (to be joined with 'AND'),
``where_clause_params`` is a list of parameters to be passed to the db layer
for the where_clause expansion, and ``tables`` is the list of double-quoted
table names that need to be included in the FROM clause.
:rtype: tuple
:return: the query expressing the given domain as provided in domain
:rtype: osv.query.Query
"""
if not context:
context = {}
args = args[:]
domain = domain[:]
# if the object has a field named 'active', filter out all inactive
# records unless they were explicitely asked for
if 'active' in self._columns and (active_test and context.get('active_test', True)):
if args:
if domain:
active_in_args = False
for a in args:
for a in domain:
if a[0] == 'active':
active_in_args = True
if not active_in_args:
args.insert(0, ('active', '=', 1))
domain.insert(0, ('active', '=', 1))
else:
args = [('active', '=', 1)]
domain = [('active', '=', 1)]
if args:
if domain:
import expression
e = expression.expression(args)
e = expression.expression(domain)
e.parse(cr, user, self, context)
tables = e.get_tables()
qu1, qu2 = e.to_sql()
qu1 = qu1 and [qu1] or []
where_clause, where_params = e.to_sql()
where_clause = where_clause and [where_clause] or []
else:
qu1, qu2, tables = [], [], ['"%s"' % self._table]
where_clause, where_params, tables = [], [], ['"%s"' % self._table]
return (qu1, qu2, tables)
return Query(tables, where_clause, where_params)
def _check_qorder(self, word):
if not regex_order.match(word):
raise except_orm(_('AccessError'), _('Invalid "order" specified. A valid "order" specification is a comma-separated list of valid field names (optionally followed by asc/desc for the direction)'))
return True
def _apply_ir_rules(self, cr, uid, where_clause, where_clause_params, tables, mode='read', model_name=None, context=None):
"""Add what's missing in ``where_clause``, ``where_params``, ``tables`` to implement
all appropriate ir.rules (on the current object but also from it's _inherits parents)
def _apply_ir_rules(self, cr, uid, query, mode='read', context=None):
"""Add what's missing in ``query`` to implement all appropriate ir.rules
(using the ``model_name``'s rules or the current model's rules if ``model_name`` is None)
:param where_clause: list with current elements of the WHERE clause (strings)
:param where_clause_params: list with parameters for ``where_clause``
:param tables: list with double-quoted names of the tables that are joined
in ``where_clause``
:param model_name: optional name of the model whose ir.rules should be applied (default:``self._name``)
This could be useful for inheritance for example, but there is no provision to include
the appropriate JOIN for linking the current model to the one referenced in model_name.
:return: True if additional clauses where applied.
:param query: the current query object
"""
added_clause, added_params, added_tables = self.pool.get('ir.rule').domain_get(cr, uid, model_name or self._name, mode, context=context)
if added_clause:
where_clause += added_clause
where_clause_params += added_params
for table in added_tables:
if table not in tables:
tables.append(table)
return True
return False
def apply_rule(added_clause, added_params, added_tables):
if added_clause:
query.where_clause += added_clause
query.where_clause_params += added_params
for table in added_tables:
if table not in query.tables:
query.tables.append(table)
return True
return False
def _generate_m2o_order_by(self, order_field, tables, where_clause):
# apply main rules on the object
rule_obj = self.pool.get('ir.rule')
apply_rule(*rule_obj.domain_get(cr, uid, self._name, mode, context=context))
# apply ir.rules from the parents (through _inherits), adding the appropriate JOINs if needed
for inherited_model in self._inherits:
if apply_rule(*rule_obj.domain_get(cr, uid, inherited_model, mode, context=context)):
# if some rules were applied, need to add the missing JOIN for them to make sense, passing the previous
# list of table in case the inherited table was not in the list before (as that means the corresponding
# JOIN(s) was(were) not present)
self._inherits_join_add(inherited_model, query)
def _generate_m2o_order_by(self, order_field, query):
"""
Add possibly missing JOIN and generate the ORDER BY clause for m2o fields,
Add possibly missing JOIN to ``query`` and generate the ORDER BY clause for m2o fields,
either native m2o fields or function/related fields that are stored, including
intermediate JOINs for inheritance if required.
:return: the qualified field name to use in an ORDER BY clause to sort by ``order_field``
"""
if order_field not in self._columns and order_field in self._inherit_fields:
# also add missing joins for reaching the table containing the m2o field
tables, where_clause, qualified_field = self._inherits_join_calc(order_field, tables, where_clause)
qualified_field = self._inherits_join_calc(order_field, query)
order_field_column = self._inherit_fields[order_field][2]
else:
qualified_field = '"%s"."%s"' % (self._table, order_field)
@@ -3995,16 +3978,14 @@ class orm(orm_template):
# extract the first field name, to be able to qualify it and add desc/asc
m2o_order = m2o_order.split(",",1)[0].strip().split(" ",1)[0]
# the perhaps missing join:
quoted_model_table = '"%s"' % dest_model._table
if quoted_model_table not in tables:
tables.append(quoted_model_table)
where_clause.append('%s = %s.id' % (qualified_field, quoted_model_table))
return ('%s.%s' % (quoted_model_table, m2o_order), tables, where_clause)
# Join the dest m2o table if it's not joined yet. We use [LEFT] OUTER join here
# as we don't want to exclude results that have NULL values for the m2o
src_table, src_field = qualified_field.replace('"','').split('.', 1)
query.join((src_table, dest_model._table, src_field, 'id'), outer=True)
return '"%s"."%s"' % (dest_model._table, m2o_order)
def _generate_order_by(self, order_spec, tables, where_clause):
def _generate_order_by(self, order_spec, query):
"""
Attempt to consruct an appropriate ORDER BY clause based on order_spec, which must be
a comma-separated list of valid field names, optionally followed by an ASC or DESC direction.
@@ -4024,16 +4005,16 @@ class orm(orm_template):
if order_column._classic_read:
order_by_clause = '"%s"."%s"' % (self._table, order_field)
elif order_column._type == 'many2one':
order_by_clause, tables, where_clause = self._generate_m2o_order_by(order_field, tables, where_clause)
order_by_clause = self._generate_m2o_order_by(order_field, query)
else:
continue # ignore non-readable or "non-joignable" fields
elif order_field in self._inherit_fields:
parent_obj = self.pool.get(self._inherit_fields[order_field][0])
order_column = parent_obj._columns[order_field]
if order_column._classic_read:
tables, where_clause, order_by_clause = self._inherits_join_calc(order_field, tables, where_clause)
order_by_clause = self._inherits_join_calc(order_field, query)
elif order_column._type == 'many2one':
order_by_clause, tables, where_clause = self._generate_m2o_order_by(order_field, tables, where_clause)
order_by_clause = self._generate_m2o_order_by(order_field, query)
else:
continue # ignore non-readable or "non-joignable" fields
order_by_elements.append("%s %s" % (order_by_clause, order_direction))
@@ -4054,34 +4035,21 @@ class orm(orm_template):
if context is None:
context = {}
self.pool.get('ir.model.access').check(cr, access_rights_uid or user, self._name, 'read', context=context)
# compute the where, order by, limit and offset clauses
(where_clause, where_clause_params, tables) = self._where_calc(cr, user, args, context=context)
# apply direct ir.rules from current model
self._apply_ir_rules(cr, user, where_clause, where_clause_params, tables, 'read', context=context)
query = self._where_calc(cr, user, args, context=context)
self._apply_ir_rules(cr, user, query, 'read', context=context)
order_by = self._generate_order_by(order, query)
from_clause, where_clause, where_clause_params = query.get_sql()
# then apply the ir.rules from the parents (through _inherits), adding the appropriate JOINs if needed
for inherited_model in self._inherits:
previous_tables = list(tables)
if self._apply_ir_rules(cr, user, where_clause, where_clause_params, tables, 'read', model_name=inherited_model, context=context):
# if some rules were applied, need to add the missing JOIN for them to make sense, passing the previous
# list of table in case the inherited table was not in the list before (as that means the corresponding
# JOIN(s) was(were) not present)
self._inherits_join_add(inherited_model, previous_tables, where_clause)
tables = list(set(tables).union(set(previous_tables)))
where = where_clause
order_by = self._generate_order_by(order, tables, where_clause)
limit_str = limit and ' limit %d' % limit or ''
offset_str = offset and ' offset %d' % offset or ''
where_str = where and (" WHERE %s" % " AND ".join(where)) or ''
where_str = where_clause and (" WHERE %s" % where_clause) or ''
if count:
cr.execute('select count(%s.id) from ' % self._table +
','.join(tables) + where_str + limit_str + offset_str, where_clause_params)
cr.execute('SELECT count("%s".id) FROM ' % self._table + from_clause + where_str + limit_str + offset_str, where_clause_params)
res = cr.fetchall()
return res[0][0]
cr.execute('select %s.id from ' % self._table + ','.join(tables) + where_str + order_by + limit_str+offset_str, where_clause_params)
cr.execute('SELECT "%s".id FROM ' % self._table + from_clause + where_str + order_by + limit_str + offset_str, where_clause_params)
res = cr.fetchall()
return [x[0] for x in res]
+122
View File
@@ -0,0 +1,122 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.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/>.
#
##############################################################################
def _quote(to_quote):
if '"' not in to_quote:
return '"%s"' % to_quote
return to_quote
class Query(object):
"""
Dumb implementation of a Query object, using 3 string lists so far
for backwards compatibility with the (table, where_clause, where_params) previously used.
TODO: To be improved after v6.0 to rewrite part of the ORM and add support for:
- auto-generated multiple table aliases
- multiple joins to the same table with different conditions
- dynamic right-hand-side values in domains (e.g. a.name = a.description)
- etc.
"""
def __init__(self, tables=None, where_clause=None, where_clause_params=None, joins=None):
# holds the list of tables joined using default JOIN.
# the table names are stored double-quoted (backwards compatibility)
self.tables = tables or []
# holds the list of WHERE clause elements, to be joined with
# 'AND' when generating the final query
self.where_clause = where_clause or []
# holds the parameters for the formatting of `where_clause`, to be
# passed to psycopg's execute method.
self.where_clause_params = where_clause_params or []
# holds table joins done explicitly, supporting outer joins. The JOIN
# condition should not be in `where_clause`. The dict is used as follows:
# self.joins = {
# 'table_a': [
# ('table_b', 'table_a_col1', 'table_b_col', 'LEFT JOIN'),
# ('table_c', 'table_a_col2', 'table_c_col', 'LEFT JOIN'),
# ('table_d', 'table_a_col3', 'table_d_col', 'JOIN'),
# ]
# }
# which should lead to the following SQL:
# SELECT ... FROM "table_a" LEFT JOIN "table_b" ON ("table_a"."table_a_col1" = "table_b"."table_b_col")
# LEFT JOIN "table_c" ON ("table_a"."table_a_col2" = "table_c"."table_c_col")
self.joins = joins or {}
def join(self, connection, outer=False):
"""Adds the JOIN specified in ``connection``.
:param connection: a tuple ``(lhs, table, lhs_col, col)``.
The join corresponds to the SQL equivalent of::
``(lhs.lhs_col = table.col)``
:param outer: True if a LEFT OUTER JOIN should be used, if possible
(no promotion to OUTER JOIN is supported in case the JOIN
was already present in the query, as for the moment
implicit INNER JOINs are only connected from NON-NULL
columns so it would not be correct (e.g. for
``_inherits`` or when a domain criterion explicitly
adds filtering)
"""
(lhs, table, lhs_col, col) = connection
lhs = _quote(lhs)
table = _quote(table)
assert lhs in self.tables, "Left-hand-side table must already be part of the query!"
if table in self.tables:
# already joined, must ignore (promotion to outer and multiple joins not supported yet)
pass
else:
# add JOIN
self.tables.append(table)
self.joins.setdefault(lhs, []).append((table, lhs_col, col, outer and 'LEFT JOIN' or 'JOIN'))
return self
def get_sql(self):
"""Returns (query_from, query_where, query_params)"""
query_from = ''
tables_to_process = list(self.tables)
def add_joins_for_table(table, query_from):
for (dest_table, lhs_col, col, join) in self.joins.get(table,[]):
tables_to_process.remove(dest_table)
query_from += ' %s %s ON (%s."%s" = %s."%s")' % \
(join, dest_table, table, lhs_col, dest_table, col)
query_from = add_joins_for_table(dest_table, query_from)
return query_from
for table in tables_to_process:
query_from += table
if table in self.joins:
query_from = add_joins_for_table(table, query_from)
query_from += ','
query_from = query_from[:-1] # drop last comma
return (query_from, " AND ".join(self.where_clause), self.where_clause_params)
def __str__(self):
return '<osv.Query: "SELECT ... FROM %s WHERE %s" with params: %r>' % self.get_sql()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -2
View File
@@ -44,12 +44,11 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False,
cr = db.cursor()
try:
pool.init_set(cr, False)
pool.get('ir.actions.report.xml').register_all(cr)
cr.commit()
finally:
cr.close()
import report
report.interface.register_all(db)
if pooljobs:
pool.get('ir.cron').restart(db.dbname)
return db, pool
-20
View File
@@ -219,25 +219,5 @@ class report_rml(report_int):
obj.render()
return obj.get()
from report_sxw import report_sxw
def register_all(db):
opj = os.path.join
cr = db.cursor()
cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True,))
result = cr.dictfetchall()
cr.close()
svcs = netsvc.Service._services
for r in result:
if svcs.has_key('report.'+r['report_name']):
continue
if r['report_rml'] or r['report_rml_content_data']:
report_sxw('report.'+r['report_name'], r['model'],
opj('addons',r['report_rml'] or '/'), header=r['header'])
if r['report_xsl']:
report_rml('report.'+r['report_name'], r['model'],
opj('addons',r['report_xml']),
r['report_xsl'] and opj('addons',r['report_xsl']))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+17 -17
View File
@@ -98,19 +98,20 @@ class report_printscreen_list(report_int):
continue
child_ids = model.search(cr, uid, inner_domain)
res = model.read(cr, uid, child_ids, result['fields'].keys(), context)
res.sort(lambda x,y: cmp(ids.index(x['id']), ids.index(y['id'])))
rows.extend(res)
dom = [('id','in',ids)]
if self.groupby_no_leaf and len(ids) and not ids[0]:
dom = datas.get('_domain',[])
get_groupby_data(self.groupby, dom)
else:
rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context)
ids2 = map(itemgetter('id'), rows) # getting the ids from read result
if datas['ids'] != ids2: # sorted ids were not taken into consideration for print screen
rows_new = []
for id in datas['ids']:
rows_new += [elem for elem in rows if elem['id'] == id]
rows = rows_new
rows = model.read(cr, uid, datas['ids'], result['fields'].keys(), context)
ids2 = map(itemgetter('id'), rows) # getting the ids from read result
if datas['ids'] != ids2: # sorted ids were not taken into consideration for print screen
rows_new = []
for id in datas['ids']:
rows_new += [elem for elem in rows if elem['id'] == id]
rows = rows_new
res = self._create_table(uid, datas['ids'], result['fields'], fields_order, rows, context, model_desc)
return (self.obj.get(), 'pdf')
@@ -231,7 +232,7 @@ class report_printscreen_list(report_int):
if line[f] != None:
col.text = tools.ustr(line[f] or '')
if float_flag:
col.set('tree','float')
col.set('tree','float')
if line.get('__no_leaf') and temp[count] == 1 and f != 'id' and not line['__context']['group_by']:
tsum[count] = float(tsum[count]) + float(line[f])
if not line.get('__group') and f != 'id' and temp[count] == 1:
@@ -239,19 +240,18 @@ class report_printscreen_list(report_int):
else:
col.text = '/'
node_line = etree.SubElement(lines, 'row')
for f in range(0, len(fields_order)):
col = etree.SubElement(node_line, 'col', para='group', tree='no')
col.set('tree','float')
col.set('tree', 'float')
if tsum[f] != None:
if tsum[f] >= 0.01 :
prec = '%.2f'
total = prec%(tsum[f])
txt = str(total or '')
else:
txt = str(tsum[f] or '')
if tsum[f] != 0.0:
digits = fields[fields_order[f]].get('digits', (16, 2))
prec = '%%.%sf' % (digits[1], )
total = prec % (tsum[f], )
txt = str(total or '')
else:
txt = str(tsum[f] or '')
else:
txt = '/'
if f == 0:
+34 -1
View File
@@ -39,6 +39,7 @@ import tools
import warnings
import zipfile
import common
from osv.fields import float as float_class, function as function_class
DT_FORMAT = '%Y-%m-%d'
DHM_FORMAT = '%Y-%m-%d %H:%M:%S'
@@ -240,9 +241,36 @@ class rml_parse(object):
self.default_lang[lang] = self.lang_dict.copy()
return True
def formatLang(self, value, digits=2, date=False,date_time=False, grouping=True, monetary=False):
def digits_fmt(self, obj=None, f=None, dp=None):
digits = self.get_digits(obj, f, dp)
return "%%.%df" % (digits, )
def get_digits(self, obj=None, f=None, dp=None):
d = DEFAULT_DIGITS = 2
if dp:
decimal_precision_obj = self.pool.get('decimal.precision')
ids = decimal_precision_obj.search(self.cr, self.uid, [('name', '=', dp)])
if ids:
d = decimal_precision_obj.browse(self.cr, self.uid, ids)[0].digits
elif obj and f:
res_digits = getattr(obj._columns[f], 'digits', lambda x: ((16,DEFAULT_DIGITS)))
if isinstance(res_digits, tuple):
d = res_digits[1]
else:
d = res_digits(self.cr)[1]
elif (hasattr(obj, '_field') and\
isinstance(obj._field, (float_class, function_class)) and\
obj._field.digits):
d = obj._field.digits[1] or DEFAULT_DIGITS
return d
def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False):
if digits is None:
digits = self.get_digits(value)
if isinstance(value, (str, unicode)) and not value:
return ''
if not self.lang_dict_called:
self._get_lang_dict()
self.lang_dict_called = True
@@ -250,6 +278,7 @@ class rml_parse(object):
if date or date_time:
if not str(value):
return ''
date_format = self.lang_dict['date_format']
parse_format = DT_FORMAT
if date_time:
@@ -258,9 +287,11 @@ class rml_parse(object):
parse_format = DHM_FORMAT
if not isinstance(value, time.struct_time):
return time.strftime(date_format, time.strptime(value, parse_format))
else:
date = datetime(*value.timetuple()[:6])
return date.strftime(date_format)
return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
def repeatIn(self, lst, name,nodes_parent=False):
@@ -305,6 +336,8 @@ class rml_parse(object):
def set_context(self, objects, data, ids, report_type = None):
self.localcontext['data'] = data
self.localcontext['objects'] = objects
self.localcontext['digits_fmt'] = self.digits_fmt
self.localcontext['get_digits'] = self.get_digits
self.datas = data
self.ids = ids
self.objects = objects
+27
View File
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.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 unittest
import test
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromModule(test))
+22
View File
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.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 test_osv import *
+64
View File
@@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2010 OpenERP S.A. http://www.openerp.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 unittest
from osv.query import Query
class QueryTestCase(unittest.TestCase):
def test_basic_query(self):
query = Query()
query.tables.extend(['"product_product"','"product_template"'])
query.where_clause.append("product_product.template_id = product_template.id")
query.join(("product_template", "product_category", "categ_id", "id"), outer=False) # add normal join
query.join(("product_product", "res_user", "user_id", "id"), outer=True) # outer join
self.assertEquals(query.get_sql()[0].strip(),
""""product_product" LEFT JOIN "res_user" ON ("product_product"."user_id" = "res_user"."id"),"product_template" JOIN "product_category" ON ("product_template"."categ_id" = "product_category"."id") """.strip())
self.assertEquals(query.get_sql()[1].strip(), """product_product.template_id = product_template.id""".strip())
def test_query_chained_explicit_joins(self):
query = Query()
query.tables.extend(['"product_product"','"product_template"'])
query.where_clause.append("product_product.template_id = product_template.id")
query.join(("product_template", "product_category", "categ_id", "id"), outer=False) # add normal join
query.join(("product_category", "res_user", "user_id", "id"), outer=True) # CHAINED outer join
self.assertEquals(query.get_sql()[0].strip(),
""""product_product","product_template" JOIN "product_category" ON ("product_template"."categ_id" = "product_category"."id") LEFT JOIN "res_user" ON ("product_category"."user_id" = "res_user"."id")""".strip())
self.assertEquals(query.get_sql()[1].strip(), """product_product.template_id = product_template.id""".strip())
def test_mixed_query_chained_explicit_implicit_joins(self):
query = Query()
query.tables.extend(['"product_product"','"product_template"'])
query.where_clause.append("product_product.template_id = product_template.id")
query.join(("product_template", "product_category", "categ_id", "id"), outer=False) # add normal join
query.join(("product_category", "res_user", "user_id", "id"), outer=True) # CHAINED outer join
query.tables.append('"account.account"')
query.where_clause.append("product_category.expense_account_id = account_account.id") # additional implicit join
self.assertEquals(query.get_sql()[0].strip(),
""""product_product","product_template" JOIN "product_category" ON ("product_template"."categ_id" = "product_category"."id") LEFT JOIN "res_user" ON ("product_category"."user_id" = "res_user"."id"),"account.account" """.strip())
self.assertEquals(query.get_sql()[1].strip(), """product_product.template_id = product_template.id AND product_category.expense_account_id = account_account.id""".strip())
def test_raise_missing_lhs(self):
query = Query()
query.tables.append('"product_product"')
self.assertRaises(AssertionError, query.join, ("product_template", "product_category", "categ_id", "id"), outer=False)
+3 -3
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2010-09-15 02:58+0000\n"
"Last-Translator: barge <Unknown>\n"
"PO-Revision-Date: 2010-09-29 08:30+0000\n"
"Last-Translator: OpenERP Administrators <Unknown>\n"
"Language-Team: Korean <ko@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:47+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:38+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. Type: string
+2 -2
View File
@@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
"PO-Revision-Date: 2010-09-10 03:13+0000\n"
"PO-Revision-Date: 2010-09-29 08:02+0000\n"
"Last-Translator: ub121 <ubs121@gmail.com>\n"
"Language-Team: Mongolian <mn@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-09-29 04:47+0000\n"
"X-Launchpad-Export-Date: 2010-09-30 04:38+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. Type: string