[MERGE]: Merge with lp:openobject-server
bzr revid: rpa@tinyerp.com-20100903061133-2aamj5doyxpx2ppj
This commit is contained in:
@@ -82,7 +82,7 @@
|
||||
context="{'user_id': self, 'user_preference': 1}" groups="base.group_multi_company"/>
|
||||
<field name="view" readonly="0"/>
|
||||
<label string="" colspan="2"/>
|
||||
<field name="menu_tips" colspan="2"/>
|
||||
<field name="menu_tips" colspan="2" readonly="0"/>
|
||||
<newline/>
|
||||
<separator colspan="4" string="Preferences"/>
|
||||
</page>
|
||||
@@ -116,7 +116,11 @@
|
||||
<page string="User">
|
||||
<field name="address_id" select="1"/>
|
||||
<field name="user_email" widget="email"/>
|
||||
<field name="company_id" required="1" context="{'user_id': self, 'user_preference': 1}" groups="base.group_multi_company"/>
|
||||
<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="action_id" required="True"/>
|
||||
<field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
|
||||
<field name="context_lang"/>
|
||||
|
||||
@@ -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-04-25 04:24+0000\n"
|
||||
"Last-Translator: OpenERP Administrators <Unknown>\n"
|
||||
"PO-Revision-Date: 2010-09-02 07:50+0000\n"
|
||||
"Last-Translator: Quentin THEURET <quentin@theuret.net>\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-07-13 03:45+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
@@ -7998,7 +7998,7 @@ msgstr "Sierra Leone"
|
||||
#: view:res.company:0
|
||||
#: view:res.partner:0
|
||||
msgid "General Information"
|
||||
msgstr "Information générale"
|
||||
msgstr "Informations générales"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
|
||||
@@ -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-08-26 06:44+0000\n"
|
||||
"Last-Translator: Goran Kliska <gkliska@gmail.com>\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:44+0000\n"
|
||||
"Last-Translator: nafterburner <nafterburner@gmail.com>\n"
|
||||
"Language-Team: openerp-translators\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2010-08-27 03:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
"Language: hr\n"
|
||||
|
||||
@@ -7979,12 +7979,12 @@ msgstr ""
|
||||
#. module: base
|
||||
#: model:res.country,name:base.lk
|
||||
msgid "Sri Lanka"
|
||||
msgstr ""
|
||||
msgstr "Sri Lanka"
|
||||
|
||||
#. module: base
|
||||
#: selection:module.lang.install,init,lang:0
|
||||
msgid "Russian / русский язык"
|
||||
msgstr ""
|
||||
msgstr "Ruski / русский язык"
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Recursivity Detected."
|
||||
|
||||
+78
-67
@@ -8,93 +8,93 @@ 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: 2009-11-24 18:49+0000\n"
|
||||
"Last-Translator: Iman Sulaiman <isulaiman@hotmail.com>\n"
|
||||
"PO-Revision-Date: 2010-08-28 06:59+0000\n"
|
||||
"Last-Translator: Iman Sulaiman <iman_sl02@yahoo.com>\n"
|
||||
"Language-Team: Indonesian <id@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-07-13 03:46+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-08-29 03:43+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.sh
|
||||
msgid "Saint Helena"
|
||||
msgstr ""
|
||||
msgstr "Santa Helena"
|
||||
|
||||
#. module: base
|
||||
#: wizard_view:res.partner.sms_send,init:0
|
||||
msgid "SMS - Gateway: clickatell"
|
||||
msgstr ""
|
||||
msgstr "SMS - Gateway: clickatell"
|
||||
|
||||
#. module: base
|
||||
#: view:res.lang:0
|
||||
msgid "%j - Day of the year as a decimal number [001,366]."
|
||||
msgstr ""
|
||||
msgstr "%j - Hari dalam setahun sebagai angka desimal [001,366]."
|
||||
|
||||
#. module: base
|
||||
#: field:ir.values,meta_unpickle:0
|
||||
msgid "Metadata"
|
||||
msgstr ""
|
||||
msgstr "Metadata"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.ui.view,arch:0
|
||||
#: field:ir.ui.view.custom,arch:0
|
||||
msgid "View Architecture"
|
||||
msgstr ""
|
||||
msgstr "Arsitektur View"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_model.py:0
|
||||
#, python-format
|
||||
msgid "You can not create this kind of document! (%s)"
|
||||
msgstr ""
|
||||
msgstr "Anda tidak dapat membuat dokumen seperti ini! (%s)"
|
||||
|
||||
#. module: base
|
||||
#: wizard_field:module.lang.import,init,code:0
|
||||
msgid "Code (eg:en__US)"
|
||||
msgstr ""
|
||||
msgstr "Kode (misal:en__US)"
|
||||
|
||||
#. module: base
|
||||
#: view:workflow:0
|
||||
#: field:workflow.activity,wkf_id:0
|
||||
#: field:workflow.instance,wkf_id:0
|
||||
msgid "Workflow"
|
||||
msgstr ""
|
||||
msgstr "Alur kerja"
|
||||
|
||||
#. module: base
|
||||
#: view:wizard.module.lang.export:0
|
||||
msgid "To browse official translations, you can visit this link: "
|
||||
msgstr ""
|
||||
msgstr "Untuk mencari penterjemahan resmi, anda bisa kunjungi tautan ini: "
|
||||
|
||||
#. module: base
|
||||
#: selection:module.lang.install,init,lang:0
|
||||
msgid "Hungarian / Magyar"
|
||||
msgstr ""
|
||||
msgstr "Bahasa Hungaria"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.server,wkf_model_id:0
|
||||
msgid "Workflow On"
|
||||
msgstr ""
|
||||
msgstr "Alur kerja Pada"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
msgid "Created Views"
|
||||
msgstr ""
|
||||
msgstr "View Tercipta"
|
||||
|
||||
#. module: base
|
||||
#: view:workflow.activity:0
|
||||
msgid "Outgoing transitions"
|
||||
msgstr ""
|
||||
msgstr "Transisi Keluar"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.report.custom,frequency:0
|
||||
msgid "Yearly"
|
||||
msgstr ""
|
||||
msgstr "Tahunan"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.act_window,target:0
|
||||
msgid "Target Window"
|
||||
msgstr ""
|
||||
msgstr "Jendela Sasaran"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.todo,note:base.config_wizard_simple_view
|
||||
@@ -107,6 +107,12 @@ msgid ""
|
||||
"understand. You will be able to switch to the extended view later.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"Pilih antara \"Antaramuka Sederhana\" atau yang diperluas.\n"
|
||||
"Jika anda sedang mencoba atau menggunakan OpenERP untuk pertama kalinya, "
|
||||
"kami sarankan untuk menggunakan antarmuka sederhana, yang memiliki sedikit "
|
||||
"opsi dan field namun mudah untuk dipahami dan anda masih dapat merubahnya ke "
|
||||
"antarmuka yang diperluas nantinya.\n"
|
||||
" "
|
||||
|
||||
#. module: base
|
||||
#: field:ir.rule,operand:0
|
||||
@@ -116,93 +122,93 @@ msgstr ""
|
||||
#. module: base
|
||||
#: model:res.country,name:base.kr
|
||||
msgid "South Korea"
|
||||
msgstr ""
|
||||
msgstr "Korea Selatan"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_workflow_transition_form
|
||||
#: model:ir.ui.menu,name:base.menu_workflow_transition
|
||||
#: view:workflow.activity:0
|
||||
msgid "Transitions"
|
||||
msgstr ""
|
||||
msgstr "Transisi"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_ui_view_custom
|
||||
msgid "ir.ui.view.custom"
|
||||
msgstr ""
|
||||
msgstr "ir.ui.view.custom"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.sz
|
||||
msgid "Swaziland"
|
||||
msgstr ""
|
||||
msgstr "Swaziland"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_actions_report_custom
|
||||
#: selection:ir.ui.menu,action:0
|
||||
msgid "ir.actions.report.custom"
|
||||
msgstr ""
|
||||
msgstr "ir.actions.report.custom"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
msgid "STOCK_CANCEL"
|
||||
msgstr ""
|
||||
msgstr "STOCK_CANCEL"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.report.custom,sortby:0
|
||||
msgid "Sorted By"
|
||||
msgstr ""
|
||||
msgstr "Diurut Berdasarkan"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.sequence,number_increment:0
|
||||
msgid "Increment Number"
|
||||
msgstr ""
|
||||
msgstr "Kenaikan Angka"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_res_company_tree
|
||||
#: model:ir.ui.menu,name:base.menu_action_res_company_tree
|
||||
msgid "Company's Structure"
|
||||
msgstr ""
|
||||
msgstr "Struktur Perusahaan"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_report_custom_fields
|
||||
msgid "ir.report.custom.fields"
|
||||
msgstr ""
|
||||
msgstr "ir.report.custom.fields"
|
||||
|
||||
#. module: base
|
||||
#: view:res.partner:0
|
||||
msgid "Search Partner"
|
||||
msgstr ""
|
||||
msgstr "Pencarian Partner"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/module/wizard/wizard_export_lang.py:0
|
||||
#, python-format
|
||||
msgid "new"
|
||||
msgstr ""
|
||||
msgstr "baru"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
msgid "STOCK_GOTO_TOP"
|
||||
msgstr ""
|
||||
msgstr "STOCK_GOTO_TOP"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.report.custom,multi:0
|
||||
#: field:ir.actions.report.xml,multi:0
|
||||
msgid "On multiple doc."
|
||||
msgstr ""
|
||||
msgstr "Pada multi dok."
|
||||
|
||||
#. module: base
|
||||
#: field:ir.module.category,module_nr:0
|
||||
msgid "Number of Modules"
|
||||
msgstr ""
|
||||
msgstr "Jumlah Modul"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner.bank.type.field,size:0
|
||||
msgid "Max. Size"
|
||||
msgstr ""
|
||||
msgstr "Ukuran Maksimal"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner.address,name:0
|
||||
msgid "Contact Name"
|
||||
msgstr ""
|
||||
msgstr "Nama Kontak"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/module/wizard/wizard_export_lang.py:0
|
||||
@@ -211,142 +217,145 @@ msgid ""
|
||||
"Save this document to a %s file and edit it with a specific software or a "
|
||||
"text editor. The file encoding is UTF-8."
|
||||
msgstr ""
|
||||
"Simpan dokumen ini ke dalam file %s dan editlah menggunakan program text "
|
||||
"editor. Gunakan encoding UTF-8."
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
msgid "STOCK_DELETE"
|
||||
msgstr ""
|
||||
msgstr "STOCK_DELETE"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/ir/ir_model.py:0
|
||||
#, python-format
|
||||
msgid "Password mismatch !"
|
||||
msgstr ""
|
||||
msgstr "Password tidak sama!"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/module/module.py:0
|
||||
#, python-format
|
||||
msgid "This url '%s' must provide an html file with links to zip modules"
|
||||
msgstr ""
|
||||
"Url '%s' ini harus memiliki sebuah file html dengan tautan ke module zip"
|
||||
|
||||
#. module: base
|
||||
#: selection:res.request,state:0
|
||||
msgid "active"
|
||||
msgstr ""
|
||||
msgstr "aktif"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.wizard,wiz_name:0
|
||||
msgid "Wizard Name"
|
||||
msgstr ""
|
||||
msgstr "Nama Wizard"
|
||||
|
||||
#. module: base
|
||||
#: view:res.lang:0
|
||||
msgid "%y - Year without century as a decimal number [00,99]."
|
||||
msgstr ""
|
||||
msgstr "%y - Tahun tanpa abad sebagai angka desimal [00,99]."
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
msgid "STOCK_GOTO_FIRST"
|
||||
msgstr ""
|
||||
msgstr "STOCK_GOTO_FIRST"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.rule.group,rules:0
|
||||
msgid "The rule is satisfied if at least one test is True"
|
||||
msgstr ""
|
||||
msgstr "Aturan ini memuaskan jika setidaknya satu test Benar"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.report.custom.fields,operation:0
|
||||
msgid "Get Max"
|
||||
msgstr ""
|
||||
msgstr "Dapatkan Mak"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.act_window,limit:0
|
||||
msgid "Default limit for the list view"
|
||||
msgstr ""
|
||||
msgstr "Batas baku untuk daftar view"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.model.data,date_update:0
|
||||
msgid "Update Date"
|
||||
msgstr ""
|
||||
msgstr "Tanggal Pembaharuan"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.act_window,src_model:0
|
||||
msgid "Source Object"
|
||||
msgstr ""
|
||||
msgstr "Sumber Obyek"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.act_ir_actions_todo_form
|
||||
#: view:ir.actions.todo:0
|
||||
#: model:ir.ui.menu,name:base.menu_ir_actions_todo_form
|
||||
msgid "Config Wizard Steps"
|
||||
msgstr ""
|
||||
msgstr "Langkah Konfigurasi Wizard"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_ui_view_sc
|
||||
msgid "ir.ui.view_sc"
|
||||
msgstr ""
|
||||
msgstr "ir.ui.view_sc"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.model.access,group_id:0
|
||||
#: field:ir.rule,rule_group:0
|
||||
msgid "Group"
|
||||
msgstr ""
|
||||
msgstr "Grup"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.exports.line,name:0
|
||||
#: field:ir.translation,name:0
|
||||
#: field:res.partner.bank.type.field,name:0
|
||||
msgid "Field Name"
|
||||
msgstr ""
|
||||
msgstr "Nama Kolom"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.open_module_tree_uninstall
|
||||
#: model:ir.ui.menu,name:base.menu_module_tree_uninstall
|
||||
msgid "Uninstalled modules"
|
||||
msgstr ""
|
||||
msgstr "Modul belum terinstal"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.actions.report.xml,report_type:0
|
||||
msgid "txt"
|
||||
msgstr ""
|
||||
msgstr "txt"
|
||||
|
||||
#. module: base
|
||||
#: wizard_view:server.action.create,init:0
|
||||
#: wizard_field:server.action.create,init,type:0
|
||||
msgid "Select Action Type"
|
||||
msgstr ""
|
||||
msgstr "Pilih Jenis Aksi"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.actions.todo,type:0
|
||||
msgid "Configure"
|
||||
msgstr ""
|
||||
msgstr "Konfigur"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.tv
|
||||
msgid "Tuvalu"
|
||||
msgstr ""
|
||||
msgstr "Tuvalu"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.model,state:0
|
||||
#: selection:ir.model.grid,state:0
|
||||
msgid "Custom Object"
|
||||
msgstr ""
|
||||
msgstr "Obyek Kesukaan"
|
||||
|
||||
#. module: base
|
||||
#: field:res.lang,date_format:0
|
||||
msgid "Date Format"
|
||||
msgstr ""
|
||||
msgstr "Format Tanggal"
|
||||
|
||||
#. module: base
|
||||
#: field:res.bank,email:0
|
||||
#: field:res.partner.address,email:0
|
||||
msgid "E-Mail"
|
||||
msgstr ""
|
||||
msgstr "E-Mail"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.an
|
||||
msgid "Netherlands Antilles"
|
||||
msgstr ""
|
||||
msgstr "Netherlands Antilles"
|
||||
|
||||
#. module: base
|
||||
#: code:addons/base/res/res_user.py:0
|
||||
@@ -355,21 +364,23 @@ msgid ""
|
||||
"You can not remove the admin user as it is used internally for resources "
|
||||
"created by OpenERP (updates, module installation, ...)"
|
||||
msgstr ""
|
||||
"Anda tidak dapat menghapus pengguna admin sebab digunakan secara internal "
|
||||
"sebagai sumber yang dibuat oleh OpenERP (pembaharuan, instalasi modul, ...)"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.gf
|
||||
msgid "French Guyana"
|
||||
msgstr ""
|
||||
msgstr "Guyana Perancis"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.ui.view.custom,ref_id:0
|
||||
msgid "Original View"
|
||||
msgstr ""
|
||||
msgstr "View Asli"
|
||||
|
||||
#. module: base
|
||||
#: selection:module.lang.install,init,lang:0
|
||||
msgid "Bosnian / bosanski jezik"
|
||||
msgstr ""
|
||||
msgstr "Bosnia"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.report.xml,attachment_use:0
|
||||
@@ -381,27 +392,27 @@ msgstr ""
|
||||
#. module: base
|
||||
#: help:res.lang,iso_code:0
|
||||
msgid "This ISO code is the name of po files to use for translations"
|
||||
msgstr ""
|
||||
msgstr "Kode ISO ini adalah nama file po untuk digunakan pada penerjemahan"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
msgid "STOCK_MEDIA_REWIND"
|
||||
msgstr ""
|
||||
msgstr "STOCK_MEDIA_REWIND"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.todo,note:0
|
||||
msgid "Text"
|
||||
msgstr ""
|
||||
msgstr "Teks"
|
||||
|
||||
#. module: base
|
||||
#: field:res.country,name:0
|
||||
msgid "Country Name"
|
||||
msgstr ""
|
||||
msgstr "Nama Negara"
|
||||
|
||||
#. module: base
|
||||
#: model:res.country,name:base.coreturn
|
||||
msgid "Colombia"
|
||||
msgstr ""
|
||||
msgstr "Kolombia"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
|
||||
@@ -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-08-26 06:37+0000\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:41+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-08-27 03:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
|
||||
@@ -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-08-26 06:47+0000\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:33+0000\n"
|
||||
"Last-Translator: Harry (Open ERP) <hmo@tinyerp.com>\n"
|
||||
"Language-Team: Japanese <ja@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-08-27 03:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
|
||||
+1242
-1161
File diff suppressed because it is too large
Load Diff
@@ -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-08-26 06:38+0000\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:28+0000\n"
|
||||
"Last-Translator: OpenERP Administrators <Unknown>\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-08-27 03:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:45+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
|
||||
@@ -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-08-10 04:28+0000\n"
|
||||
"Last-Translator: Nikolay Chesnokov <chesnokov_n@msn.com>\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:48+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-08-11 03:47+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:44+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
@@ -2820,7 +2820,7 @@ msgstr "Перу"
|
||||
#. module: base
|
||||
#: selection:ir.model.fields,on_delete:0
|
||||
msgid "Set NULL"
|
||||
msgstr "Устоновить в BULL"
|
||||
msgstr "Установить в NULL"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner.event,som:0
|
||||
|
||||
@@ -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-08-26 06:50+0000\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:31+0000\n"
|
||||
"Last-Translator: Anders Wallenquist <anders.wallenquist@vertel.se>\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-08-27 03:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:45+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
|
||||
@@ -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-08-26 06:41+0000\n"
|
||||
"PO-Revision-Date: 2010-09-02 06:38+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\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-08-27 03:37+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-03 03:45+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
|
||||
@@ -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-08-26 06:49+0000\n"
|
||||
"Last-Translator: Eleanor Chen <chenyueg@gmail.com>\n"
|
||||
"PO-Revision-Date: 2010-09-01 06:36+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-08-27 03:38+0000\n"
|
||||
"X-Launchpad-Export-Date: 2010-09-02 03:51+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
|
||||
#. module: base
|
||||
@@ -199,7 +199,7 @@ msgstr "模块数"
|
||||
#. module: base
|
||||
#: field:res.partner.bank.type.field,size:0
|
||||
msgid "Max. Size"
|
||||
msgstr ""
|
||||
msgstr "字段长度"
|
||||
|
||||
#. module: base
|
||||
#: field:res.partner.address,name:0
|
||||
@@ -229,7 +229,7 @@ msgstr "密码不符合!"
|
||||
#: code:addons/base/module/module.py:0
|
||||
#, python-format
|
||||
msgid "This url '%s' must provide an html file with links to zip modules"
|
||||
msgstr ""
|
||||
msgstr "这个 URL '%s' 必须提供一个链接到 zip 模块文件的 HTML 页面"
|
||||
|
||||
#. module: base
|
||||
#: selection:res.request,state:0
|
||||
@@ -1232,7 +1232,7 @@ msgstr "提示:这个操作会花费一些时间"
|
||||
msgid ""
|
||||
"If set, sequence will only be used in case this python expression matches, "
|
||||
"and will precede other sequences."
|
||||
msgstr ""
|
||||
msgstr "当设置后, 系统会优先使用这个python表达式来做为序号."
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.actions.act_window,view_type:0
|
||||
@@ -2606,7 +2606,7 @@ msgstr "作者"
|
||||
#. module: base
|
||||
#: model:res.country,name:base.mk
|
||||
msgid "FYROM"
|
||||
msgstr ""
|
||||
msgstr "马其顿共和国"
|
||||
|
||||
#. module: base
|
||||
#: selection:ir.ui.menu,icon:0
|
||||
@@ -5381,7 +5381,7 @@ msgstr "强制域"
|
||||
#. module: base
|
||||
#: help:ir.sequence,weight:0
|
||||
msgid "If two sequences match, the highest weight will be used."
|
||||
msgstr ""
|
||||
msgstr "如果有两种设置, 则采用优先级最高的一个."
|
||||
|
||||
#. module: base
|
||||
#: model:ir.actions.act_window,name:base.action_attachment
|
||||
@@ -6064,7 +6064,7 @@ msgstr "上级"
|
||||
#. module: base
|
||||
#: view:multi_company.default:0
|
||||
msgid "Returning"
|
||||
msgstr ""
|
||||
msgstr "所属公司"
|
||||
|
||||
#. module: base
|
||||
#: field:ir.actions.act_window,res_model:0
|
||||
|
||||
+17
-29
@@ -179,14 +179,13 @@
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sequences">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="prefix"/>
|
||||
<field name="padding"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="number_next"/>
|
||||
<field name="number_increment"/>
|
||||
<field name="active"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -197,10 +196,10 @@
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Sequences">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="company_id" select="1"/>
|
||||
<field name="company_id" select="1" groups="base.group_multi_company"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
@@ -709,7 +708,6 @@
|
||||
<menuitem id="menu_res_company_global"
|
||||
parent="base.menu_administration"
|
||||
name="Companies"
|
||||
groups="base.group_multi_company"
|
||||
sequence="5"/>
|
||||
|
||||
<record id="action_res_company_tree" model="ir.actions.act_window">
|
||||
@@ -884,13 +882,12 @@
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Views">
|
||||
<field name="priority"/>
|
||||
<field name="priority" string="Sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="model"/>
|
||||
<field name="xml_id"/>
|
||||
<field name="inherit_id"/>
|
||||
<field name="field_parent"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -1201,11 +1198,6 @@
|
||||
<field name="model"/>
|
||||
<field name="state"/>
|
||||
<field name="osv_memory"/>
|
||||
<button colspan="2"
|
||||
icon="gtk-justify-fill"
|
||||
name="%(act_menu_create)d"
|
||||
string="Create a Menu" type="action"
|
||||
target="new" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -1324,9 +1316,8 @@
|
||||
<tree string="Module Data">
|
||||
<field name="module"/>
|
||||
<field name="name"/>
|
||||
<field name="model" select="1" />
|
||||
<field name="model"/>
|
||||
<field name="res_id"/>
|
||||
<field name="noupdate"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -1543,13 +1534,12 @@
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Scheduled Actions">
|
||||
<field name="priority"/>
|
||||
<field name="priority" string="Sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="nextcall"/>
|
||||
<field name="interval_number"/>
|
||||
<field name="interval_type"/>
|
||||
<field name="numbercall"/>
|
||||
<field name="active"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -1915,9 +1905,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Config Wizard Steps">
|
||||
<field name="sequence"/>
|
||||
<field name="action_id" select="1"/>
|
||||
<field name="state"/>
|
||||
<button name="action_id" states="open,skip" string="Launch" type="action" icon="gtk-execute" help="Launch Configuration Wizard"/>
|
||||
<field name="action_id"/>
|
||||
<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"
|
||||
string="Set as Todo" type="object"
|
||||
icon="gtk-convert"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -1929,21 +1922,16 @@
|
||||
<field name="arch" type="xml">
|
||||
<form editable="bottom" string="Config Wizard Steps">
|
||||
<group colspan="4" col="6">
|
||||
<field name="sequence"/>
|
||||
<field name="action_id" select="1"/>
|
||||
<field name="action_id"/>
|
||||
<field name="restart"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
<separator string="Groups" colspan="4"/>
|
||||
<field name="groups_id" nolabel="1" colspan="4"/>
|
||||
<separator string="State" colspan="4"/>
|
||||
<group colspan="4" col="4">
|
||||
<field name="state" colspan="2" readonly="1"/>
|
||||
<!--TO CHECK: This is working in tree view but not here in form view -->
|
||||
<button name="action_id" states="open,skip"
|
||||
string="Launch" type="action"
|
||||
icon="gtk-execute"
|
||||
help="Launch Configuration Wizard" />
|
||||
<button name="action_open" states="cancel,done"
|
||||
<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"
|
||||
string="Set as Todo" type="object"
|
||||
icon="gtk-convert"/>
|
||||
</group>
|
||||
|
||||
@@ -757,6 +757,16 @@ class ir_actions_todo(osv.osv):
|
||||
}
|
||||
_order="sequence,id"
|
||||
|
||||
def action_launch(self, cr, uid, ids, context=None):
|
||||
""" Launch Action of Wizard"""
|
||||
if context is None:
|
||||
context = {}
|
||||
wizard_id = ids and ids[0] or False
|
||||
wizard = self.browse(cr, uid, wizard_id, context=context)
|
||||
res = self.pool.get('ir.actions.act_window').read(cr, uid, wizard.action_id.id, ['name', 'view_type', 'view_mode', 'res_model', 'context', 'views', 'type'], context=context)
|
||||
res.update({'target':'new', 'nodestroy': True})
|
||||
return res
|
||||
|
||||
def action_open(self, cr, uid, ids, context=None):
|
||||
""" Sets configuration wizard in TODO state"""
|
||||
return self.write(cr, uid, ids, {'state': 'open'}, context=context)
|
||||
|
||||
@@ -44,11 +44,6 @@ class ir_filters(osv.osv):
|
||||
'context': fields.text('Context Value', required=True),
|
||||
'model_id': fields.selection(_list_all_models, 'Model', required=True),
|
||||
}
|
||||
|
||||
def get_filters(self, cr, uid, model):
|
||||
act_ids = self.search(cr,uid,[('model_id','=',model),('user_id','=',uid)])
|
||||
my_acts = self.read(cr, uid, act_ids, ['name', 'domain','context'])
|
||||
return my_acts
|
||||
|
||||
ir_filters()
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ class ir_ui_menu(osv.osv):
|
||||
menu_id = self.pool.get('ir.ui.menu').create(cr, uid, menu_data)
|
||||
sc_data= {'name':values['name'], 'sequence': 1,'res_id': menu_id }
|
||||
sc_menu_id = self.pool.get('ir.ui.view_sc').create(cr, uid, sc_data, context)
|
||||
|
||||
user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id'])
|
||||
key = (cr.dbname, shortcut_menu_id, tuple(user_groups))
|
||||
self._cache[key] = True
|
||||
@@ -182,7 +183,7 @@ class ir_ui_menu(osv.osv):
|
||||
rex=re.compile('\([0-9]+\)')
|
||||
concat=rex.findall(datas['name'])
|
||||
if concat:
|
||||
next_num=eval(concat[0])+1
|
||||
next_num=int(concat[0])+1
|
||||
datas['name']=rex.sub(('(%d)'%next_num),datas['name'])
|
||||
else:
|
||||
datas['name']=datas['name']+'(1)'
|
||||
|
||||
@@ -222,14 +222,15 @@ class ir_values(osv.osv):
|
||||
res2 = res[:]
|
||||
for r in res:
|
||||
if type(r[2])==type({}) and 'type' in r[2]:
|
||||
groups = r[2].get('groups_id')
|
||||
if groups:
|
||||
cr.execute('SELECT COUNT(1) FROM res_groups_users_rel WHERE gid IN %s AND uid=%s',(tuple(groups), uid))
|
||||
cnt = cr.fetchone()[0]
|
||||
if cnt:
|
||||
res2.remove(r)
|
||||
if r[1] == 'Menuitem' and not res2:
|
||||
raise osv.except_osv('Error !','You do not have the permission to perform this operation !!!')
|
||||
if r[2]['type'] in ('ir.actions.report.xml','ir.actions.act_window','ir.actions.wizard'):
|
||||
groups = r[2].get('groups_id')
|
||||
if groups:
|
||||
cr.execute('SELECT COUNT(1) FROM res_groups_users_rel WHERE gid IN %s AND uid=%s',(tuple(groups), uid))
|
||||
cnt = cr.fetchone()[0]
|
||||
if not cnt:
|
||||
res2.remove(r)
|
||||
if r[1] == 'Menuitem' and not res2:
|
||||
raise osv.except_osv('Error !','You do not have the permission to perform this operation !!!')
|
||||
return res2
|
||||
ir_values()
|
||||
|
||||
|
||||
@@ -118,6 +118,16 @@
|
||||
<xsl:value-of select="."/>
|
||||
</font></para>
|
||||
</xsl:when>
|
||||
<xsl:when test="@tree='undefined'">
|
||||
<para>
|
||||
<xsl:attribute name="leftIndent">
|
||||
<xsl:value-of select="@space"/>
|
||||
</xsl:attribute>
|
||||
<font fontName="Helvetica-Bold" fontSize="9" color="gray">
|
||||
<xsl:value-of select="."/>
|
||||
</font>
|
||||
</para>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<para>
|
||||
|
||||
@@ -72,7 +72,7 @@ class res_config_configurable(osv.osv_memory):
|
||||
config_logo = _get_image
|
||||
)
|
||||
|
||||
def _next_action(self, cr, uid):
|
||||
def _next_action(self, cr, uid, context=None):
|
||||
todos = self.pool.get('ir.actions.todo')
|
||||
self.logger.notifyChannel('actions', netsvc.LOG_INFO,
|
||||
'getting next %s' % todos)
|
||||
@@ -92,7 +92,7 @@ class res_config_configurable(osv.osv_memory):
|
||||
return self._next_action(cr, uid)
|
||||
return None
|
||||
|
||||
def _set_previous_todo(self, cr, uid, state):
|
||||
def _set_previous_todo(self, cr, uid, state, context=None):
|
||||
""" lookup the previous (which is still the next at this point)
|
||||
ir.actions.todo, set it to whatever state was provided.
|
||||
|
||||
@@ -101,10 +101,12 @@ class res_config_configurable(osv.osv_memory):
|
||||
`ValueError`: if no state is provided
|
||||
anything ir_actions_todo.write can throw
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
# this is ultra brittle, but apart from storing the todo id
|
||||
# into the res.config view, I'm not sure how to get the
|
||||
# "previous" todo
|
||||
previous_todo = self._next_action(cr, uid)
|
||||
previous_todo = self._next_action(cr, uid, context=context)
|
||||
if not previous_todo:
|
||||
raise LookupError(_("Couldn't find previous ir.actions.todo"))
|
||||
if not state:
|
||||
@@ -112,7 +114,7 @@ class res_config_configurable(osv.osv_memory):
|
||||
"nothingness"))
|
||||
previous_todo.write({'state':state})
|
||||
|
||||
def _next(self, cr, uid):
|
||||
def _next(self, cr, uid, context=None):
|
||||
self.logger.notifyChannel('actions', netsvc.LOG_INFO,
|
||||
'getting next operation')
|
||||
next = self._next_action(cr, uid)
|
||||
@@ -139,7 +141,6 @@ class res_config_configurable(osv.osv_memory):
|
||||
.read(cr, uid, current_user_menu.id)
|
||||
|
||||
def start(self, cr, uid, ids, context=None):
|
||||
print 'Start'
|
||||
ids2 = self.pool.get('ir.actions.todo').search(cr, uid, [], context=context)
|
||||
for todo in self.pool.get('ir.actions.todo').browse(cr, uid, ids2, context=context):
|
||||
if (todo.restart=='always') or (todo.restart=='onskip' and (todo.state in ('skip','cancel'))):
|
||||
@@ -150,7 +151,7 @@ class res_config_configurable(osv.osv_memory):
|
||||
""" Returns the next todo action to execute (using the default
|
||||
sort order)
|
||||
"""
|
||||
return self._next(cr, uid)
|
||||
return self._next(cr, uid, context=context)
|
||||
|
||||
def execute(self, cr, uid, ids, context=None):
|
||||
""" Method called when the user clicks on the ``Next`` button.
|
||||
@@ -185,7 +186,10 @@ class res_config_configurable(osv.osv_memory):
|
||||
an action dictionary -- executes the action provided by calling
|
||||
``next``.
|
||||
"""
|
||||
self._set_previous_todo(cr, uid, state='done')
|
||||
try:
|
||||
self._set_previous_todo(cr, uid, state='done', context=context)
|
||||
except Exception, e:
|
||||
raise osv.except_osv(_('Error'), e.message)
|
||||
next = self.execute(cr, uid, ids, context=None)
|
||||
if next: return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
@@ -198,7 +202,10 @@ class res_config_configurable(osv.osv_memory):
|
||||
an action dictionary -- executes the action provided by calling
|
||||
``next``.
|
||||
"""
|
||||
self._set_previous_todo(cr, uid, state='skip')
|
||||
try:
|
||||
self._set_previous_todo(cr, uid, state='skip', context=context)
|
||||
except Exception, e:
|
||||
raise osv.except_osv(_('Error'), e.message)
|
||||
next = self.cancel(cr, uid, ids, context=None)
|
||||
if next: return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
@@ -214,7 +221,10 @@ class res_config_configurable(osv.osv_memory):
|
||||
an action dictionary -- executes the action provided by calling
|
||||
``next``.
|
||||
"""
|
||||
self._set_previous_todo(cr, uid, state='cancel')
|
||||
try:
|
||||
self._set_previous_todo(cr, uid, state='cancel', context=context)
|
||||
except Exception, e:
|
||||
raise osv.except_osv(_('Error'), e.message)
|
||||
next = self.cancel(cr, uid, ids, context=None)
|
||||
if next: return next
|
||||
return self.next(cr, uid, ids, context=context)
|
||||
|
||||
@@ -57,6 +57,18 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="res_request_calendar_view">
|
||||
<field name="name">Request - Calendar</field>
|
||||
<field name="model">res.request</field>
|
||||
<field name="type">calendar</field>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="arch" type="xml">
|
||||
<calendar string="Requests" date_start="trigger_date" color="act_to">
|
||||
<field name="name"/>
|
||||
<field name="act_from"/>
|
||||
</calendar>
|
||||
</field>
|
||||
</record>
|
||||
<record id="res_request_search_view" model="ir.ui.view">
|
||||
<field name="name">res.request.search</field>
|
||||
<field name="model">res.request</field>
|
||||
@@ -65,7 +77,7 @@
|
||||
<search string="Requests">
|
||||
<group colspan="4" col="10">
|
||||
<field name="act_from"/>
|
||||
<field name="act_to"/>
|
||||
<field name="act_to" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
</group>
|
||||
@@ -81,10 +93,11 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.request</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="search_view_id" ref="res_request_search_view"/>
|
||||
<field name="context">{"search_default_act_to":uid}</field>
|
||||
</record>
|
||||
<menuitem id="next_id_12" name="Requests" parent="base.next_id_4"/>
|
||||
<menuitem action="res_request-act" id="menu_res_request_act" parent="next_id_12" sequence="1"/>
|
||||
<menuitem action="res_request-act" id="menu_res_request_act" parent="base.next_id_4" sequence="1"/>
|
||||
|
||||
<record id="res_request_link-view" model="ir.ui.view">
|
||||
<field name="name">res.request.link.form</field>
|
||||
@@ -129,7 +142,7 @@
|
||||
<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_12" sequence="4"/>
|
||||
<menuitem action="res_request_link-act" id="menu_res_request_link_act" parent="base.next_id_4" sequence="4"/>
|
||||
|
||||
|
||||
<record id="res_request_history_tree-view" model="ir.ui.view">
|
||||
|
||||
@@ -209,13 +209,17 @@ class users(osv.osv):
|
||||
return dict(zip(ids, ['extended' if user in extended_users else 'simple' for user in ids]))
|
||||
|
||||
def _email_get(self, cr, uid, ids, name, arg, context=None):
|
||||
return dict([(user.id, user.address_id.email) for user in self.browse(cr, uid, ids, context=context)])
|
||||
# perform this as superuser because the current user is allowed to read users, and that includes
|
||||
# the email, even without any direct read access on the res_partner_address object.
|
||||
return dict([(user.id, user.address_id.email) for user in self.browse(cr, 1, ids)]) # no context to avoid potential security issues as superuser
|
||||
|
||||
def _email_set(self, cr, uid, ids, name, value, arg, context=None):
|
||||
if not isinstance(ids,list):
|
||||
ids = [ids]
|
||||
address_obj = self.pool.get('res.partner.address')
|
||||
for user in self.browse(cr, uid, ids, context=context):
|
||||
# perform this as superuser because the current user is allowed to write to the user, and that includes
|
||||
# the email even without any direct write access on the res_partner_address object.
|
||||
if user.address_id:
|
||||
address_obj.write(cr, 1, user.address_id.id, {'email': value or None}) # no context to avoid potential security issues as superuser
|
||||
else:
|
||||
@@ -264,6 +268,13 @@ class users(osv.osv):
|
||||
|
||||
}
|
||||
|
||||
def on_change_company_id(self, cr, uid, ids, company_id):
|
||||
return {
|
||||
'value': {
|
||||
'warning' : _("Please keep in mind that data currently displayed may not be relevant after switching to another company. If you have unsaved changes, please make sure to save and close the forms before switching to a different company (you can click on Cancel now)"),
|
||||
}
|
||||
}
|
||||
|
||||
def read(self,cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||
def override_password(o):
|
||||
if 'password' in o and ( 'id' not in o or o['id'] != uid ):
|
||||
|
||||
@@ -38,13 +38,20 @@
|
||||
</rng:optional>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="access_rights">
|
||||
<rng:optional>
|
||||
<rng:attribute name="groups"/>
|
||||
</rng:optional>
|
||||
</rng:define>
|
||||
|
||||
|
||||
|
||||
<rng:define name="container">
|
||||
<rng:optional><rng:attribute name="col"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="notebook"/>
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="shortcut"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="hpaned" />
|
||||
@@ -129,7 +136,6 @@
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="shortcut"/>
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="tree"/>
|
||||
<rng:ref name="group"/>
|
||||
@@ -299,8 +305,8 @@
|
||||
<rng:define name="page">
|
||||
<rng:element name="page">
|
||||
<rng:ref name="overload"/>
|
||||
<rng:ref name="access_rights"/>
|
||||
<rng:optional><rng:attribute name="string"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="groups"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
@@ -308,7 +314,6 @@
|
||||
<rng:element name="properties"><rng:empty/></rng:element>
|
||||
<rng:ref name="label" />
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="shortcut"/>
|
||||
<rng:ref name="group"/>
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="button"/>
|
||||
@@ -338,6 +343,7 @@
|
||||
<rng:define name="separator">
|
||||
<rng:element name="separator">
|
||||
<rng:ref name="overload"/>
|
||||
<rng:ref name="access_rights"/>
|
||||
<rng:optional><rng:attribute name="colspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="rowspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="string"/></rng:optional>
|
||||
@@ -349,7 +355,6 @@
|
||||
<rng:ref name="separator"/>
|
||||
<rng:ref name="button"/>
|
||||
<rng:ref name="field"/>
|
||||
<rng:ref name="shortcut"/>
|
||||
<rng:ref name="label" />
|
||||
<rng:ref name="group" />
|
||||
<rng:ref name="filter"/>
|
||||
@@ -401,6 +406,7 @@
|
||||
<rng:element name="field">
|
||||
<rng:attribute name="name" />
|
||||
<rng:ref name="overload"/>
|
||||
<rng:ref name="access_rights"/>
|
||||
<rng:optional><rng:attribute name="editable"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="string"/></rng:optional>
|
||||
@@ -433,7 +439,6 @@
|
||||
<rng:optional><rng:attribute name="view_mode"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="widget"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="context"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="groups"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="states"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="digits"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="icon"/></rng:optional>
|
||||
@@ -474,12 +479,12 @@
|
||||
<rng:define name="group">
|
||||
<rng:element name="group">
|
||||
<rng:ref name="overload"/>
|
||||
<rng:ref name="access_rights"/>
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="colspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="rowspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="expand"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="states"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="groups"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="string"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="fill"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="height"/></rng:optional>
|
||||
@@ -527,6 +532,7 @@
|
||||
<rng:define name="button">
|
||||
<rng:element name="button">
|
||||
<rng:ref name="overload"/>
|
||||
<rng:ref name="access_rights"/>
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="invisible"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="name" /></rng:optional>
|
||||
@@ -537,7 +543,6 @@
|
||||
<rng:optional><rng:attribute name="special" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="align" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="colspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="groups"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="target"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="readonly"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="context"/></rng:optional>
|
||||
@@ -571,6 +576,7 @@
|
||||
<rng:define name="filter">
|
||||
<rng:element name="filter">
|
||||
<rng:ref name="overload"/>
|
||||
<rng:ref name="access_rights"/>
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="name" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="separator" /></rng:optional>
|
||||
@@ -579,7 +585,6 @@
|
||||
<rng:optional><rng:attribute name="type" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="align" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="colspan"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="groups"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="readonly"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="context"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="help"/></rng:optional>
|
||||
@@ -608,15 +613,6 @@
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="shortcut">
|
||||
<rng:element name="shortcut">
|
||||
<rng:optional><rng:attribute name="attrs"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="name" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="key"/></rng:optional>
|
||||
<rng:optional><rng:attribute name="goto" /></rng:optional>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:start>
|
||||
<rng:choice>
|
||||
<rng:ref name="diagram" />
|
||||
|
||||
+163
-154
@@ -1313,29 +1313,25 @@ class orm_template(object):
|
||||
}
|
||||
attrs = {'views': views}
|
||||
if node.get('widget') and node.get('widget') == 'selection':
|
||||
if not check_group(node):
|
||||
name = node.get('name')
|
||||
default = self.default_get(cr, user, [name], context=context).get(name)
|
||||
if default:
|
||||
attrs['selection'] = relation.name_get(cr, 1, [default], context=context)
|
||||
else:
|
||||
attrs['selection'] = []
|
||||
# We can not use the 'string' domain has it is defined according to the record !
|
||||
else:
|
||||
# If domain and context are strings, we keep them for client-side, otherwise
|
||||
# we evaluate them server-side to consider them when generating the list of
|
||||
# possible values
|
||||
# TODO: find a way to remove this hack, by allow dynamic domains
|
||||
dom = []
|
||||
if column._domain and not isinstance(column._domain, basestring):
|
||||
dom = column._domain
|
||||
dom += eval(node.get('domain','[]'), {'uid':user, 'time':time})
|
||||
search_context = dict(context)
|
||||
if column._context and not isinstance(column._context, basestring):
|
||||
search_context.update(column._context)
|
||||
attrs['selection'] = relation._name_search(cr, 1, '', dom, context=search_context, limit=None, name_get_uid=1)
|
||||
if (node.get('required') and not int(node.get('required'))) or not column.required:
|
||||
attrs['selection'].append((False,''))
|
||||
# Prepare the cached selection list for the client. This needs to be
|
||||
# done even when the field is invisible to the current user, because
|
||||
# other events could need to change its value to any of the selectable ones
|
||||
# (such as on_change events, refreshes, etc.)
|
||||
|
||||
# If domain and context are strings, we keep them for client-side, otherwise
|
||||
# we evaluate them server-side to consider them when generating the list of
|
||||
# possible values
|
||||
# TODO: find a way to remove this hack, by allow dynamic domains
|
||||
dom = []
|
||||
if column._domain and not isinstance(column._domain, basestring):
|
||||
dom = column._domain
|
||||
dom += eval(node.get('domain','[]'), {'uid':user, 'time':time})
|
||||
search_context = dict(context)
|
||||
if column._context and not isinstance(column._context, basestring):
|
||||
search_context.update(column._context)
|
||||
attrs['selection'] = relation._name_search(cr, user, '', dom, context=search_context, limit=None, name_get_uid=1)
|
||||
if (node.get('required') and not int(node.get('required'))) or not column.required:
|
||||
attrs['selection'].append((False,''))
|
||||
fields[node.get('name')] = attrs
|
||||
|
||||
elif node.tag in ('form', 'tree'):
|
||||
@@ -1496,7 +1492,7 @@ class orm_template(object):
|
||||
view = self.fields_view_get(cr, uid, False, 'form', context)
|
||||
|
||||
root = etree.fromstring(encode(view['arch']))
|
||||
res = etree.XML("<search string='%s'></search>" % root.get("string", ""))
|
||||
res = etree.XML("""<search string="%s"></search>""" % root.get("string", ""))
|
||||
node = etree.Element("group")
|
||||
res.append(node)
|
||||
|
||||
@@ -1771,15 +1767,116 @@ class orm_template(object):
|
||||
return len(res)
|
||||
return res
|
||||
|
||||
def search(self, cr, user, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
|
||||
"""
|
||||
Search for records based on a search domain.
|
||||
|
||||
:param cr: database cursor
|
||||
:param user: current user id
|
||||
:param args: list of tuples specifying the search domain [('field_name', 'operator', value), ...]. Pass an empty list to match all records.
|
||||
:param offset: optional number of results to skip in the returned values (default: 0)
|
||||
:param limit: optional max number of records to return (default: **None**)
|
||||
:param order: optional columns to sort by (default: self._order=id )
|
||||
:param context: optional context arguments, like lang, time zone
|
||||
:type context: dictionary
|
||||
:param count: optional (default: **False**), if **True**, returns only the number of records matching the criteria, not their ids
|
||||
:return: id or list of ids of records matching the criteria
|
||||
:rtype: integer or list of integers
|
||||
:raise AccessError: * if user tries to bypass access rules for read on the requested object.
|
||||
|
||||
**Expressing a search domain (args)**
|
||||
|
||||
Each tuple in the search domain needs to have 3 elements, in the form: **('field_name', 'operator', value)**, where:
|
||||
|
||||
* **field_name** must be a valid name of field of the object model, possibly following many-to-one relationships using dot-notation, e.g 'street' or 'partner_id.country' are valid values.
|
||||
* **operator** must be a string with a valid comparison operator from this list: ``=, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right``
|
||||
The semantics of most of these operators are obvious.
|
||||
The ``child_of`` operator will look for records who are children or grand-children of a given record,
|
||||
according to the semantics of this model (i.e following the relationship field named by
|
||||
``self._parent_name``, by default ``parent_id``.
|
||||
* **value** must be a valid value to compare with the values of **field_name**, depending on its type.
|
||||
|
||||
Domain criteria can be combined using 3 logical operators than can be added between tuples: '**&**' (logical AND, default), '**|**' (logical OR), '**!**' (logical NOT).
|
||||
These are **prefix** operators and the arity of the '**&**' and '**|**' operator is 2, while the arity of the '**!**' is just 1.
|
||||
Be very careful about this when you combine them the first time.
|
||||
|
||||
Here is an example of searching for Partners named *ABC* from Belgium and Germany whose language is not english ::
|
||||
|
||||
[('name','=','ABC'),'!',('language.code','=','en_US'),'|',('country_id.code','=','be'),('country_id.code','=','de'))
|
||||
|
||||
The '&' is omitted as it is the default, and of course we could have used '!=' for the language, but what this domain really represents is::
|
||||
|
||||
(name is 'ABC' AND (language is NOT english) AND (country is Belgium OR Germany))
|
||||
|
||||
"""
|
||||
return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
|
||||
|
||||
def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
|
||||
"""
|
||||
Private implementation of search() method, allowing specifying the uid to use for the access right check.
|
||||
This is useful for example when filling in the selection list for a drop-down and avoiding access rights errors,
|
||||
by specifying ``access_rights_uid=1`` to bypass access rights check, but not ir.rules!
|
||||
|
||||
:param access_rights_uid: optional user ID to use when checking access rights
|
||||
(not for ir.rules, this is only for ir.model.access)
|
||||
"""
|
||||
raise NotImplementedError(_('The search method is not implemented on this object !'))
|
||||
|
||||
def name_get(self, cr, user, ids, context=None):
|
||||
raise NotImplementedError(_('The name_get method is not implemented on this object !'))
|
||||
"""
|
||||
|
||||
:param cr: database cursor
|
||||
:param user: current user id
|
||||
:type user: integer
|
||||
:param ids: list of ids
|
||||
:param context: context arguments, like lang, time zone
|
||||
:type context: dictionary
|
||||
:return: tuples with the text representation of requested objects for to-many relationships
|
||||
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
if not ids:
|
||||
return []
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
return [(r['id'], tools.ustr(r[self._rec_name])) for r in self.read(cr, user, ids,
|
||||
[self._rec_name], context, load='_classic_write')]
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):
|
||||
raise NotImplementedError(_('The name_search method is not implemented on this object !'))
|
||||
"""
|
||||
Search for records and their display names according to a search domain.
|
||||
|
||||
:param cr: database cursor
|
||||
:param user: current user id
|
||||
:param name: object name to search
|
||||
:param args: list of tuples specifying search criteria [('field_name', 'operator', 'value'), ...]
|
||||
:param operator: operator for search criterion
|
||||
:param context: context arguments, like lang, time zone
|
||||
:type context: dictionary
|
||||
:param limit: optional max number of records to return
|
||||
:return: list of object names matching the search criteria, used to provide completion for to-many relationships
|
||||
|
||||
This method is equivalent of :py:meth:`~osv.osv.osv.search` on **name** + :py:meth:`~osv.osv.osv.name_get` on the result.
|
||||
See :py:meth:`~osv.osv.osv.search` for an explanation of the possible values for the search domain specified in **args**.
|
||||
|
||||
"""
|
||||
return self._name_search(cr, user, name, args, operator, context, limit)
|
||||
|
||||
# private implementation of name_search, allows passing a dedicated user for the name_get part to
|
||||
# solve some access rights issues
|
||||
def _name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100, name_get_uid=None):
|
||||
if args is None:
|
||||
args = []
|
||||
if context is None:
|
||||
context = {}
|
||||
args = args[:]
|
||||
if name:
|
||||
args += [(self._rec_name, operator, name)]
|
||||
access_rights_uid = name_get_uid or user
|
||||
ids = self._search(cr, user, args, limit=limit, context=context, access_rights_uid=access_rights_uid)
|
||||
res = self.name_get(cr, access_rights_uid, ids, context)
|
||||
return res
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
raise NotImplementedError(_('The copy method is not implemented on this object !'))
|
||||
@@ -1830,7 +1927,33 @@ class orm_template(object):
|
||||
def _check_removed_columns(self, cr, log=False):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _add_missing_default_values(self, cr, uid, values, context=None):
|
||||
missing_defaults = []
|
||||
avoid_tables = [] # avoid overriding inherited values when parent is set
|
||||
for tables, parent_field in self._inherits.items():
|
||||
if parent_field in values:
|
||||
avoid_tables.append(tables)
|
||||
for field in self._columns.keys():
|
||||
if not field in values:
|
||||
missing_defaults.append(field)
|
||||
for field in self._inherit_fields.keys():
|
||||
if (field not in values) and (self._inherit_fields[field][0] not in avoid_tables):
|
||||
missing_defaults.append(field)
|
||||
|
||||
if len(missing_defaults):
|
||||
# override defaults with the provided values, never allow the other way around
|
||||
defaults = self.default_get(cr, uid, missing_defaults, context)
|
||||
for dv in defaults:
|
||||
# FIXME: also handle inherited m2m
|
||||
if dv in self._columns and self._columns[dv]._type == 'many2many' \
|
||||
and defaults[dv] and isinstance(defaults[dv][0], (int, long)):
|
||||
defaults[dv] = [(6, 0, defaults[dv])]
|
||||
defaults.update(values)
|
||||
values = defaults
|
||||
return values
|
||||
|
||||
class orm_memory(orm_template):
|
||||
|
||||
_protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count', 'exists']
|
||||
_inherit_fields = {}
|
||||
_max_count = 200
|
||||
@@ -1922,10 +2045,7 @@ class orm_memory(orm_template):
|
||||
self.next_id += 1
|
||||
id_new = self.next_id
|
||||
|
||||
# override defaults with the provided values, never allow the other way around
|
||||
defaults = self.default_get(cr, user, [], context)
|
||||
defaults.update(vals)
|
||||
vals = defaults
|
||||
vals = self._add_missing_default_values(cr, user, vals, context)
|
||||
|
||||
vals2 = {}
|
||||
upd_todo = []
|
||||
@@ -1975,8 +2095,7 @@ class orm_memory(orm_template):
|
||||
res = e.exp
|
||||
return res or []
|
||||
|
||||
def search(self, cr, user, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
@@ -3385,30 +3504,7 @@ class orm(orm_template):
|
||||
context = {}
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'create', context=context)
|
||||
|
||||
default = []
|
||||
|
||||
avoid_table = []
|
||||
for (t, c) in self._inherits.items():
|
||||
if c in vals:
|
||||
avoid_table.append(t)
|
||||
for f in self._columns.keys(): # + self._inherit_fields.keys():
|
||||
if not f in vals:
|
||||
default.append(f)
|
||||
|
||||
for f in self._inherit_fields.keys():
|
||||
if (not f in vals) and (self._inherit_fields[f][0] not in avoid_table):
|
||||
default.append(f)
|
||||
|
||||
if len(default):
|
||||
default_values = self.default_get(cr, user, default, context)
|
||||
for dv in default_values:
|
||||
if dv in self._columns and self._columns[dv]._type == 'many2many':
|
||||
if default_values[dv] and isinstance(default_values[dv][0], (int, long)):
|
||||
default_values[dv] = [(6, 0, default_values[dv])]
|
||||
|
||||
# override defaults with the provided values, never allow the other way around
|
||||
default_values.update(vals)
|
||||
vals = default_values
|
||||
vals = self._add_missing_default_values(cr, user, vals, context)
|
||||
|
||||
tocreate = {}
|
||||
for v in self._inherits:
|
||||
@@ -3761,52 +3857,19 @@ class orm(orm_template):
|
||||
return True
|
||||
return False
|
||||
|
||||
def search(self, cr, user, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None):
|
||||
"""
|
||||
Search for record/s based on a search domain.
|
||||
|
||||
:param cr: database cursor
|
||||
:param user: current user id
|
||||
:param args: list of tuples specifying the search domain [('field_name', 'operator', value), ...]. Pass an empty list to match all records.
|
||||
:param offset: optional number of results to skip in the returned values (default: 0)
|
||||
:param limit: optional max number of records to return (default: **None**)
|
||||
:param order: optional columns to sort by (default: self._order=id )
|
||||
:param context: optional context arguments, like lang, time zone
|
||||
:type context: dictionary
|
||||
:param count: optional (default: **False**), if **True**, returns only the number of records matching the criteria, not their ids
|
||||
:return: id or list of ids of records matching the criteria
|
||||
:rtype: integer or list of integers
|
||||
:raise AccessError: * if user tries to bypass access rules for read on the requested object.
|
||||
|
||||
**Expressing a search domain (args)**
|
||||
|
||||
Each tuple in the search domain needs to have 3 elements, in the form: **('field_name', 'operator', value)**, where:
|
||||
|
||||
* **field_name** must be a valid name of field of the object model, possibly following many-to-one relationships using dot-notation, e.g 'street' or 'partner_id.country' are valid values.
|
||||
* **operator** must be a string with a valid comparison operator from this list: ``=, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right``
|
||||
The semantics of most of these operators are obvious.
|
||||
The ``child_of`` operator will look for records who are children or grand-children of a given record,
|
||||
according to the semantics of this model (i.e following the relationship field named by
|
||||
``self._parent_name``, by default ``parent_id``.
|
||||
* **value** must be a valid value to compare with the values of **field_name**, depending on its type.
|
||||
|
||||
Domain criteria can be combined using 3 logical operators than can be added between tuples: '**&**' (logical AND, default), '**|**' (logical OR), '**!**' (logical NOT).
|
||||
These are **prefix** operators and the arity of the '**&**' and '**|**' operator is 2, while the arity of the '**!**' is just 1.
|
||||
Be very careful about this when you combine them the first time.
|
||||
|
||||
Here is an example of searching for Partners named *ABC* from Belgium and Germany whose language is not english ::
|
||||
|
||||
[('name','=','ABC'),'!',('language.code','=','en_US'),'|',('country_id.code','=','be'),('country_id.code','=','de'))
|
||||
|
||||
The '&' is omitted as it is the default, and of course we could have used '!=' for the language, but what this domain really represents is::
|
||||
|
||||
(name is 'ABC' AND (language is NOT english) AND (country is Belgium OR Germany))
|
||||
|
||||
Private implementation of search() method, allowing specifying the uid to use for the access right check.
|
||||
This is useful for example when filling in the selection list for a drop-down and avoiding access rights errors,
|
||||
by specifying ``access_rights_uid=1`` to bypass access rights check, but not ir.rules!
|
||||
This is ok at the security level because this method is private and not callable through XML-RPC.
|
||||
|
||||
:param access_rights_uid: optional user ID to use when checking access rights
|
||||
(not for ir.rules, this is only for ir.model.access)
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'read', context=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)
|
||||
|
||||
@@ -3867,60 +3930,6 @@ class orm(orm_template):
|
||||
else:
|
||||
return self._columns[field].search(cr, self, args, field, value, offset, limit, uid)
|
||||
|
||||
def name_get(self, cr, user, ids, context=None):
|
||||
"""
|
||||
|
||||
:param cr: database cursor
|
||||
:param user: current user id
|
||||
:type user: integer
|
||||
:param ids: list of ids
|
||||
:param context: context arguments, like lang, time zone
|
||||
:type context: dictionary
|
||||
:return: tuples with the text representation of requested objects for to-many relationships
|
||||
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
if not ids:
|
||||
return []
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
return [(r['id'], tools.ustr(r[self._rec_name])) for r in self.read(cr, user, ids,
|
||||
[self._rec_name], context, load='_classic_write')]
|
||||
|
||||
# private implementation of name_search, allows passing a dedicated user for the name_get part to
|
||||
# solve some access rights issues
|
||||
def _name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100, name_get_uid=None):
|
||||
if args is None:
|
||||
args = []
|
||||
if context is None:
|
||||
context = {}
|
||||
args = args[:]
|
||||
if name:
|
||||
args += [(self._rec_name, operator, name)]
|
||||
ids = self.search(cr, user, args, limit=limit, context=context)
|
||||
res = self.name_get(cr, name_get_uid or user, ids, context)
|
||||
return res
|
||||
|
||||
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100):
|
||||
"""
|
||||
|
||||
:param cr: database cursor
|
||||
:param user: current user id
|
||||
:param name: object name to search
|
||||
:param args: list of tuples specifying search criteria [('field_name', 'operator', 'value'), ...]
|
||||
:param operator: operator for search criterion
|
||||
:param context: context arguments, like lang, time zone
|
||||
:type context: dictionary
|
||||
:param limit: optional max number of records to return
|
||||
:return: list of object names matching the search criteria, used to provide completion for to-many relationships
|
||||
|
||||
This method is equivalent of :py:meth:`~osv.osv.osv.search` on **name** + :py:meth:`~osv.osv.osv.name_get` on the result.
|
||||
See :py:meth:`~osv.osv.osv.search` for an explanation of the possible values for the search domain specified in **args**.
|
||||
|
||||
"""
|
||||
return self._name_search(cr, user, name, args, operator, context, limit)
|
||||
|
||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||
"""
|
||||
Copy given record's data with all its fields values
|
||||
|
||||
@@ -83,20 +83,21 @@ class report_printscreen_list(report_int):
|
||||
for rec in records:
|
||||
rec['__group'] = True
|
||||
rec['__no_leaf'] = self.groupby_no_leaf
|
||||
rec['__grouped_by'] = groupby[0] if (isinstance(groupby, list) and groupby) else groupby
|
||||
for f in fields_order:
|
||||
if f not in rec:
|
||||
rec.update({f:False})
|
||||
elif isinstance(rec[f], tuple):
|
||||
rec[f] = rec[f][1]
|
||||
rows.append(rec)
|
||||
groupby = (rec.get('__context', {})).get('group_by',[])
|
||||
domain = rec.get('__domain', [])
|
||||
if groupby:
|
||||
get_groupby_data(groupby, domain)
|
||||
inner_groupby = (rec.get('__context', {})).get('group_by',[])
|
||||
inner_domain = rec.get('__domain', [])
|
||||
if inner_groupby:
|
||||
get_groupby_data(inner_groupby, inner_domain)
|
||||
else:
|
||||
if self.groupby_no_leaf:
|
||||
continue
|
||||
child_ids = model.search(cr, uid, domain)
|
||||
child_ids = model.search(cr, uid, inner_domain)
|
||||
res = model.read(cr, uid, child_ids, result['fields'].keys(), context)
|
||||
rows.extend(res)
|
||||
dom = [('id','in',ids)]
|
||||
@@ -175,7 +176,7 @@ class report_printscreen_list(report_int):
|
||||
count += 1
|
||||
if fields[f]['type']=='many2one' and line[f]:
|
||||
if not line.get('__group'):
|
||||
line[f]= line[f][1]
|
||||
line[f] = line[f][1]
|
||||
if fields[f]['type']=='selection' and line[f]:
|
||||
for key, value in fields[f]['selection']:
|
||||
if key == line[f]:
|
||||
@@ -212,10 +213,18 @@ class report_printscreen_list(report_int):
|
||||
d1 = datetime.strptime(line[f], '%Y-%m-%d %H:%M:%S')
|
||||
new_d1 = d1.strftime(format)
|
||||
line[f] = new_d1
|
||||
|
||||
|
||||
if line.get('__group'):
|
||||
col = etree.SubElement(node_line, 'col', para='group', tree='no')
|
||||
else:
|
||||
col = etree.SubElement(node_line, 'col', para='yes', tree='no')
|
||||
|
||||
# Prevent empty labels in groups
|
||||
if f == line.get('__grouped_by') and line.get('__group') and not line[f] and not float_flag and not temp[count]:
|
||||
col.text = line[f] = 'Undefined'
|
||||
col.set('tree', 'undefined')
|
||||
|
||||
if line[f] != None:
|
||||
col.text = tools.ustr(line[f] or '')
|
||||
if float_flag:
|
||||
@@ -225,7 +234,10 @@ class report_printscreen_list(report_int):
|
||||
if not line.get('__group') and f != 'id' and temp[count] == 1:
|
||||
tsum[count] = float(tsum[count]) + float(line[f]);
|
||||
else:
|
||||
col.text = '/'
|
||||
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')
|
||||
|
||||
@@ -364,15 +364,18 @@ class _rml_canvas(object):
|
||||
image_data = self.images[node.get('name')]
|
||||
s = cStringIO.StringIO(image_data)
|
||||
else:
|
||||
import base64
|
||||
if self.localcontext:
|
||||
res = utils._regex.findall(node.text)
|
||||
for key in res:
|
||||
newtext = eval(key, {}, self.localcontext)
|
||||
node.text = newtext
|
||||
image_data = base64.decodestring(node.text)
|
||||
if not image_data: return False
|
||||
s = cStringIO.StringIO(image_data)
|
||||
res = utils._regex.findall(node.text)
|
||||
for key in res:
|
||||
newtext = eval(key, {}, self.localcontext)
|
||||
node.text = newtext
|
||||
image_data = None
|
||||
if node.text:
|
||||
image_data = base64.decodestring(node.text)
|
||||
if image_data:
|
||||
s = cStringIO.StringIO(image_data)
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if node.get('file') in self.images:
|
||||
s = cStringIO.StringIO(self.images[node.get('file')])
|
||||
|
||||
+19
-11
@@ -523,29 +523,35 @@ form: module.record_id""" % (xml_id,)
|
||||
m_l = map(escape, escape_re.split(rec.get("name",'').encode('utf8')))
|
||||
|
||||
values = {'parent_id': False}
|
||||
if not rec.get('parent'):
|
||||
if rec.get('parent', False) is False and len(m_l) > 1:
|
||||
# No parent attribute specified and the menu name has several menu components,
|
||||
# try to determine the ID of the parent according to menu path
|
||||
pid = False
|
||||
res = None
|
||||
values['name'] = m_l[-1]
|
||||
m_l = m_l[:-1] # last part is our name, not a parent
|
||||
for idx, menu_elem in enumerate(m_l):
|
||||
if pid:
|
||||
cr.execute('select id from ir_ui_menu where parent_id=%s and name=%s', (pid, menu_elem))
|
||||
else:
|
||||
cr.execute('select id from ir_ui_menu where parent_id is null and name=%s', (menu_elem,))
|
||||
res = cr.fetchone()
|
||||
if idx==len(m_l)-1:
|
||||
values = {'parent_id': pid,'name':menu_elem}
|
||||
elif res:
|
||||
if res:
|
||||
pid = res[0]
|
||||
xml_id = idx==len(m_l)-1 and rec.get('id','').encode('utf8')
|
||||
try:
|
||||
self.pool.get('ir.model.data')._update_dummy(cr, self.uid, 'ir.ui.menu', self.module, xml_id, idx==len(m_l)-1)
|
||||
except:
|
||||
self.logger.notifyChannel('init', netsvc.LOG_ERROR, "module: %s xml_id: %s" % (self.module, xml_id))
|
||||
else:
|
||||
# the menuitem does't exist but we are in branch (not a leaf)
|
||||
self.logger.notifyChannel("init", netsvc.LOG_WARNING, 'Warning no ID for submenu %s of menu %s !' % (menu_elem, str(m_l)))
|
||||
pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
|
||||
values['parent_id'] = pid
|
||||
else:
|
||||
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.get('parent',''))
|
||||
# The parent attribute was specified, if non-empty determine its ID, otherwise
|
||||
# explicitly make a top-level menu
|
||||
if rec.get('parent'):
|
||||
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.get('parent',''))
|
||||
else:
|
||||
# we get here with <menuitem parent="">, explicit clear of parent, or
|
||||
# if no parent attribute at all but menu name is not a menu path
|
||||
menu_parent_id = False
|
||||
values = {'parent_id': menu_parent_id}
|
||||
if rec.get('name'):
|
||||
values['name'] = rec.get('name')
|
||||
@@ -793,7 +799,9 @@ form: module.record_id""" % (xml_id,)
|
||||
def id_get(self, cr, model, id_str):
|
||||
if id_str in self.idref:
|
||||
return self.idref[id_str]
|
||||
return self.model_id_get(cr, model, id_str)[1]
|
||||
res = self.model_id_get(cr, model, id_str)
|
||||
if res and len(res)>1: res = res[1]
|
||||
return res
|
||||
|
||||
def model_id_get(self, cr, model, id_str):
|
||||
model_data_obj = self.pool.get('ir.model.data')
|
||||
|
||||
@@ -375,6 +375,9 @@ def trans_export(lang, modules, buffer, format, dbname=None):
|
||||
if newlang:
|
||||
lang = 'en_US'
|
||||
trans = trans_generate(lang, modules, dbname)
|
||||
if newlang and format!='csv':
|
||||
for trx in trans:
|
||||
trx[-1] = ''
|
||||
modules = set([t[0] for t in trans[1:]])
|
||||
_process(format, modules, trans, buffer, lang, newlang)
|
||||
del trans
|
||||
|
||||
@@ -250,6 +250,25 @@ class YamlInterpreter(object):
|
||||
if not success:
|
||||
msg = 'Assertion "%s" FAILED\ntest: %s\n'
|
||||
args = (assertion.string, test)
|
||||
for aop in ('==', '!=', '<>', 'in', 'not in', '>=', '<=', '>', '<'):
|
||||
if aop in test:
|
||||
left, right = test.split(aop,1)
|
||||
lmsg = ''
|
||||
rmsg = ''
|
||||
try:
|
||||
lmsg = unsafe_eval(left, self.eval_context, RecordDictWrapper(record))
|
||||
except Exception, e:
|
||||
lmsg = '<exc>'
|
||||
|
||||
try:
|
||||
rmsg = unsafe_eval(right, self.eval_context, RecordDictWrapper(record))
|
||||
except Exception, e:
|
||||
rmsg = '<exc>'
|
||||
|
||||
msg += 'values: ! %s %s %s'
|
||||
args += ( lmsg, aop, rmsg )
|
||||
break
|
||||
|
||||
self._log_assert_failure(assertion.severity, msg, *args)
|
||||
return
|
||||
else: # all tests were successful for this assertion tag (no break)
|
||||
@@ -293,8 +312,10 @@ class YamlInterpreter(object):
|
||||
|
||||
record_dict = self._create_record(model, fields)
|
||||
self.logger.debug("RECORD_DICT %s" % record_dict)
|
||||
#context = self.get_context(record, self.eval_context)
|
||||
context = record.context #TOFIX: record.context like {'withoutemployee':True} should pass from self.eval_context. example: test_project.yml in project module
|
||||
id = self.pool.get('ir.model.data')._update(self.cr, self.uid, record.model, \
|
||||
self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode)
|
||||
self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context)
|
||||
self.id_map[record.id] = int(id)
|
||||
if config.get('import_partial'):
|
||||
self.cr.commit()
|
||||
@@ -360,14 +381,14 @@ class YamlInterpreter(object):
|
||||
value = expression
|
||||
# raise YamlImportException('Unsupported column "%s" or value %s:%s' % (field_name, type(expression), expression))
|
||||
return value
|
||||
|
||||
|
||||
def process_context(self, node):
|
||||
self.context = node.__dict__
|
||||
if node.uid:
|
||||
self.uid = self.get_id(node.uid)
|
||||
if node.noupdate:
|
||||
self.noupdate = node.noupdate
|
||||
|
||||
|
||||
def process_python(self, node):
|
||||
def log(msg, *args):
|
||||
self.logger.log(logging.TEST, msg, *args)
|
||||
@@ -384,7 +405,7 @@ class YamlInterpreter(object):
|
||||
return
|
||||
except Exception, e:
|
||||
self.logger.debug('Exception during evaluation of !python block in yaml_file %s.', self.filename, exc_info=True)
|
||||
raise YamlImportAbortion(e)
|
||||
raise
|
||||
else:
|
||||
self.assert_report.record(True, python.severity)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user