[MERGE] merged trunk.

bzr revid: vmt@openerp.com-20110928130246-stflg3oza3nqq05i
This commit is contained in:
Vo Minh Thu 2011-09-28 15:02:46 +02:00
commit b4661b5b09
17 changed files with 9925 additions and 941 deletions

View File

@ -22,6 +22,8 @@
""" OpenERP core library.
"""
# The hard-coded super-user id (a.k.a. administrator, or root user).
SUPERUSER_ID = 1
import addons
import conf

View File

@ -1002,7 +1002,7 @@
</record>
<record id="main_partner" model="res.partner">
<field name="name">OpenERP S.A.</field>
<field name="name">Company Name</field>
<!-- Address and Company ID will be set later -->
<field name="address" eval="[]"/>
<field name="company_id" eval="None"/>
@ -1010,13 +1010,13 @@
</record>
<record id="main_address" model="res.partner.address">
<field name="partner_id" ref="main_partner"/>
<field name="name">Fabien Pinckaers</field>
<field name="street">Chaussee de Namur 40</field>
<field name="zip">1367</field>
<field name="city">Gerompont</field>
<field name="phone">(+32).81.81.37.00</field>
<field name="name">Company contact name</field>
<field name="street">Company street, number</field>
<field name="zip">Company zip</field>
<field name="city">Company city</field>
<field name="phone">+1-212-555-12345</field>
<field name="type">default</field>
<field model="res.country" name="country_id" ref="be"/>
<field model="res.country" name="country_id" ref="us"/>
<!-- Company ID will be set later -->
<field name="company_id" eval="None"/>
</record>
@ -1038,19 +1038,14 @@
<!-- Basic Company -->
<record id="main_company" model="res.company">
<field name="name">OpenERP S.A.</field>
<field name="name">Company Name</field>
<field name="partner_id" ref="main_partner"/>
<field name="rml_header1">Free Business Solutions</field>
<field name="rml_footer1">Web: http://www.openerp.com - Tel: (+32).81.81.37.00 - Bank: CPH 126-2013269-07</field>
<field name="rml_footer2">IBAN: BE74 1262 0132 6907 - SWIFT: CPHBBE75 - VAT: BE0477.472.701</field>
<field name="rml_header1">Company business slogan</field>
<field name="rml_footer1">Web: www.companyname.com - Tel: +1-212-555-12345</field>
<field name="rml_footer2">IBAN: XX12 3456 7890 1234 5678 - SWIFT: SWIFTCODE - VAT: Company vat number</field>
<field name="currency_id" ref="base.EUR"/>
</record>
<assert id="main_company" model="res.company">
<test expr="currency_id.name == 'eur'.upper()"/>
<test expr="name">OpenERP S.A.</test>
</assert>
<record model="res.users" id="base.user_root">
<field name="signature">Administrator</field>
<field name="company_id" ref="main_company"/>

File diff suppressed because it is too large Load Diff

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
"PO-Revision-Date: 2011-01-28 02:14+0000\n"
"PO-Revision-Date: 2011-09-27 16:28+0000\n"
"Last-Translator: Walter Cheuk <wwycheuk@gmail.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: 2011-09-01 04:45+0000\n"
"X-Generator: Launchpad (build 13827)\n"
"X-Launchpad-Export-Date: 2011-09-28 05:19+0000\n"
"X-Generator: Launchpad (build 14049)\n"
#. module: base
#: view:ir.filters:0
@ -46,7 +46,7 @@ msgstr "日期時間"
msgid ""
"The second argument of the many2many field %s must be a SQL table !You used "
"%s, which is not a valid SQL table name."
msgstr "many2many 欄位 %s 之第二個引數須為 SQL 表格!您用了並非有效 SQL 表格名稱之 %s。"
msgstr "「多對多(many2many)」欄位 %s 之第二個引數須為 SQL 表格!您用了並非有效 SQL 表格名稱之 %s。"
#. module: base
#: view:ir.values:0
@ -103,7 +103,7 @@ msgstr "工作流程作用於"
#. module: base
#: field:ir.actions.act_window,display_menu_tip:0
msgid "Display Menu Tips"
msgstr "顯示選提示"
msgstr "顯示選提示"
#. module: base
#: view:ir.module.module:0
@ -129,7 +129,7 @@ msgstr ""
#. module: base
#: field:res.partner,ref:0
msgid "Reference"
msgstr "參"
msgstr "參"
#. module: base
#: field:ir.actions.act_window,target:0
@ -154,7 +154,7 @@ msgstr ""
#: code:addons/osv.py:133
#, python-format
msgid "Constraint Error"
msgstr ""
msgstr "約束錯誤"
#. module: base
#: model:ir.model,name:base.model_ir_ui_view_custom
@ -171,12 +171,12 @@ msgstr "史瓦濟蘭"
#: code:addons/orm.py:3653
#, python-format
msgid "created."
msgstr ""
msgstr "已建立。"
#. module: base
#: model:res.partner.category,name:base.res_partner_category_woodsuppliers0
msgid "Wood Suppliers"
msgstr ""
msgstr "木材供應商"
#. module: base
#: code:addons/base/module/module.py:303
@ -224,7 +224,7 @@ msgstr "新"
#. module: base
#: field:ir.actions.report.xml,multi:0
msgid "On multiple doc."
msgstr "作用於多重檔案。"
msgstr "作用於多重文件。"
#. module: base
#: field:ir.module.category,module_nr:0
@ -252,12 +252,12 @@ msgstr "聯絡人名稱"
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 "將此檔案儲存為%s檔案後可以特定軟體或文字編輯程式修改。檔案編碼為 UTF-8。"
msgstr "將此檔案存為 %s 檔案,並以特定軟體或文字編輯程式修改。檔案編碼為 UTF-8。"
#. module: base
#: sql_constraint:res.lang:0
msgid "The name of the language must be unique !"
msgstr ""
msgstr "語言名稱須與其他不同 !"
#. module: base
#: selection:res.request,state:0
@ -329,7 +329,7 @@ msgstr "欄位名稱"
#: wizard_view:server.action.create,init:0
#: wizard_field:server.action.create,init,type:0
msgid "Select Action Type"
msgstr "選動作類型"
msgstr "選動作類型"
#. module: base
#: model:res.country,name:base.tv
@ -422,7 +422,7 @@ msgstr "哥倫比亞"
#. module: base
#: view:ir.module.module:0
msgid "Schedule Upgrade"
msgstr "排升級"
msgstr "排升級"
#. module: base
#: code:addons/orm.py:838
@ -436,7 +436,7 @@ msgid ""
"The ISO country code in two chars.\n"
"You can use this field for quick search."
msgstr ""
"ISO 國家代碼使用兩個字。\n"
"ISO 國家代碼使用兩個字。\n"
"您可以使用該欄位來快速搜索。"
#. module: base
@ -447,7 +447,7 @@ msgstr "帛琉"
#. module: base
#: view:res.partner:0
msgid "Sales & Purchases"
msgstr "銷售&採購"
msgstr "銷售 及 購貨"
#. module: base
#: view:ir.translation:0
@ -481,7 +481,7 @@ msgstr "自訂欄位名稱開頭必須是 'x_' !"
#. module: base
#: help:ir.actions.server,action_id:0
msgid "Select the Action Window, Report, Wizard to be executed."
msgstr "選擇要執行的動作視窗、報表或精靈。"
msgstr "選取要執行之動作視窗、報表或精靈。"
#. module: base
#: view:res.config.users:0
@ -502,7 +502,7 @@ msgstr "模型說明"
#: help:ir.actions.act_window,src_model:0
msgid ""
"Optional model name of the objects on which this action should be visible"
msgstr ""
msgstr "要可見動作的物件之模型名稱(可有可無)"
#. module: base
#: field:workflow.transition,trigger_expr_id:0
@ -548,7 +548,7 @@ msgstr "是否檢查 Ean "
#. module: base
#: field:ir.values,key2:0
msgid "Event Type"
msgstr "事件類型"
msgstr "活動類型"
#. module: base
#: view:base.language.export:0
@ -684,7 +684,7 @@ msgstr "西班牙文 (UY) / Español (UY)"
#: field:res.partner,mobile:0
#: field:res.partner.address,mobile:0
msgid "Mobile"
msgstr "手"
msgstr "手提電話"
#. module: base
#: model:res.country,name:base.om
@ -741,7 +741,7 @@ msgstr "印度"
#: model:ir.actions.act_window,name:base.res_request_link-act
#: model:ir.ui.menu,name:base.menu_res_request_link_act
msgid "Request Reference Types"
msgstr "請求參類型"
msgstr "請求參類型"
#. module: base
#: view:ir.values:0
@ -812,7 +812,7 @@ msgstr "人力資源儀錶板"
#: code:addons/base/res/res_user.py:507
#, python-format
msgid "Setting empty passwords is not allowed for security reasons!"
msgstr "因安理由密碼不能留空!"
msgstr "因安理由密碼不能留空!"
#. module: base
#: selection:ir.actions.server,state:0
@ -882,7 +882,7 @@ msgstr "刪除存取"
#. module: base
#: model:res.country,name:base.ne
msgid "Niger"
msgstr "尼日"
msgstr "尼日"
#. module: base
#: selection:base.language.install,lang:0
@ -998,7 +998,7 @@ msgstr "儀錶板"
#. module: base
#: model:ir.ui.menu,name:base.menu_purchase_root
msgid "Purchases"
msgstr "購"
msgstr "購"
#. module: base
#: model:res.country,name:base.md
@ -1120,7 +1120,7 @@ msgstr "報表"
msgid ""
"If set to true, the action will not be displayed on the right toolbar of a "
"form view."
msgstr "如設為,該動作不會顯示於表單檢視右側工具欄。"
msgstr "如設為,該動作不會顯示於表單檢視右側工具欄。"
#. module: base
#: field:workflow,on_create:0
@ -1239,7 +1239,7 @@ msgstr "馬爾地夫"
#. module: base
#: help:ir.values,res_id:0
msgid "Keep 0 if the action must appear on all resources."
msgstr "如該動作要顯示於所有資源的話請保持為「0」。"
msgstr "如該動作要顯示於所有資源的話請保持為「0」。"
#. module: base
#: model:ir.model,name:base.model_ir_rule
@ -1325,7 +1325,7 @@ msgstr "優先次序"
#. module: base
#: field:workflow.transition,act_from:0
msgid "Source Activity"
msgstr "來源活動"
msgstr "來源地動態"
#. module: base
#: view:ir.sequence:0
@ -1368,7 +1368,7 @@ msgstr "完整路徑"
#. module: base
#: view:res.request:0
msgid "References"
msgstr "參"
msgstr "參"
#. module: base
#: view:res.lang:0
@ -1510,7 +1510,7 @@ msgstr ""
#. module: base
#: view:workflow.activity:0
msgid "Workflow Activity"
msgstr "工作流程動"
msgstr "工作流程動"
#. module: base
#: view:ir.rule:0
@ -1694,7 +1694,7 @@ msgstr "原始檢視"
#. module: base
#: view:ir.values:0
msgid "Action To Launch"
msgstr "要啟動之動作"
msgstr "要執行之動作"
#. module: base
#: field:ir.actions.url,target:0
@ -1736,7 +1736,7 @@ msgstr ""
#. module: base
#: help:ir.values,action_id:0
msgid "This field is not used, it only helps you to select the right action."
msgstr "欄位並未使用,只是為了幫您選擇正確動作。"
msgstr "欄位並未使用,只是為了幫您選擇正確動作。"
#. module: base
#: field:ir.actions.server,email:0
@ -1916,7 +1916,7 @@ msgstr "諾福克島"
#. module: base
#: selection:base.language.install,lang:0
msgid "Korean (KR) / 한국어 (KR)"
msgstr "韓文 (KR) / 한국어 (KR)"
msgstr "韓文 (北韓) / 한국어 (KR)"
#. module: base
#: help:ir.model.fields,model:0
@ -1927,7 +1927,7 @@ msgstr ""
#: field:ir.actions.server,action_id:0
#: selection:ir.actions.server,state:0
msgid "Client Action"
msgstr "戶端動作"
msgstr "戶端動作"
#. module: base
#: model:res.country,name:base.bd
@ -2007,7 +2007,7 @@ msgstr "屬性"
#: model:ir.model,name:base.model_res_partner_bank_type
#: view:res.partner.bank.type:0
msgid "Bank Account Type"
msgstr "銀行帳類型"
msgstr "銀行帳類型"
#. module: base
#: field:base.language.export,config_logo:0
@ -2171,7 +2171,7 @@ msgstr "西班牙文 (DO) / Español (DO)"
#. module: base
#: model:ir.model,name:base.model_workflow_activity
msgid "workflow.activity"
msgstr "工作流程.動"
msgstr "工作流程.動"
#. module: base
#: help:ir.ui.view_sc,res_id:0
@ -2239,7 +2239,7 @@ msgstr ""
#. module: base
#: field:ir.default,ref_id:0
msgid "ID Ref."
msgstr "ID參"
msgstr "ID參"
#. module: base
#: model:ir.actions.server,name:base.action_start_configurator
@ -2313,7 +2313,7 @@ msgstr "分格格式"
#. module: base
#: selection:publisher_warranty.contract,state:0
msgid "Unvalidated"
msgstr "未驗"
msgstr "未驗"
#. module: base
#: model:ir.ui.menu,name:base.next_id_9
@ -2336,7 +2336,7 @@ msgstr "馬約特"
#: code:addons/base/ir/ir_actions.py:597
#, python-format
msgid "Please specify an action to launch !"
msgstr "請指定執行動作!"
msgstr "請指定執行動作!"
#. module: base
#: view:res.payterm:0
@ -2368,7 +2368,7 @@ msgstr "請檢查所有行數皆有%d個欄位。"
#: view:ir.cron:0
#: model:ir.ui.menu,name:base.menu_ir_cron_act
msgid "Scheduled Actions"
msgstr "計劃的動作"
msgstr "已安排動作"
#. module: base
#: field:res.partner.address,title:0
@ -2412,7 +2412,7 @@ msgstr "建立選單"
msgid ""
"Value Added Tax number. Check the box if the partner is subjected to the "
"VAT. Used by the VAT legal statement."
msgstr "增值稅編號。如該伙伴適用於增值稅,請選擇。用於增值稅申報。"
msgstr "增值稅編號。如該伙伴需要繳交增值稅,請選擇。用於申報增值稅。"
#. module: base
#: model:ir.model,name:base.model_maintenance_contract
@ -2710,7 +2710,7 @@ msgstr "基礎欄位"
#. module: base
#: view:publisher_warranty.contract:0
msgid "Validate"
msgstr "驗"
msgstr "驗"
#. module: base
#: field:ir.actions.todo,restart:0
@ -2810,7 +2810,7 @@ msgstr ""
#. module: base
#: model:res.partner.category,name:base.res_partner_category_16
msgid "Telecom sector"
msgstr "電範疇"
msgstr "電範疇"
#. module: base
#: field:workflow.transition,trigger_model:0
@ -2820,7 +2820,7 @@ msgstr "觸發器物件"
#. module: base
#: view:res.users:0
msgid "Current Activity"
msgstr "目前活動"
msgstr "當前動態"
#. module: base
#: view:workflow.activity:0
@ -2842,7 +2842,7 @@ msgstr "行銷"
#: view:res.partner.bank:0
#: model:res.partner.bank.type,name:base.bank_normal
msgid "Bank account"
msgstr "銀行帳"
msgstr "銀行帳"
#. module: base
#: selection:base.language.install,lang:0
@ -2857,7 +2857,7 @@ msgstr "序列類型"
#. module: base
#: view:ir.ui.view.custom:0
msgid "Customized Architecture"
msgstr "自訂架構"
msgstr "自訂架構"
#. module: base
#: field:ir.module.module,license:0
@ -2877,7 +2877,7 @@ msgstr "必定"
#. module: base
#: selection:ir.translation,type:0
msgid "SQL Constraint"
msgstr "SQL 限制"
msgstr "SQL 約束"
#. module: base
#: field:ir.actions.server,srcmodel_id:0
@ -3070,7 +3070,7 @@ msgstr "肯亞"
#. module: base
#: view:res.partner.event:0
msgid "Event"
msgstr "事件"
msgstr "活動"
#. module: base
#: model:ir.ui.menu,name:base.menu_custom_reports
@ -3080,7 +3080,7 @@ msgstr "自訂報表"
#. module: base
#: selection:base.language.install,lang:0
msgid "Abkhazian / аҧсуа"
msgstr "阿布哈文 / аҧсуа"
msgstr "阿布哈文 / аҧсуа"
#. module: base
#: view:base.module.configuration:0
@ -3106,7 +3106,7 @@ msgstr "聖馬利諾"
#. module: base
#: model:res.country,name:base.bm
msgid "Bermuda"
msgstr "百慕"
msgstr "百慕"
#. module: base
#: model:res.country,name:base.pe
@ -3180,7 +3180,7 @@ msgstr "完整存取"
#: view:ir.model.fields:0
#: model:ir.ui.menu,name:base.menu_security
msgid "Security"
msgstr "安"
msgstr "安"
#. module: base
#: model:res.widget,title:base.openerp_favorites_twitter_widget
@ -3481,8 +3481,8 @@ msgid ""
"plugin, don't forget to register emails to each contact so that the gateway "
"will automatically attach incoming emails to the right partner."
msgstr ""
"客戶是指您與其做生意者,例如公司或機構。客戶可有多個聯絡人或地址,均屬於其員工。您可用「歷史」分頁追蹤所有有關交易:訂單、電郵、機、退款要求等等。如您用"
"電郵閘道Outlook 或 Thunderbird 外掛程式,別忘了為聯絡人登記電郵,好讓閘道自動為合適伙伴寄送收到之電郵。"
"客戶是指您與其做生意者,例如公司或機構。客戶可有多個聯絡人或地址,均屬於其員工。您可用「歷史」分頁追蹤所有有關交易:訂單、電郵、機、退款要求等等。如您用"
"電郵閘道Outlook 或 Thunderbird 外掛程式,別忘了為聯絡人登記電郵,好讓閘道自動為合適伙伴寄送收到之電郵。"
#. module: base
#: field:ir.actions.report.xml,name:0
@ -3517,7 +3517,7 @@ msgstr "名稱"
msgid ""
"If set to true, the action will not be displayed on the right toolbar of a "
"form view"
msgstr "如設為,該動作不會顯示於表單檢視右側工具欄"
msgstr "如設為,該動作不會顯示於表單檢視右側工具欄"
#. module: base
#: model:res.country,name:base.ms
@ -3543,7 +3543,7 @@ msgstr "應用程式詞彙"
msgid ""
"The user's timezone, used to perform timezone conversions between the server "
"and the client."
msgstr ""
msgstr "用戶之時區,用以為伺服器及用戶端進行時區轉換。"
#. module: base
#: field:ir.module.module,demo:0
@ -3565,7 +3565,7 @@ msgstr "日文 / 日本語"
msgid ""
"Source activity. When this activity is over, the condition is tested to "
"determine if we can start the ACT_TO activity."
msgstr ""
msgstr "來源地動態。當再無動態,會測試條件以決定是否開始 ACT_TO 動態。"
#. module: base
#: model:res.partner.category,name:base.res_partner_category_3
@ -3618,7 +3618,7 @@ msgstr "冷岸及央麥恩群島"
#: model:ir.model,name:base.model_ir_actions_wizard
#: selection:ir.ui.menu,action:0
msgid "ir.actions.wizard"
msgstr ""
msgstr "ir.actions.wizard"
#. module: base
#: view:ir.actions.act_window:0
@ -3753,12 +3753,12 @@ msgstr "無法載入模組基礎!(提示:檢查附加元件路徑)"
#. module: base
#: view:res.partner.bank:0
msgid "Bank Account Owner"
msgstr "銀行帳所有者"
msgstr "銀行帳所有者"
#. module: base
#: model:ir.actions.act_window,name:base.act_values_form
msgid "Client Actions Connections"
msgstr "客戶端動作連接"
msgstr "用戶端動作連線"
#. module: base
#: field:ir.attachment,res_name:0
@ -3836,7 +3836,7 @@ msgstr ""
#. module: base
#: view:ir.actions.server:0
msgid "Client Action Configuration"
msgstr "客戶端動作設置"
msgstr "用戶端動作設定"
#. module: base
#: model:ir.model,name:base.model_res_partner_address
@ -3872,13 +3872,13 @@ msgstr "選取要匯入之模組套件 (.zip 檔)"
#: field:res.partner.event,name:0
#: model:res.widget,title:base.events_widget
msgid "Events"
msgstr "事件"
msgstr "活動"
#. module: base
#: model:ir.model,name:base.model_ir_actions_url
#: selection:ir.ui.menu,action:0
msgid "ir.actions.url"
msgstr ""
msgstr "ir.actions.url"
#. module: base
#: model:res.widget,title:base.currency_converter_widget
@ -4098,7 +4098,7 @@ msgstr "重複錯過的"
#. module: base
#: help:ir.actions.server,state:0
msgid "Type of the Action that is to be executed"
msgstr "要執行動作之類型"
msgstr "要執行動作之類型"
#. module: base
#: field:ir.server.object.lines,server_id:0
@ -4706,7 +4706,7 @@ msgid ""
"Track from where is coming your leads and opportunities by creating specific "
"channels that will be maintained at the creation of a document in the "
"system. Some examples of channels can be: Website, Phone Call, Reseller, etc."
msgstr ""
msgstr "於系統建立文件,以保持特定渠道追蹤潛在客戶及商機之來源。渠道例子有網站、電話查詢、零售商等等。"
#. module: base
#: model:res.partner.bank.type.field,name:base.bank_normal_field
@ -4765,7 +4765,7 @@ msgstr "變改我的偏好設定"
#: code:addons/base/ir/ir_actions.py:164
#, python-format
msgid "Invalid model name in the action definition."
msgstr "動作定義之模型名無效。"
msgstr "動作定義之模型名無效。"
#. module: base
#: field:partner.sms.send,text:0
@ -4900,7 +4900,7 @@ msgstr "如指定,此動作會於此用戶登入時於標準選單以外額外
#. module: base
#: view:ir.values:0
msgid "Client Actions"
msgstr "戶端動作"
msgstr "戶端動作"
#. module: base
#: code:addons/orm.py:1806
@ -4921,12 +4921,12 @@ msgstr ""
#. module: base
#: field:workflow.transition,act_to:0
msgid "Destination Activity"
msgstr "目的地動"
msgstr "目的地動"
#. module: base
#: view:ir.values:0
msgid "Connect Events to Actions"
msgstr "把事件連接動作"
msgstr "把活動關聯到動作"
#. module: base
#: model:ir.model,name:base.model_base_update_translations
@ -5041,7 +5041,7 @@ msgstr "網頁圖示影像"
#. module: base
#: view:ir.values:0
msgid "Values for Event Type"
msgstr "事件類型值"
msgstr "活動類型值"
#. module: base
#: selection:ir.model.fields,select_level:0
@ -5069,6 +5069,8 @@ msgid ""
"installed the CRM, with the history tab, you can track all the interactions "
"with a partner such as opportunities, emails, or sales orders issued."
msgstr ""
"客戶(於系統其他地方又稱「伙伴」)助您管理其他公司,包括潛在客戶、客戶及/或供應商,之通訊錄。「伙伴表單」讓您追蹤及紀錄所有所需資訊,以讓您處理公司地址、"
"聯絡人、報價單等等。如您安裝了客戶關係管理(CRM)模組,以歷史分頁您可追蹤與伙伴有關之所有來往,如商機、電郵或銷售訂單等。"
#. module: base
#: model:res.country,name:base.ph
@ -5552,7 +5554,7 @@ msgstr ""
#: code:addons/base/res/res_config.py:94
#, python-format
msgid "Couldn't find previous ir.actions.todo"
msgstr ""
msgstr "找不到之前的 ir.actions.todo"
#. module: base
#: view:ir.actions.act_window:0
@ -5792,7 +5794,7 @@ msgstr "宏都拉斯"
#: help:res.users,menu_tips:0
msgid ""
"Check out this box if you want to always display tips on each menu action"
msgstr ""
msgstr "如想於每個選單動作顯示提示,勾選此框"
#. module: base
#: model:res.country,name:base.eg
@ -6078,7 +6080,7 @@ msgstr "建立日期"
msgid ""
"Select the action that will be executed. Loop action will not be avaliable "
"inside loop."
msgstr "選擇將要執行的動作。循環動作在循環內不可用。"
msgstr "選取要執行之動作。循環動作在循環內不可用。"
#. module: base
#: selection:base.language.install,lang:0
@ -6358,7 +6360,7 @@ msgstr "模組更新結果"
#: view:workflow.activity:0
#: field:workflow.workitem,act_id:0
msgid "Activity"
msgstr "動"
msgstr "動"
#. module: base
#: view:res.partner:0
@ -6423,7 +6425,7 @@ msgstr ""
msgid ""
"Customized views are used when users reorganize the content of their "
"dashboard views (via web client)"
msgstr ""
msgstr "當用戶(以 web client重組其 dashboard 檢視即會使用自訂化檢視"
#. module: base
#: field:ir.model,name:0
@ -6494,7 +6496,7 @@ msgstr ""
#: model:ir.actions.act_window,name:base.res_log_act_window
#: model:ir.ui.menu,name:base.menu_res_log_act_window
msgid "Client Logs"
msgstr "戶端日誌"
msgstr "戶端日誌"
#. module: base
#: model:res.country,name:base.al
@ -6534,7 +6536,7 @@ msgstr ""
#: code:addons/base/ir/ir_actions.py:716
#, python-format
msgid "Problem in configuration `Record Id` in Server Action!"
msgstr "於伺服器動作之「Record Id」配置錯誤"
msgstr "伺服器動作之「紀錄 Id」配置有問題"
#. module: base
#: code:addons/orm.py:2306
@ -6587,7 +6589,7 @@ msgstr "電郵"
#: field:res.config.users,action_id:0
#: field:res.users,action_id:0
msgid "Home Action"
msgstr "家動作Home Action"
msgstr "家動作(Home Action)"
#. module: base
#: code:addons/custom.py:558
@ -7603,7 +7605,7 @@ msgstr "要更新模組"
msgid ""
"Important when you deal with multiple actions, the execution order will be "
"decided based on this, low number is higher priority."
msgstr "對於處理多個動作很重要,其決定動作執行順序;小的數字具較高優先次序。"
msgstr "對於處理多重動作很重要,其決定動作執行次序;小的數字具較高優先次序。"
#. module: base
#: field:ir.actions.report.xml,header:0
@ -7756,7 +7758,7 @@ msgstr "格陵蘭"
#. module: base
#: field:res.partner.bank,acc_number:0
msgid "Account Number"
msgstr "帳"
msgstr "帳號"
#. module: base
#: view:res.lang:0
@ -7969,7 +7971,7 @@ msgstr "斯洛伐克文 / Slovenský jazyk"
#: field:ir.ui.menu,icon_pict:0
#: field:publisher_warranty.contract.wizard,state:0
msgid "unknown"
msgstr "不"
msgstr "不"
#. module: base
#: field:res.currency,symbol:0
@ -8032,7 +8034,7 @@ msgstr "CSV 檔"
#. module: base
#: field:res.company,account_no:0
msgid "Account No."
msgstr "帳"
msgstr "帳號"
#. module: base
#: code:addons/base/res/res_lang.py:157
@ -8128,7 +8130,7 @@ msgstr "土耳其文 / Türkçe"
#: view:workflow:0
#: field:workflow,activities:0
msgid "Activities"
msgstr "動"
msgstr "動"
#. module: base
#: field:ir.actions.act_window,auto_refresh:0
@ -8166,7 +8168,7 @@ msgstr ""
#: model:ir.ui.menu,name:base.menu_event_association
#: model:ir.ui.menu,name:base.menu_event_main
msgid "Events Organisation"
msgstr "事件組織"
msgstr "活動組織"
#. module: base
#: model:ir.actions.act_window,name:base.ir_sequence_actions
@ -8247,7 +8249,7 @@ msgstr "添加公司 RML 頁首與否"
#. module: base
#: help:workflow.transition,act_to:0
msgid "The destination activity."
msgstr "目的地活地。"
msgstr "目的地動態。"
#. module: base
#: view:base.module.update:0
@ -8283,7 +8285,7 @@ msgstr "聖誕島"
#. module: base
#: view:ir.actions.server:0
msgid "Other Actions Configuration"
msgstr "其他動作置"
msgstr "其他動作置"
#. module: base
#: view:res.config.installer:0
@ -8307,7 +8309,7 @@ msgstr "額外資訊"
#: model:ir.actions.act_window,name:base.act_values_form_action
#: model:ir.ui.menu,name:base.menu_values_form_action
msgid "Client Events"
msgstr "客戶端事件"
msgstr "用戶端活動"
#. module: base
#: view:ir.module.module:0
@ -8429,7 +8431,7 @@ msgstr "關聯欄位"
#. module: base
#: view:res.partner.event:0
msgid "Event Logs"
msgstr "事件日誌"
msgstr "活動日誌"
#. module: base
#: code:addons/base/module/wizard/base_module_configuration.py:37
@ -8446,7 +8448,7 @@ msgstr "目的地實例"
#: field:ir.actions.act_window,multi:0
#: field:ir.actions.wizard,multi:0
msgid "Action on Multiple Doc."
msgstr "動作作用於多個文件"
msgstr "多重文件之動作。"
#. module: base
#: view:base.language.export:0
@ -8477,7 +8479,7 @@ msgstr "盧森堡"
#: help:ir.values,key2:0
msgid ""
"The kind of action or button in the client side that will trigger the action."
msgstr "客戶端的該類動作或按鈕將觸發此動作。"
msgstr "用戶端的該類動作或按鈕會觸發此動作。"
#. module: base
#: code:addons/base/ir/ir_ui_menu.py:285
@ -8899,7 +8901,7 @@ msgstr "目前視窗"
#. module: base
#: view:ir.values:0
msgid "Action Source"
msgstr "動作來源"
msgstr "動作來源"
#. module: base
#: view:res.config.view:0
@ -9048,7 +9050,7 @@ msgstr "本地化"
#. module: base
#: view:ir.actions.server:0
msgid "Action to Launch"
msgstr "要啟動動作"
msgstr "要執行之動作"
#. module: base
#: view:ir.cron:0
@ -9086,7 +9088,7 @@ msgstr "另存為附件前綴"
msgid ""
"Only one client action will be executed, last client action will be "
"considered in case of multiple client actions."
msgstr "只能執行一個客戶端動作,如有多重動作只考慮最後一個。"
msgstr "只會執行一個用戶端動作,如有多重用戶端動作只考慮最後一個。"
#. module: base
#: view:res.lang:0
@ -9131,7 +9133,7 @@ msgstr "塞席爾"
#: model:ir.model,name:base.model_res_partner_bank
#: view:res.partner.bank:0
msgid "Bank Accounts"
msgstr "銀行帳"
msgstr "銀行帳"
#. module: base
#: model:res.country,name:base.sl
@ -9152,7 +9154,7 @@ msgstr "土克斯及開科斯群島"
#. module: base
#: field:res.partner.bank,owner_name:0
msgid "Account Owner"
msgstr "帳所有者"
msgstr "帳所有者"
#. module: base
#: code:addons/base/res/res_user.py:256

View File

@ -63,7 +63,7 @@ class ir_model(osv.osv):
models = self.browse(cr, uid, ids, context=context)
res = dict.fromkeys(ids)
for model in models:
res[model.id] = isinstance(self.pool.get(model.model), osv.osv_memory)
res[model.id] = self.pool.get(model.model).is_transient()
return res
def _search_osv_memory(self, cr, uid, model, name, domain, context=None):
@ -165,7 +165,7 @@ class ir_model(osv.osv):
pass
x_custom_model._name = model
x_custom_model._module = False
a = x_custom_model.createInstance(self.pool, cr)
a = x_custom_model.create_instance(self.pool, cr)
if (not a._columns) or ('x_name' in a._columns.keys()):
x_name = 'x_name'
else:
@ -481,14 +481,12 @@ class ir_model_access(osv.osv):
if isinstance(model, browse_record):
assert model._table_name == 'ir.model', 'Invalid model object'
model_name = model.name
model_name = model.model
else:
model_name = model
# osv_memory objects can be read by everyone, as they only return
# results that belong to the current user (except for superuser)
model_obj = self.pool.get(model_name)
if isinstance(model_obj, osv.osv_memory):
# TransientModel records have no access rights, only an implicit access rule
if self.pool.get(model_name).is_transient():
return True
# We check if a specific rule exists
@ -523,7 +521,7 @@ class ir_model_access(osv.osv):
}
raise except_orm(_('AccessError'), msgs[mode] % (model_name, groups) )
return r
return r or False
__cache_clearing_methods = []

View File

@ -26,8 +26,7 @@ from functools import partial
import tools
from tools.safe_eval import safe_eval as eval
from tools.misc import unquote as unquote
SUPERUSER_UID = 1
from openerp import SUPERUSER_ID
class ir_rule(osv.osv):
_name = 'ir.rule'
@ -68,7 +67,7 @@ class ir_rule(osv.osv):
return res
def _check_model_obj(self, cr, uid, ids, context=None):
return not any(isinstance(self.pool.get(rule.model_id.model), osv.osv_memory) for rule in self.browse(cr, uid, ids, context))
return not any(self.pool.get(rule.model_id.model).is_transient() for rule in self.browse(cr, uid, ids, context))
_columns = {
'name': fields.char('Name', size=128, select=1),
@ -104,7 +103,7 @@ class ir_rule(osv.osv):
if mode not in self._MODES:
raise ValueError('Invalid mode: %r' % (mode,))
if uid == SUPERUSER_UID:
if uid == SUPERUSER_ID:
return None
cr.execute("""SELECT r.id
FROM ir_rule r
@ -117,10 +116,10 @@ class ir_rule(osv.osv):
rule_ids = [x[0] for x in cr.fetchall()]
if rule_ids:
# browse user as super-admin root to avoid access errors!
user = self.pool.get('res.users').browse(cr, SUPERUSER_UID, uid)
user = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid)
global_domains = [] # list of domains
group_domains = {} # map: group -> list of domains
for rule in self.browse(cr, SUPERUSER_UID, rule_ids):
for rule in self.browse(cr, SUPERUSER_ID, rule_ids):
# read 'domain' as UID to have the correct eval context for the rule.
rule_domain = self.read(cr, uid, rule.id, ['domain'])['domain']
dom = expression.normalize(rule_domain)

View File

@ -19,18 +19,15 @@
#
##############################################################################
from osv import osv
from osv.orm import orm_memory
import openerp
class osv_memory_autovacuum(osv.osv_memory):
class osv_memory_autovacuum(openerp.osv.osv.osv_memory):
""" Expose the osv_memory.vacuum() method to the cron jobs mechanism. """
_name = 'osv_memory.autovacuum'
def power_on(self, cr, uid, context=None):
for model in self.pool.obj_list():
obj = self.pool.get(model)
if isinstance(obj, orm_memory):
obj.vaccum(cr, uid)
for model in self.pool.models.values():
if model.is_transient():
model._transient_vacuum(cr, uid)
return True
osv_memory_autovacuum()

View File

@ -91,7 +91,7 @@ class res_currency(osv.osv):
(name, (COALESCE(company_id,-1)))""")
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
res = super(osv.osv, self).read(cr, user, ids, fields, context, load)
res = super(res_currency, self).read(cr, user, ids, fields, context, load)
currency_rate_obj = self.pool.get('res.currency.rate')
for r in res:
if r.__contains__('rate_ids'):

View File

@ -144,45 +144,3 @@
!python {model: res.partner.category}: |
self.pool._init = True
-
"OSV Memory: Verify that osv_memory properly handles large data allocation"
-
1. No "count-based" auto-vaccuum when max_count is disabled
-
!python {model: base.language.export}: |
# setup special limits for the test, these will be reset at next pool reload anyway
self._max_count = None
num_recs = 250
for i in xrange(num_recs):
self.create(cr, uid, {'format':'po'})
assert (len(self.datas) >= num_recs), "OSV Memory must not auto-vaccum records from the current transaction if max_count is not set"
-
2. Auto-vaccuum should be enabled when max_count is set
-
!python {model: base.language.export}: |
# setup special limits for the test, these will be reset at next pool reload anyway
self._max_count = 100
num_recs = 219
for i in xrange(num_recs):
self.create(cr, uid, {'name': i, 'format':'po'})
assert (self._max_count <= len(self.datas) < self._max_count + self._check_time), "OSV Memory must auto-expire records when max_count is reached"
for k,v in self.datas.iteritems():
assert (int(v['name']) >= (num_recs - (self._max_count + self._check_time))), "OSV Memory must auto-expire records based on age"
-
3. Auto-vaccuum should be based on age only when max_count is not set
-
!python {model: base.language.export}: |
# setup special limits for the test, these will be reset at next pool reload anyway
self._max_count = None
self._max_hours = 0.01 #36 seconds
num_recs = 200
for i in xrange(num_recs):
self.create(cr, uid, {'format':'po'})
assert (len(self.datas) >= num_recs), "OSV Memory must not auto-expire records from the current transaction"
# expire all records
for k,v in self.datas.iteritems():
v['internal.date_access'] = 0
self.vaccum(cr, 1, force=True)
assert (len(self.datas) == 0), "OSV Memory must expire old records after vaccuum"

View File

@ -339,16 +339,16 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""")
for (model, name) in cr.fetchall():
model_obj = pool.get(model)
if model_obj and not isinstance(model_obj, osv.osv.osv_memory):
logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name))
if model_obj and not model_obj.is_transient():
logger.notifyChannel('init', netsvc.LOG_WARNING, 'Model %s (%s) has no access rules!' % (model, name))
# Temporary warning while we remove access rights on osv_memory objects, as they have
# been replaced by owner-only access rights
cr.execute("""select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""")
for (model, name) in cr.fetchall():
model_obj = pool.get(model)
if isinstance(model_obj, osv.osv.osv_memory) and not isinstance(model_obj, osv.osv.osv):
logger.notifyChannel('init', netsvc.LOG_WARNING, 'In-memory object %s (%s) should not have explicit access rules!' % (model, name))
if model_obj and model_obj.is_transient():
logger.notifyChannel('init', netsvc.LOG_WARNING, 'The transient model %s (%s) should not have explicit access rules!' % (model, name))
cr.execute("SELECT model from ir_model")
for (model,) in cr.fetchall():
@ -356,7 +356,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
if obj:
obj._check_removed_columns(cr, log=True)
else:
logger.notifyChannel('init', netsvc.LOG_WARNING, "Model %s is referenced but not present in the orm pool!" % model)
logger.notifyChannel('init', netsvc.LOG_WARNING, "Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)" % model)
# Cleanup orphan records
pool.get('ir.model.data')._process_end(cr, 1, processed_modules)

View File

@ -277,7 +277,6 @@ def init_module_models(cr, module_name, obj_list):
TODO better explanation of _auto_init and init.
"""
logger.notifyChannel('init', netsvc.LOG_INFO,
'module %s: creating or updating database tables' % module_name)
todo = []

View File

@ -89,10 +89,10 @@ class Registry(object):
res = []
# Instantiate registered classes (via metamodel discovery or via explicit
# constructor call), and add them to the pool.
# Instantiate registered classes (via the MetaModel automatic discovery
# or via explicit constructor call), and add them to the pool.
for cls in openerp.osv.orm.MetaModel.module_to_models.get(module.name, []):
res.append(cls.createInstance(self, cr))
res.append(cls.create_instance(self, cr))
return res

View File

@ -450,7 +450,7 @@ class expression(object):
# field could not be found in model columns, it's probably invalid, unless
# it's one of the _log_access special fields
# TODO: make these fields explicitly available in self.columns instead!
if (field_path[0] not in MAGIC_COLUMNS) and (left not in MAGIC_COLUMNS):
if field_path[0] not in MAGIC_COLUMNS:
raise ValueError("Invalid field %r in domain expression %r" % (left, exp))
continue

View File

@ -72,7 +72,7 @@ class _column(object):
_symbol_set = (_symbol_c, _symbol_f)
_symbol_get = None
def __init__(self, string='unknown', required=False, readonly=False, domain=None, context=None, states=None, priority=0, change_default=False, size=None, ondelete="set null", translate=False, select=False, manual=False, **args):
def __init__(self, string='unknown', required=False, readonly=False, domain=None, context=None, states=None, priority=0, change_default=False, size=None, ondelete=None, translate=False, select=False, manual=False, **args):
"""
The 'manual' keyword argument specifies if the field is a custom one.
@ -91,7 +91,7 @@ class _column(object):
self.help = args.get('help', '')
self.priority = priority
self.change_default = change_default
self.ondelete = ondelete
self.ondelete = ondelete.lower() if ondelete else None # defaults to 'set null' in ORM
self.translate = translate
self._domain = domain
self._context = context
@ -112,12 +112,6 @@ class _column(object):
def set(self, cr, obj, id, name, value, user=None, context=None):
cr.execute('update '+obj._table+' set '+name+'='+self._symbol_set[0]+' where id=%s', (self._symbol_set[1](value), id))
def set_memory(self, cr, obj, id, name, value, user=None, context=None):
raise Exception(_('Not implemented set_memory method !'))
def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None):
raise Exception(_('Not implemented get_memory method !'))
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
raise Exception(_('undefined get method !'))
@ -126,9 +120,6 @@ class _column(object):
res = obj.read(cr, uid, ids, [name], context=context)
return [x[name] for x in res]
def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, context=None):
raise Exception(_('Not implemented search_memory method !'))
# ---------------------------------------------------------
# Simple fields
@ -269,7 +260,7 @@ class binary(_column):
_column.__init__(self, string=string, **args)
self.filters = filters
def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None):
def get(self, cr, obj, ids, name, user=None, context=None, values=None):
if not context:
context = {}
if not values:
@ -293,9 +284,6 @@ class binary(_column):
res[i] = val
return res
get = get_memory
class selection(_column):
_type = 'selection'
@ -355,30 +343,6 @@ class many2one(_column):
_column.__init__(self, string=string, **args)
self._obj = obj
def set_memory(self, cr, obj, id, field, values, user=None, context=None):
obj.datas.setdefault(id, {})
obj.datas[id][field] = values
def get_memory(self, cr, obj, ids, name, user=None, context=None, values=None):
result = {}
for id in ids:
result[id] = obj.datas[id].get(name, False)
# build a dictionary of the form {'id_of_distant_resource': name_of_distant_resource}
# we use uid=1 because the visibility of a many2one field value (just id and name)
# must be the access right of the parent form and not the linked object itself.
obj = obj.pool.get(self._obj)
records = dict(obj.name_get(cr, 1,
list(set([x for x in result.values() if x and isinstance(x, (int,long))])),
context=context))
for id in ids:
if result[id] in records:
result[id] = (result[id], records[result[id]])
else:
result[id] = False
return result
def get(self, cr, obj, ids, name, user=None, context=None, values=None):
if context is None:
context = {}
@ -447,55 +411,6 @@ class one2many(_column):
#one2many can't be used as condition for defaults
assert(self.change_default != True)
def get_memory(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
if context is None:
context = {}
if self._context:
context = context.copy()
context.update(self._context)
if not values:
values = {}
res = {}
for id in ids:
res[id] = []
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id, 'in', ids)], limit=self._limit, context=context)
for r in obj.pool.get(self._obj).read(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
if r[self._fields_id] in res:
res[r[self._fields_id]].append(r['id'])
return res
def set_memory(self, cr, obj, id, field, values, user=None, context=None):
if not context:
context = {}
if self._context:
context = context.copy()
context.update(self._context)
if not values:
return
obj = obj.pool.get(self._obj)
for act in values:
if act[0] == 0:
act[2][self._fields_id] = id
obj.create(cr, user, act[2], context=context)
elif act[0] == 1:
obj.write(cr, user, [act[1]], act[2], context=context)
elif act[0] == 2:
obj.unlink(cr, user, [act[1]], context=context)
elif act[0] == 3:
obj.datas[act[1]][self._fields_id] = False
elif act[0] == 4:
obj.datas[act[1]][self._fields_id] = id
elif act[0] == 5:
for o in obj.datas.values():
if o[self._fields_id] == id:
o[self._fields_id] = False
elif act[0] == 6:
for id2 in (act[2] or []):
obj.datas[id2][self._fields_id] = id
def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None):
raise _('Not Implemented')
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
if context is None:
context = {}
@ -578,14 +493,34 @@ class one2many(_column):
# (6, ?, ids) set a list of links
#
class many2many(_column):
"""Encapsulates the logic of a many-to-many bidirectional relationship, handling the
low-level details of the intermediary relationship table transparently.
:param str obj: destination model
:param str rel: optional name of the intermediary relationship table. If not specified,
a canonical name will be derived based on the alphabetically-ordered
model names of the source and destination (in the form: ``amodel_bmodel_rel``).
Automatic naming is not possible when the source and destination are
the same, for obvious ambiguity reasons.
:param str id1: optional name for the column holding the foreign key to the current
model in the relationship table. If not specified, a canonical name
will be derived based on the model name (in the form: `src_model_id`).
:param str id2: optional name for the column holding the foreign key to the destination
model in the relationship table. If not specified, a canonical name
will be derived based on the model name (in the form: `dest_model_id`)
:param str string: field label
"""
_classic_read = False
_classic_write = False
_prefetch = False
_type = 'many2many'
def __init__(self, obj, rel, id1, id2, string='unknown', limit=None, **args):
def __init__(self, obj, rel=None, id1=None, id2=None, string='unknown', limit=None, **args):
"""
"""
_column.__init__(self, string=string, **args)
self._obj = obj
if '.' in rel:
if rel and '.' in rel:
raise Exception(_('The second argument of the many2many field %s must be a SQL table !'\
'You used %s, which is not a valid SQL table name.')% (string,rel))
self._rel = rel
@ -593,7 +528,30 @@ class many2many(_column):
self._id2 = id2
self._limit = limit
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
def _sql_names(self, source_model):
"""Return the SQL names defining the structure of the m2m relationship table
:return: (m2m_table, local_col, dest_col) where m2m_table is the table name,
local_col is the name of the column holding the current model's FK, and
dest_col is the name of the column holding the destination model's FK, and
"""
tbl, col1, col2 = self._rel, self._id1, self._id2
if not all((tbl, col1, col2)):
# the default table name is based on the stable alphabetical order of tables
dest_model = source_model.pool.get(self._obj)
tables = tuple(sorted([source_model._table, dest_model._table]))
if not tbl:
assert tables[0] != tables[1], 'Implicit/Canonical naming of m2m relationship table '\
'is not possible when source and destination models are '\
'the same'
tbl = '%s_%s_rel' % tables
if not col1:
col1 = '%s_id' % source_model._table
if not col2:
col2 = '%s_id' % dest_model._table
return (tbl, col1, col2)
def get(self, cr, model, ids, name, user=None, offset=0, context=None, values=None):
if not context:
context = {}
if not values:
@ -606,7 +564,8 @@ class many2many(_column):
if offset:
warnings.warn("Specifying offset at a many2many.get() may produce unpredictable results.",
DeprecationWarning, stacklevel=2)
obj = obj.pool.get(self._obj)
obj = model.pool.get(self._obj)
rel, id1, id2 = self._sql_names(model)
# static domains are lists, and are evaluated both here and on client-side, while string
# domains supposed by dynamic and evaluated on client-side only (thus ignored here)
@ -636,11 +595,11 @@ class many2many(_column):
%(order_by)s \
%(limit)s \
OFFSET %(offset)d' \
% {'rel': self._rel,
% {'rel': rel,
'from_c': from_c,
'tbl': obj._table,
'id1': self._id1,
'id2': self._id2,
'id1': id1,
'id2': id2,
'where_c': where_c,
'limit': limit_str,
'order_by': order_by,
@ -651,31 +610,32 @@ class many2many(_column):
res[r[1]].append(r[0])
return res
def set(self, cr, obj, id, name, values, user=None, context=None):
def set(self, cr, model, id, name, values, user=None, context=None):
if not context:
context = {}
if not values:
return
obj = obj.pool.get(self._obj)
rel, id1, id2 = self._sql_names(model)
obj = model.pool.get(self._obj)
for act in values:
if not (isinstance(act, list) or isinstance(act, tuple)) or not act:
continue
if act[0] == 0:
idnew = obj.create(cr, user, act[2], context=context)
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s,%s)', (id, idnew))
cr.execute('insert into '+rel+' ('+id1+','+id2+') values (%s,%s)', (id, idnew))
elif act[0] == 1:
obj.write(cr, user, [act[1]], act[2], context=context)
elif act[0] == 2:
obj.unlink(cr, user, [act[1]], context=context)
elif act[0] == 3:
cr.execute('delete from '+self._rel+' where ' + self._id1 + '=%s and '+ self._id2 + '=%s', (id, act[1]))
cr.execute('delete from '+rel+' where ' + id1 + '=%s and '+ id2 + '=%s', (id, act[1]))
elif act[0] == 4:
# following queries are in the same transaction - so should be relatively safe
cr.execute('SELECT 1 FROM '+self._rel+' WHERE '+self._id1+' = %s and '+self._id2+' = %s', (id, act[1]))
cr.execute('SELECT 1 FROM '+rel+' WHERE '+id1+' = %s and '+id2+' = %s', (id, act[1]))
if not cr.fetchone():
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s,%s)', (id, act[1]))
cr.execute('insert into '+rel+' ('+id1+','+id2+') values (%s,%s)', (id, act[1]))
elif act[0] == 5:
cr.execute('delete from '+self._rel+' where ' + self._id1 + ' = %s', (id,))
cr.execute('delete from '+rel+' where ' + id1 + ' = %s', (id,))
elif act[0] == 6:
d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
@ -683,10 +643,10 @@ class many2many(_column):
d1 = ' and ' + ' and '.join(d1)
else:
d1 = ''
cr.execute('delete from '+self._rel+' where '+self._id1+'=%s AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+','.join(tables)+' WHERE '+self._rel+'.'+self._id1+'=%s AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
cr.execute('delete from '+rel+' where '+id1+'=%s AND '+id2+' IN (SELECT '+rel+'.'+id2+' FROM '+rel+', '+','.join(tables)+' WHERE '+rel+'.'+id1+'=%s AND '+rel+'.'+id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
for act_nbr in act[2]:
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s, %s)', (id, act_nbr))
cr.execute('insert into '+rel+' ('+id1+','+id2+') values (%s, %s)', (id, act_nbr))
#
# TODO: use a name_search
@ -694,32 +654,6 @@ class many2many(_column):
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None):
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name', operator, value)], offset, limit, context=context)
def get_memory(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
result = {}
for id in ids:
result[id] = obj.datas[id].get(name, [])
return result
def set_memory(self, cr, obj, id, name, values, user=None, context=None):
if not values:
return
for act in values:
# TODO: use constants instead of these magic numbers
if act[0] == 0:
raise _('Not Implemented')
elif act[0] == 1:
raise _('Not Implemented')
elif act[0] == 2:
raise _('Not Implemented')
elif act[0] == 3:
raise _('Not Implemented')
elif act[0] == 4:
raise _('Not Implemented')
elif act[0] == 5:
raise _('Not Implemented')
elif act[0] == 6:
obj.datas[id][name] = act[2]
def get_nice_size(value):
size = 0
@ -801,8 +735,8 @@ class function(_column):
Implements the function field.
:param orm_template model: model to which the field belongs (should be ``self`` for
a model method)
:param orm model: model to which the field belongs (should be ``self`` for
a model method)
:param field_name(s): name of the field to compute, or if ``multi`` is provided,
list of field names to compute.
:type field_name(s): str | [str]
@ -865,8 +799,8 @@ class function(_column):
Callable that implements the ``write`` operation for the function field.
:param orm_template model: model to which the field belongs (should be ``self`` for
a model method)
:param orm model: model to which the field belongs (should be ``self`` for
a model method)
:param int id: the identifier of the object to write on
:param str field_name: name of the field to set
:param fnct_inv_arg: arbitrary value passed when declaring the function field
@ -887,10 +821,10 @@ class function(_column):
a search criterion based on the function field into a new domain based only on
columns that are stored in the database.
:param orm_template model: model to which the field belongs (should be ``self`` for
a model method)
:param orm_template model_again: same value as ``model`` (seriously! this is for backwards
compatibility)
:param orm model: model to which the field belongs (should be ``self`` for
a model method)
:param orm model_again: same value as ``model`` (seriously! this is for backwards
compatibility)
:param str field_name: name of the field to search on
:param list criterion: domain component specifying the search criterion on the field.
:rtype: list
@ -935,7 +869,7 @@ class function(_column):
corresponding records in the source model (whose field values
need to be recomputed).
:param orm_template model: trigger_model
:param orm model: trigger_model
:param list trigger_ids: ids of the records of trigger_model that were
modified
:rtype: list
@ -1064,14 +998,11 @@ class function(_column):
result[id] = self.postprocess(cr, uid, obj, name, result[id], context)
return result
get_memory = get
def set(self, cr, obj, id, name, value, user=None, context=None):
if not context:
context = {}
if self._fnct_inv:
self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context)
set_memory = set
# ---------------------------------------------------------
# Related fields

File diff suppressed because it is too large Load Diff

View File

@ -21,16 +21,17 @@
#.apidoc title: Objects Services (OSV)
import logging
from psycopg2 import IntegrityError, errorcodes
import orm
import openerp
import openerp.netsvc as netsvc
import openerp.pooler as pooler
import openerp.sql_db as sql_db
import logging
from psycopg2 import IntegrityError, errorcodes
from openerp.tools.func import wraps
from openerp.tools.translate import translate
from openerp.osv.orm import MetaModel
from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel
class except_osv(Exception):
def __init__(self, name, value, exc_type='warning'):
@ -198,17 +199,10 @@ class object_proxy():
cr.close()
return res
class osv_memory(orm.orm_memory):
""" Deprecated class. """
__metaclass__ = MetaModel
_register = False # Set to false if the model shouldn't be automatically discovered.
class osv(orm.orm):
""" Deprecated class. """
__metaclass__ = MetaModel
_register = False # Set to false if the model shouldn't be automatically discovered.
# deprecated - for backward compatibility.
osv = Model
osv_memory = TransientModel
osv_abstract = AbstractModel # ;-)
def start_object_proxy():

View File

@ -307,7 +307,7 @@ class YamlInterpreter(object):
import openerp.osv as osv
record, fields = node.items()[0]
model = self.get_model(record.model)
if isinstance(model, osv.osv.osv_memory):
if model.is_transient():
record_dict=self.create_osv_memory_record(record, fields)
else:
self.validate_xml_id(record.id)