diff --git a/openerp-server b/openerp-server
index 277451df74e..94dc6d6df6f 100755
--- a/openerp-server
+++ b/openerp-server
@@ -27,7 +27,7 @@ OpenERP is an ERP+CRM program for small and medium businesses.
The whole source code is distributed under the terms of the
GNU Public Licence.
-(c) 2003-TODAY, Fabien Pinckaers - OpenERP s.a.
+(c) 2003-TODAY, Fabien Pinckaers - OpenERP SA
"""
import logging
@@ -88,8 +88,11 @@ def setup_pid_file():
def preload_registry(dbname):
""" Preload a registry, and start the cron."""
- db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
- pool.get('ir.cron').restart(db.dbname)
+ try:
+ db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
+ pool.get('ir.cron').restart(db.dbname)
+ except Exception:
+ logging.exception('Failed to initialize database `%s`.', dbname)
def run_test_file(dbname, test_file):
""" Preload a registry, possibly run a test file, and start the cron."""
@@ -233,6 +236,8 @@ def quit_on_signals():
if __name__ == "__main__":
+ os.environ["TZ"] = "UTC"
+
check_root_user()
openerp.tools.config.parse_config(sys.argv[1:])
check_postgres_user()
diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py
index f19c5bc7832..4857ff0bedf 100644
--- a/openerp/addons/base/__openerp__.py
+++ b/openerp/addons/base/__openerp__.py
@@ -67,7 +67,7 @@
'res/res_currency_view.xml',
'res/res_partner_event_view.xml',
'res/wizard/partner_sms_send_view.xml',
- 'res/wizard/partner_wizard_spam_view.xml',
+ 'res/wizard/partner_wizard_massmail_view.xml',
'res/wizard/partner_clear_ids_view.xml',
'res/wizard/partner_wizard_ean_check_view.xml',
'res/res_partner_data.xml',
diff --git a/openerp/addons/base/base_data.xml b/openerp/addons/base/base_data.xml
index 00fb83a0796..f3c305fb789 100644
--- a/openerp/addons/base/base_data.xml
+++ b/openerp/addons/base/base_data.xml
@@ -1086,16 +1086,17 @@
-
- VEB
- Bs
- 2.95
+
+
+ VEF
+ Bs.F
+ 0.00014
-
- 2768.45
-
+
+ 5.864
+
@@ -1599,12 +1600,20 @@
0.014¢
+ 691.3153
-
+
+
+
+ localhost
+ localhost
+
+
+ MUR
diff --git a/openerp/addons/base/base_update.xml b/openerp/addons/base/base_update.xml
index b87c0ef4382..444c7b5189c 100644
--- a/openerp/addons/base/base_update.xml
+++ b/openerp/addons/base/base_update.xml
@@ -75,29 +75,29 @@
-->
- res.users.form.modif
+ res.users.preferences.formres.usersform
@@ -147,7 +147,7 @@
-
+
diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po
index bfa8ea8ed25..1a20a156fe9 100644
--- a/openerp/addons/base/i18n/cs.po
+++ b/openerp/addons/base/i18n/cs.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
-"PO-Revision-Date: 2011-09-09 10:34+0000\n"
+"PO-Revision-Date: 2011-09-16 16:25+0000\n"
"Last-Translator: Jiří Hajda \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-10 05:01+0000\n"
-"X-Generator: Launchpad (build 13900)\n"
+"X-Launchpad-Export-Date: 2011-09-17 04:54+0000\n"
+"X-Generator: Launchpad (build 13955)\n"
"X-Poedit-Language: Czech\n"
#. module: base
@@ -3812,7 +3812,7 @@ msgstr ""
#. module: base
#: view:publisher_warranty.contract.wizard:0
msgid "Please enter the serial key provided in your contract document:"
-msgstr "Prosíme zadejte sériové číslo poskytnuté ve dokumentu vaší smlouvy:"
+msgstr "Prosíme zadejte sériové číslo poskytnuté v dokumentu vaší smlouvy:"
#. module: base
#: view:workflow.activity:0
@@ -7379,7 +7379,7 @@ msgstr "Typ výkazu"
#: field:workflow.instance,state:0
#: field:workflow.workitem,state:0
msgid "State"
-msgstr "Stát"
+msgstr "Stav"
#. module: base
#: selection:base.language.install,lang:0
diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po
index e9c4a7b1bc0..45a31676521 100644
--- a/openerp/addons/base/i18n/en_GB.po
+++ b/openerp/addons/base/i18n/en_GB.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME \n"
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
-"PO-Revision-Date: 2011-07-28 15:35+0000\n"
+"PO-Revision-Date: 2011-09-22 14:47+0000\n"
"Last-Translator: John Bradshaw \n"
"Language-Team: English (United Kingdom) \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:44+0000\n"
-"X-Generator: Launchpad (build 13827)\n"
+"X-Launchpad-Export-Date: 2011-09-23 04:38+0000\n"
+"X-Generator: Launchpad (build 14012)\n"
#. module: base
#: view:ir.filters:0
@@ -1972,7 +1972,7 @@ msgstr "Iteration Actions"
#. module: base
#: help:multi_company.default,company_id:0
msgid "Company where the user is connected"
-msgstr ""
+msgstr "Company where the user is connected"
#. module: base
#: field:publisher_warranty.contract,date_stop:0
@@ -2583,7 +2583,7 @@ msgstr "Search Actions"
#: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check
#: view:partner.wizard.ean.check:0
msgid "Ean check"
-msgstr ""
+msgstr "Ean check"
#. module: base
#: field:res.partner,vat:0
@@ -2623,7 +2623,7 @@ msgstr "GPL-2 or later version"
#. module: base
#: model:res.partner.title,shortcut:base.res_partner_title_sir
msgid "M."
-msgstr ""
+msgstr "M."
#. module: base
#: code:addons/base/module/module.py:429
@@ -3001,7 +3001,7 @@ msgstr "License"
#. module: base
#: field:ir.attachment,url:0
msgid "Url"
-msgstr ""
+msgstr "Url"
#. module: base
#: selection:ir.actions.todo,restart:0
@@ -3153,7 +3153,7 @@ msgstr "Workflows"
#. module: base
#: field:ir.translation,xml_id:0
msgid "XML Id"
-msgstr ""
+msgstr "XML Id"
#. module: base
#: model:ir.actions.act_window,name:base.action_config_user_form
@@ -3224,7 +3224,7 @@ msgstr "Abkhazian / аҧсуа"
#. module: base
#: view:base.module.configuration:0
msgid "System Configuration Done"
-msgstr ""
+msgstr "System Configuration Done"
#. module: base
#: code:addons/orm.py:929
@@ -3271,7 +3271,7 @@ msgstr "That contract is already registered in the system."
#. module: base
#: help:ir.sequence,suffix:0
msgid "Suffix value of the record for the sequence"
-msgstr ""
+msgstr "Suffix value of the record for the sequence"
#. module: base
#: selection:base.language.install,lang:0
@@ -3343,7 +3343,7 @@ msgstr "Installed"
#. module: base
#: selection:base.language.install,lang:0
msgid "Ukrainian / українська"
-msgstr ""
+msgstr "Ukrainian / українська"
#. module: base
#: model:ir.actions.act_window,name:base.action_translation
@@ -3389,7 +3389,7 @@ msgstr "Next Number"
#. module: base
#: help:workflow.transition,condition:0
msgid "Expression to be satisfied if we want the transition done."
-msgstr ""
+msgstr "Expression to be satisfied if we want the transition done."
#. module: base
#: selection:base.language.install,lang:0
@@ -3518,6 +3518,12 @@ msgid ""
"Would your payment have been carried out after this mail was sent, please "
"consider the present one as void."
msgstr ""
+"Please note that the following payments are now due. If your payment "
+" has been sent, kindly forward your payment details. If "
+"payment will be delayed, please contact us to "
+"discuss. \n"
+"If payment was performed after this mail was sent, please consider the "
+"present one as void."
#. module: base
#: model:res.country,name:base.mx
@@ -3673,6 +3679,8 @@ msgid ""
"If set to true, the action will not be displayed on the right toolbar of a "
"form view"
msgstr ""
+"If set to true, the action will not be displayed on the right toolbar of a "
+"form view"
#. module: base
#: model:res.country,name:base.ms
@@ -3717,7 +3725,7 @@ msgstr "English (UK)"
#. module: base
#: selection:base.language.install,lang:0
msgid "Japanese / 日本語"
-msgstr ""
+msgstr "Japanese / 日本語"
#. module: base
#: help:workflow.transition,act_from:0
@@ -3725,6 +3733,8 @@ msgid ""
"Source activity. When this activity is over, the condition is tested to "
"determine if we can start the ACT_TO activity."
msgstr ""
+"Source activity. When this activity is over, the condition is tested to "
+"determine if we can start the ACT_TO activity."
#. module: base
#: model:res.partner.category,name:base.res_partner_category_3
@@ -3885,7 +3895,7 @@ msgstr "Init Date"
#. module: base
#: selection:base.language.install,lang:0
msgid "Gujarati / ગુજરાતી"
-msgstr ""
+msgstr "Gujarati / ગુજરાતી"
#. module: base
#: code:addons/base/module/module.py:257
@@ -3953,6 +3963,9 @@ msgid ""
"form, signal tests the name of the pressed button. If signal is NULL, no "
"button is necessary to validate this transition."
msgstr ""
+"When the operation of transition comes from a button press in the client "
+"form, signal tests the name of the pressed button. If signal is NULL, no "
+"button is necessary to validate this transition."
#. module: base
#: help:multi_company.default,object_id:0
@@ -3972,7 +3985,7 @@ msgstr "Menu Name"
#. module: base
#: view:ir.module.module:0
msgid "Author Website"
-msgstr ""
+msgstr "Author Website"
#. module: base
#: view:ir.attachment:0
@@ -4012,6 +4025,8 @@ msgid ""
"Whether values for this field can be translated (enables the translation "
"mechanism for that field)"
msgstr ""
+"Whether values for this field can be translated (enables the translation "
+"mechanism for that field)"
#. module: base
#: view:res.lang:0
@@ -4072,13 +4087,13 @@ msgstr "Price Accuracy"
#. module: base
#: selection:base.language.install,lang:0
msgid "Latvian / latviešu valoda"
-msgstr ""
+msgstr "Latvian / latviešu valoda"
#. module: base
#: view:res.config:0
#: view:res.config.installer:0
msgid "vsep"
-msgstr ""
+msgstr "vsep"
#. module: base
#: selection:base.language.install,lang:0
@@ -4099,7 +4114,7 @@ msgstr "Workitem"
#. module: base
#: view:ir.actions.todo:0
msgid "Set as Todo"
-msgstr ""
+msgstr "Set as Todo"
#. module: base
#: field:ir.actions.act_window.view,act_window_id:0
@@ -4177,7 +4192,7 @@ msgstr "Menus"
#. module: base
#: selection:base.language.install,lang:0
msgid "Serbian (Latin) / srpski"
-msgstr ""
+msgstr "Serbian (Latin) / srpski"
#. module: base
#: model:res.country,name:base.il
@@ -4353,7 +4368,7 @@ msgstr ""
#. module: base
#: view:base.language.import:0
msgid "- module,type,name,res_id,src,value"
-msgstr ""
+msgstr "- module,type,name,res_id,src,value"
#. module: base
#: selection:base.language.install,lang:0
@@ -4372,7 +4387,7 @@ msgstr ""
#. module: base
#: help:ir.model.fields,relation:0
msgid "For relationship fields, the technical name of the target model"
-msgstr ""
+msgstr "For relationship fields, the technical name of the target model"
#. module: base
#: selection:base.language.install,lang:0
@@ -4387,7 +4402,7 @@ msgstr "Inherited View"
#. module: base
#: view:ir.translation:0
msgid "Source Term"
-msgstr ""
+msgstr "Source Term"
#. module: base
#: model:ir.ui.menu,name:base.menu_main_pm
@@ -4397,7 +4412,7 @@ msgstr "Project"
#. module: base
#: field:ir.ui.menu,web_icon_hover_data:0
msgid "Web Icon Image (hover)"
-msgstr ""
+msgstr "Web Icon Image (hover)"
#. module: base
#: view:base.module.import:0
@@ -4417,7 +4432,7 @@ msgstr "Create User"
#. module: base
#: view:partner.clear.ids:0
msgid "Want to Clear Ids ? "
-msgstr ""
+msgstr "Want to Clear Ids ? "
#. module: base
#: field:publisher_warranty.contract,name:0
@@ -4469,17 +4484,17 @@ msgstr "Fed. State"
#. module: base
#: field:ir.actions.server,copy_object:0
msgid "Copy Of"
-msgstr ""
+msgstr "Copy Of"
#. module: base
#: field:ir.model,osv_memory:0
msgid "In-memory model"
-msgstr ""
+msgstr "In-memory model"
#. module: base
#: view:partner.clear.ids:0
msgid "Clear Ids"
-msgstr ""
+msgstr "Clear Ids"
#. module: base
#: model:res.country,name:base.io
@@ -4501,7 +4516,7 @@ msgstr "Field Mapping"
#. module: base
#: view:publisher_warranty.contract:0
msgid "Refresh Validation Dates"
-msgstr ""
+msgstr "Refresh Validation Dates"
#. module: base
#: view:ir.model:0
@@ -4572,7 +4587,7 @@ msgstr "_Ok"
#. module: base
#: help:ir.filters,user_id:0
msgid "False means for every user"
-msgstr ""
+msgstr "False means for every user"
#. module: base
#: code:addons/base/module/module.py:198
@@ -4621,6 +4636,7 @@ msgstr "Contacts"
msgid ""
"Unable to delete this document because it is used as a default property"
msgstr ""
+"Unable to delete this document because it is used as a default property"
#. module: base
#: view:res.widget.wizard:0
@@ -4674,7 +4690,7 @@ msgstr ""
#: code:addons/orm.py:1350
#, python-format
msgid "Insufficient fields for Calendar View!"
-msgstr ""
+msgstr "Insufficient fields for Calendar View!"
#. module: base
#: selection:ir.property,type:0
@@ -4687,6 +4703,8 @@ msgid ""
"The path to the main report file (depending on Report Type) or NULL if the "
"content is in another data field"
msgstr ""
+"The path to the main report file (depending on Report Type) or NULL if the "
+"content is in another data field"
#. module: base
#: help:res.config.users,company_id:0
@@ -4748,7 +4766,7 @@ msgstr "Close"
#. module: base
#: selection:base.language.install,lang:0
msgid "Spanish (MX) / Español (MX)"
-msgstr ""
+msgstr "Spanish (MX) / Español (MX)"
#. module: base
#: view:res.log:0
@@ -4783,7 +4801,7 @@ msgstr "Publisher Warranty Contracts"
#. module: base
#: help:res.log,name:0
msgid "The logging message."
-msgstr ""
+msgstr "The logging message."
#. module: base
#: field:base.language.export,format:0
@@ -5018,7 +5036,7 @@ msgstr ""
#. module: base
#: help:ir.cron,interval_number:0
msgid "Repeat every x."
-msgstr ""
+msgstr "Repeat every x."
#. module: base
#: wizard_view:server.action.create,step_1:0
@@ -5078,6 +5096,8 @@ msgid ""
"If specified, this action will be opened at logon for this user, in addition "
"to the standard menu."
msgstr ""
+"If specified, this action will be opened at logon for this user, in addition "
+"to the standard menu."
#. module: base
#: view:ir.values:0
@@ -5088,7 +5108,7 @@ msgstr "Client Actions"
#: code:addons/orm.py:1806
#, python-format
msgid "The exists method is not implemented on this object !"
-msgstr ""
+msgstr "The exists method is not implemented on this object !"
#. module: base
#: code:addons/base/module/module.py:336
@@ -5113,7 +5133,7 @@ msgstr "Connect Events to Actions"
#. module: base
#: model:ir.model,name:base.model_base_update_translations
msgid "base.update.translations"
-msgstr ""
+msgstr "base.update.translations"
#. module: base
#: field:ir.module.category,parent_id:0
@@ -5124,7 +5144,7 @@ msgstr "Parent Category"
#. module: base
#: selection:ir.property,type:0
msgid "Integer Big"
-msgstr ""
+msgstr "Integer Big"
#. module: base
#: selection:res.partner.address,type:0
@@ -5158,7 +5178,7 @@ msgstr "Communication"
#. module: base
#: view:ir.actions.report.xml:0
msgid "RML Report"
-msgstr ""
+msgstr "RML Report"
#. module: base
#: model:ir.model,name:base.model_ir_server_object_lines
@@ -5206,7 +5226,7 @@ msgstr "Nigeria"
#: code:addons/base/ir/ir_model.py:250
#, python-format
msgid "For selection fields, the Selection Options must be given!"
-msgstr ""
+msgstr "For selection fields, the Selection Options must be given!"
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_sms_send
@@ -5254,6 +5274,13 @@ 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 ""
+"Customers (also called Partners in other areas of the system) helps you "
+"manage your address book of companies whether they are prospects, customers "
+"and/or suppliers. The partner form allows you to track and record all the "
+"necessary information to interact with your partners from the company "
+"address to their contacts as well as pricelists, and much more. If you "
+"installed the CRM, with the history tab, you can track all interactions with "
+"a partner such as opportunities, emails, or sales orders issued."
#. module: base
#: model:res.country,name:base.ph
@@ -5278,7 +5305,7 @@ msgstr "Content"
#. module: base
#: help:ir.rule,global:0
msgid "If no group is specified the rule is global and applied to everyone"
-msgstr ""
+msgstr "If no group is specified the rule is global and applied to everyone"
#. module: base
#: model:res.country,name:base.td
@@ -5355,6 +5382,9 @@ msgid ""
"groups. If this field is empty, OpenERP will compute visibility based on the "
"related object's read access."
msgstr ""
+"If you have groups, the visibility of this menu will be based on these "
+"groups. If this field is empty, OpenERP will compute visibility based on the "
+"related object's read access."
#. module: base
#: model:ir.actions.act_window,name:base.action_ui_view_custom
@@ -5496,7 +5526,7 @@ msgstr "Spanish (EC) / Español (EC)"
#. module: base
#: help:ir.ui.view,xml_id:0
msgid "ID of the view defined in xml file"
-msgstr ""
+msgstr "ID of the view defined in xml file"
#. module: base
#: model:ir.model,name:base.model_base_module_import
@@ -5512,7 +5542,7 @@ msgstr "American Samoa"
#. module: base
#: help:ir.actions.act_window,res_model:0
msgid "Model name of the object to open in the view window"
-msgstr ""
+msgstr "Model name of the object to open in the view window"
#. module: base
#: field:res.log,secondary:0
@@ -5692,11 +5722,15 @@ msgid ""
"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't "
"be possible to email new users."
msgstr ""
+"If an email is provided, the user will be sent a message welcoming them.\n"
+"\n"
+"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't "
+"be possible to email new users."
#. module: base
#: selection:base.language.install,lang:0
msgid "Flemish (BE) / Vlaams (BE)"
-msgstr ""
+msgstr "Flemish (BE) / Vlaams (BE)"
#. module: base
#: field:ir.cron,interval_number:0
@@ -5746,7 +5780,7 @@ msgstr "ir.actions.todo"
#: code:addons/base/res/res_config.py:94
#, python-format
msgid "Couldn't find previous ir.actions.todo"
-msgstr ""
+msgstr "Couldn't find previous ir.actions.todo"
#. module: base
#: view:ir.actions.act_window:0
@@ -5761,7 +5795,7 @@ msgstr "Custom Shortcuts"
#. module: base
#: selection:base.language.install,lang:0
msgid "Vietnamese / Tiếng Việt"
-msgstr ""
+msgstr "Vietnamese / Tiếng Việt"
#. module: base
#: model:res.country,name:base.dz
@@ -5776,7 +5810,7 @@ msgstr "Belgium"
#. module: base
#: model:ir.model,name:base.model_osv_memory_autovacuum
msgid "osv_memory.autovacuum"
-msgstr ""
+msgstr "osv_memory.autovacuum"
#. module: base
#: field:base.language.export,lang:0
@@ -5809,30 +5843,30 @@ msgstr "Companies"
#. module: base
#: view:res.lang:0
msgid "%H - Hour (24-hour clock) [00,23]."
-msgstr ""
+msgstr "%H - Hour (24-hour clock) [00,23]."
#. module: base
#: model:ir.model,name:base.model_res_widget
msgid "res.widget"
-msgstr ""
+msgstr "res.widget"
#. module: base
#: code:addons/base/ir/ir_model.py:258
#, python-format
msgid "Model %s does not exist!"
-msgstr ""
+msgstr "Model %s does not exist!"
#. module: base
#: code:addons/base/res/res_lang.py:159
#, python-format
msgid "You cannot delete the language which is User's Preferred Language !"
-msgstr ""
+msgstr "You cannot delete the language which is User's Preferred Language !"
#. module: base
#: code:addons/fields.py:103
#, python-format
msgid "Not implemented get_memory method !"
-msgstr ""
+msgstr "Not implemented get_memory method !"
#. module: base
#: view:ir.actions.server:0
@@ -5879,7 +5913,7 @@ msgstr "Neutral Zone"
#. module: base
#: selection:base.language.install,lang:0
msgid "Hindi / हिंदी"
-msgstr ""
+msgstr "Hindi / हिंदी"
#. module: base
#: view:ir.model:0
@@ -5926,7 +5960,7 @@ msgstr "Window Actions"
#. module: base
#: view:res.lang:0
msgid "%I - Hour (12-hour clock) [01,12]."
-msgstr ""
+msgstr "%I - Hour (12-hour clock) [01,12]."
#. module: base
#: selection:publisher_warranty.contract.wizard,state:0
@@ -5964,12 +5998,14 @@ msgid ""
"View type: set to 'tree' for a hierarchical tree view, or 'form' for other "
"views"
msgstr ""
+"View type: set to 'tree' for a hierarchical tree view, or 'form' for other "
+"views"
#. module: base
#: code:addons/base/res/res_config.py:421
#, python-format
msgid "Click 'Continue' to configure the next addon..."
-msgstr ""
+msgstr "Click 'Continue' to configure the next addon..."
#. module: base
#: field:ir.actions.server,record_id:0
@@ -6010,7 +6046,7 @@ msgstr ""
#: code:addons/base/ir/ir_actions.py:629
#, python-format
msgid "Please specify server option --email-from !"
-msgstr ""
+msgstr "Please specify server option --email-from !"
#. module: base
#: field:base.language.import,name:0
@@ -6070,6 +6106,7 @@ msgid ""
"It gives the status if the tip has to be displayed or not when a user "
"executes an action"
msgstr ""
+"It shows if the tip is to be displayed or not when a user executes an action"
#. module: base
#: view:ir.model:0
@@ -6126,7 +6163,7 @@ msgstr "Code"
#. module: base
#: model:ir.model,name:base.model_res_config_installer
msgid "res.config.installer"
-msgstr ""
+msgstr "res.config.installer"
#. module: base
#: model:res.country,name:base.mc
@@ -6170,7 +6207,7 @@ msgstr "Sequence Codes"
#. module: base
#: selection:base.language.install,lang:0
msgid "Spanish (CO) / Español (CO)"
-msgstr ""
+msgstr "Spanish (CO) / Español (CO)"
#. module: base
#: view:base.module.configuration:0
@@ -6178,6 +6215,8 @@ msgid ""
"All pending configuration wizards have been executed. You may restart "
"individual wizards via the list of configuration wizards."
msgstr ""
+"All pending configuration wizards have been executed. You may restart "
+"individual wizards via the list of configuration wizards."
#. module: base
#: wizard_button:server.action.create,step_1,create:0
@@ -6187,7 +6226,7 @@ msgstr "Create"
#. module: base
#: view:ir.sequence:0
msgid "Current Year with Century: %(year)s"
-msgstr ""
+msgstr "Current Year with Century: %(year)s"
#. module: base
#: field:ir.exports,export_fields:0
@@ -6202,13 +6241,13 @@ msgstr "France"
#. module: base
#: model:ir.model,name:base.model_res_log
msgid "res.log"
-msgstr ""
+msgstr "res.log"
#. module: base
#: help:ir.translation,module:0
#: help:ir.translation,xml_id:0
msgid "Maps to the ir_model_data for which this translation is provided."
-msgstr ""
+msgstr "Maps to the ir_model_data for which this translation is provided."
#. module: base
#: view:workflow.activity:0
@@ -6302,7 +6341,7 @@ msgstr "Todo"
#. module: base
#: field:ir.attachment,datas:0
msgid "File Content"
-msgstr ""
+msgstr "File Content"
#. module: base
#: model:res.country,name:base.pa
@@ -6319,12 +6358,13 @@ msgstr "Ltd"
msgid ""
"The group that a user must have to be authorized to validate this transition."
msgstr ""
+"The group that a user must have to be authorized to validate this transition."
#. module: base
#: constraint:res.config.users:0
#: constraint:res.users:0
msgid "The chosen company is not in the allowed companies for this user"
-msgstr ""
+msgstr "The chosen company is not in the allowed companies for this user"
#. module: base
#: model:res.country,name:base.gi
@@ -6346,6 +6386,7 @@ msgstr "Pitcairn Island"
msgid ""
"We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)."
msgstr ""
+"We suggest reloading the menu tab to see the new menus (Ctrl+T then Ctrl+R)."
#. module: base
#: model:ir.actions.act_window,name:base.action_rule
@@ -6398,7 +6439,7 @@ msgstr "Search View"
#. module: base
#: sql_constraint:res.lang:0
msgid "The code of the language must be unique !"
-msgstr ""
+msgstr "The code of the language must be unique !"
#. module: base
#: model:ir.actions.act_window,name:base.action_attachment
@@ -6441,7 +6482,7 @@ msgstr "Write Access"
#. module: base
#: view:res.lang:0
msgid "%m - Month number [01,12]."
-msgstr ""
+msgstr "%m - Month number [01,12]."
#. module: base
#: field:res.bank,city:0
@@ -6499,7 +6540,7 @@ msgstr "English (US)"
#: view:ir.model.data:0
#: model:ir.ui.menu,name:base.ir_model_data_menu
msgid "Object Identifiers"
-msgstr ""
+msgstr "Object Identifiers"
#. module: base
#: model:ir.actions.act_window,help:base.action_partner_title_partner
@@ -6507,11 +6548,13 @@ msgid ""
"Manage the partner titles you want to have available in your system. The "
"partner titles is the legal status of the company: Private Limited, SA, etc."
msgstr ""
+"Manage the partner titles you want to have available in your system. The "
+"partner title is the legal status of the company: Private Limited, SA, etc."
#. module: base
#: view:base.language.export:0
msgid "To browse official translations, you can start with these links:"
-msgstr ""
+msgstr "To browse official translations, you can start with these links:"
#. module: base
#: code:addons/base/ir/ir_model.py:484
@@ -6520,6 +6563,8 @@ msgid ""
"You can not read this document (%s) ! Be sure your user belongs to one of "
"these groups: %s."
msgstr ""
+"You can not read this document (%s) ! Be sure your user belongs to one of "
+"these groups: %s."
#. module: base
#: view:res.bank:0
@@ -6538,7 +6583,7 @@ msgstr "Installed version"
#. module: base
#: selection:base.language.install,lang:0
msgid "Mongolian / монгол"
-msgstr ""
+msgstr "Mongolian / монгол"
#. module: base
#: model:res.country,name:base.mr
@@ -6553,7 +6598,7 @@ msgstr "ir.translation"
#. module: base
#: view:base.module.update:0
msgid "Module update result"
-msgstr ""
+msgstr "Module update result"
#. module: base
#: view:workflow.activity:0
@@ -6575,7 +6620,7 @@ msgstr "Parent Company"
#. module: base
#: selection:base.language.install,lang:0
msgid "Spanish (CR) / Español (CR)"
-msgstr ""
+msgstr "Spanish (CR) / Español (CR)"
#. module: base
#: field:res.currency.rate,rate:0
@@ -6615,6 +6660,9 @@ msgid ""
"for the currency: %s \n"
"at the date: %s"
msgstr ""
+"No rate found \n"
+"for the currency: %s \n"
+"at the date: %s"
#. module: base
#: model:ir.actions.act_window,help:base.action_ui_view_custom
@@ -6622,6 +6670,8 @@ msgid ""
"Customized views are used when users reorganize the content of their "
"dashboard views (via web client)"
msgstr ""
+"Customised views are used when users reorganise the content of their "
+"dashboard views (via web client)"
#. module: base
#: field:ir.model,name:0
@@ -6660,7 +6710,7 @@ msgstr "Icon"
#. module: base
#: help:ir.model.fields,model_id:0
msgid "The model this field belongs to"
-msgstr ""
+msgstr "The model this field belongs to"
#. module: base
#: model:res.country,name:base.mq
@@ -6670,7 +6720,7 @@ msgstr "Martinique (French)"
#. module: base
#: view:ir.sequence.type:0
msgid "Sequences Type"
-msgstr ""
+msgstr "Sequences Type"
#. module: base
#: model:ir.actions.act_window,name:base.res_request-act
@@ -6694,7 +6744,7 @@ msgstr "Or"
#: 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 "Client Logs"
#. module: base
#: model:res.country,name:base.al
@@ -6713,6 +6763,8 @@ msgid ""
"You cannot delete the language which is Active !\n"
"Please de-activate the language first."
msgstr ""
+"You cannot delete a language which is active !\n"
+"Please de-activate the language first."
#. module: base
#: view:base.language.install:0
@@ -6721,6 +6773,8 @@ msgid ""
"Please be patient, this operation may take a few minutes (depending on the "
"number of modules currently installed)..."
msgstr ""
+"Please be patient, this operation may take a few minutes (depending on the "
+"number of modules currently installed)..."
#. module: base
#: field:ir.ui.menu,child_id:0
@@ -6739,18 +6793,18 @@ msgstr "Problem in configuration `Record Id` in Server Action!"
#: code:addons/orm.py:2316
#, python-format
msgid "ValidateError"
-msgstr ""
+msgstr "ValidateError"
#. module: base
#: view:base.module.import:0
#: view:base.module.update:0
msgid "Open Modules"
-msgstr ""
+msgstr "Open Modules"
#. module: base
#: model:ir.actions.act_window,help:base.action_res_bank_form
msgid "Manage bank records you want to be used in the system."
-msgstr ""
+msgstr "Manage bank records you want to be used in the system."
#. module: base
#: view:base.module.import:0
@@ -6768,6 +6822,8 @@ msgid ""
"The path to the main report file (depending on Report Type) or NULL if the "
"content is in another field"
msgstr ""
+"The path to the main report file (depending on Report Type) or NULL if the "
+"content is in another field"
#. module: base
#: model:res.country,name:base.la
@@ -6794,6 +6850,8 @@ msgid ""
"The sum of the data (2nd field) is null.\n"
"We can't draw a pie chart !"
msgstr ""
+"The sum of the data (2nd field) is null.\n"
+"We can't draw a pie chart !"
#. module: base
#: model:ir.ui.menu,name:base.menu_lunch_reporting
@@ -6815,7 +6873,7 @@ msgstr "Togo"
#. module: base
#: selection:ir.module.module,license:0
msgid "Other Proprietary"
-msgstr ""
+msgstr "Other Proprietary"
#. module: base
#: selection:workflow.activity,kind:0
@@ -6826,7 +6884,7 @@ msgstr "Stop All"
#: code:addons/orm.py:412
#, python-format
msgid "The read_group method is not implemented on this object !"
-msgstr ""
+msgstr "The read_group method is not implemented on this object !"
#. module: base
#: view:ir.model.data:0
@@ -6846,7 +6904,7 @@ msgstr "Cascade"
#. module: base
#: field:workflow.transition,group_id:0
msgid "Group Required"
-msgstr ""
+msgstr "Group Required"
#. module: base
#: view:ir.actions.configuration.wizard:0
@@ -6869,17 +6927,19 @@ msgid ""
"Enable this if you want to execute missed occurences as soon as the server "
"restarts."
msgstr ""
+"Enable this if you want to execute missed occurences as soon as the server "
+"restarts."
#. module: base
#: view:base.module.upgrade:0
msgid "Start update"
-msgstr ""
+msgstr "Start update"
#. module: base
#: code:addons/base/publisher_warranty/publisher_warranty.py:144
#, python-format
msgid "Contract validation error"
-msgstr ""
+msgstr "Contract validation error"
#. module: base
#: field:res.country.state,name:0
@@ -6906,7 +6966,7 @@ msgstr "ir.actions.report.xml"
#. module: base
#: model:res.partner.title,shortcut:base.res_partner_title_miss
msgid "Mss"
-msgstr ""
+msgstr "Mss"
#. module: base
#: model:ir.model,name:base.model_ir_ui_view
@@ -6916,7 +6976,7 @@ msgstr "ir.ui.view"
#. module: base
#: constraint:res.partner:0
msgid "Error ! You can not create recursive associated members."
-msgstr ""
+msgstr "Error ! You can not create recursive associated members."
#. module: base
#: help:res.lang,code:0
@@ -6931,7 +6991,7 @@ msgstr "OpenERP Partners"
#. module: base
#: model:ir.ui.menu,name:base.menu_hr_manager
msgid "HR Manager Dashboard"
-msgstr ""
+msgstr "HR Manager Dashboard"
#. module: base
#: code:addons/base/module/module.py:253
@@ -6939,11 +6999,12 @@ msgstr ""
msgid ""
"Unable to install module \"%s\" because an external dependency is not met: %s"
msgstr ""
+"Unable to install module \"%s\" because an external dependency is not met: %s"
#. module: base
#: view:ir.module.module:0
msgid "Search modules"
-msgstr ""
+msgstr "Search modules"
#. module: base
#: model:res.country,name:base.by
@@ -6968,6 +7029,10 @@ msgid ""
"not connect to the system. You can assign them groups in order to give them "
"specific access to the applications they need to use in the system."
msgstr ""
+"Create and manage users that will connect to the system. Users can be "
+"deactivated should there be a period of time during which they will/should "
+"not connect to the system. You can assign them groups to give them specific "
+"access to the applications they need to use."
#. module: base
#: selection:res.request,priority:0
@@ -6983,13 +7048,13 @@ msgstr "Street2"
#. module: base
#: model:ir.actions.act_window,name:base.action_view_base_module_update
msgid "Module Update"
-msgstr ""
+msgstr "Module Update"
#. module: base
#: code:addons/base/module/wizard/base_module_upgrade.py:95
#, python-format
msgid "Following modules are not installed or unknown: %s"
-msgstr ""
+msgstr "Following modules are not installed or unknown: %s"
#. module: base
#: view:ir.cron:0
@@ -7018,7 +7083,7 @@ msgstr "Open Window"
#. module: base
#: field:ir.actions.act_window,auto_search:0
msgid "Auto Search"
-msgstr ""
+msgstr "Auto Search"
#. module: base
#: field:ir.actions.act_window,filter:0
@@ -7064,25 +7129,25 @@ msgstr "Load"
#: help:res.config.users,name:0
#: help:res.users,name:0
msgid "The new user's real name, used for searching and most listings"
-msgstr ""
+msgstr "The new user's real name, used for searching and most listings"
#. module: base
#: code:addons/osv.py:154
#: code:addons/osv.py:156
#, python-format
msgid "Integrity Error"
-msgstr ""
+msgstr "Integrity Error"
#. module: base
#: model:ir.model,name:base.model_ir_wizard_screen
msgid "ir.wizard.screen"
-msgstr ""
+msgstr "ir.wizard.screen"
#. module: base
#: code:addons/base/ir/ir_model.py:223
#, python-format
msgid "Size of the field can never be less than 1 !"
-msgstr ""
+msgstr "Size of the field can never be less than 1 !"
#. module: base
#: model:res.country,name:base.so
@@ -7092,7 +7157,7 @@ msgstr "Somalia"
#. module: base
#: selection:publisher_warranty.contract,state:0
msgid "Terminated"
-msgstr ""
+msgstr "Terminated"
#. module: base
#: model:res.partner.category,name:base.res_partner_category_13
@@ -7102,7 +7167,7 @@ msgstr "Important customers"
#. module: base
#: view:res.lang:0
msgid "Update Terms"
-msgstr ""
+msgstr "Update Terms"
#. module: base
#: field:partner.sms.send,mobile_to:0
@@ -7121,7 +7186,7 @@ msgstr "Arguments"
#: code:addons/orm.py:716
#, python-format
msgid "Database ID doesn't exist: %s : %s"
-msgstr ""
+msgstr "Database ID doesn't exist: %s : %s"
#. module: base
#: selection:ir.module.module,license:0
@@ -7137,7 +7202,7 @@ msgstr "GPL Version 3"
#: code:addons/orm.py:836
#, python-format
msgid "key '%s' not found in selection field '%s'"
-msgstr ""
+msgstr "key '%s' not found in selection field '%s'"
#. module: base
#: view:partner.wizard.ean.check:0
@@ -7148,7 +7213,7 @@ msgstr "Correct EAN13"
#: code:addons/orm.py:2317
#, python-format
msgid "The value \"%s\" for the field \"%s\" is not in the selection"
-msgstr ""
+msgstr "The value \"%s\" for the field \"%s\" is not in the selection"
#. module: base
#: field:res.partner,customer:0
diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po
new file mode 100644
index 00000000000..1df9844334b
--- /dev/null
+++ b/openerp/addons/base/i18n/kk.po
@@ -0,0 +1,9248 @@
+# Kazakh translation for openobject-server
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openobject-server package.
+# FIRST AUTHOR , 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-server\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2011-01-11 11:14+0000\n"
+"PO-Revision-Date: 2011-09-16 07:28+0000\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: Kazakh \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-17 04:54+0000\n"
+"X-Generator: Launchpad (build 13955)\n"
+
+#. module: base
+#: view:ir.filters:0
+#: field:ir.model.fields,domain:0
+#: field:ir.rule,domain:0
+#: field:ir.rule,domain_force:0
+#: field:res.partner.title,domain:0
+msgid "Domain"
+msgstr "Домен"
+
+#. module: base
+#: model:res.country,name:base.sh
+msgid "Saint Helena"
+msgstr "Әулие Елена ар."
+
+#. module: base
+#: view:ir.actions.report.xml:0
+msgid "Other Configuration"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "DateTime"
+msgstr "Күн мен уақыт"
+
+#. module: base
+#: code:addons/fields.py:534
+#, python-format
+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 ""
+
+#. module: base
+#: view:ir.values:0
+#: field:ir.values,meta_unpickle:0
+msgid "Metadata"
+msgstr "Метаақпарат"
+
+#. module: base
+#: field:ir.ui.view,arch:0
+#: field:ir.ui.view.custom,arch:0
+msgid "View Architecture"
+msgstr ""
+
+#. module: base
+#: field:base.language.import,code:0
+msgid "Code (eg:en__US)"
+msgstr ""
+
+#. module: base
+#: view:workflow:0
+#: view:workflow.activity:0
+#: field:workflow.activity,wkf_id:0
+#: field:workflow.instance,wkf_id:0
+#: field:workflow.transition,wkf_id:0
+#: field:workflow.workitem,wkf_id:0
+msgid "Workflow"
+msgstr ""
+
+#. module: base
+#: view:partner.sms.send:0
+msgid "SMS - Gateway: clickatell"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Hungarian / Magyar"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,select_level:0
+msgid "Not Searchable"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (VE) / Español (VE)"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,wkf_model_id:0
+msgid "Workflow On"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,display_menu_tip:0
+msgid "Display Menu Tips"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Created Views"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:485
+#, python-format
+msgid ""
+"You can not write in this document (%s) ! Be sure your user belongs to one "
+"of these groups: %s."
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,domain:0
+msgid ""
+"The optional domain to restrict possible values for relationship fields, "
+"specified as a Python expression defining a list of triplets. For example: "
+"[('color','=','red')]"
+msgstr ""
+
+#. module: base
+#: field:res.partner,ref:0
+msgid "Reference"
+msgstr "Сілтеме"
+
+#. module: base
+#: field:ir.actions.act_window,target:0
+msgid "Target Window"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:507
+#, python-format
+msgid "Warning!"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:304
+#, python-format
+msgid ""
+"Properties of base fields cannot be altered in this manner! Please modify "
+"them through Python code, preferably through a custom addon!"
+msgstr ""
+
+#. module: base
+#: code:addons/osv.py:133
+#, python-format
+msgid "Constraint Error"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_ui_view_custom
+msgid "ir.ui.view.custom"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sz
+msgid "Swaziland"
+msgstr "Свазиленд"
+
+#. module: base
+#: code:addons/orm.py:1993
+#: code:addons/orm.py:3653
+#, python-format
+msgid "created."
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_woodsuppliers0
+msgid "Wood Suppliers"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:303
+#, python-format
+msgid ""
+"Some installed modules depend on the module you plan to Uninstall :\n"
+" %s"
+msgstr ""
+
+#. module: base
+#: field:ir.sequence,number_increment:0
+msgid "Increment Number"
+msgstr ""
+
+#. 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 ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Inuktitut / ᐃᓄᒃᑎᑐᑦ"
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+msgid "Search Partner"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:132
+#, python-format
+msgid "\"smtp_server\" needs to be set to send mails to users"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_export_language.py:60
+#, python-format
+msgid "new"
+msgstr "жаңа"
+
+#. module: base
+#: field:ir.actions.report.xml,multi:0
+msgid "On multiple doc."
+msgstr ""
+
+#. module: base
+#: field:ir.module.category,module_nr:0
+msgid "Number of Modules"
+msgstr ""
+
+#. module: base
+#: help:multi_company.default,company_dest_id:0
+msgid "Company to store the current record"
+msgstr ""
+
+#. module: base
+#: field:res.partner.bank.type.field,size:0
+msgid "Max. Size"
+msgstr ""
+
+#. module: base
+#: field:res.partner.address,name:0
+msgid "Contact Name"
+msgstr "Контакт атауы"
+
+#. module: base
+#: code:addons/base/module/wizard/base_export_language.py:56
+#, python-format
+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 ""
+
+#. module: base
+#: sql_constraint:res.lang:0
+msgid "The name of the language must be unique !"
+msgstr ""
+
+#. module: base
+#: selection:res.request,state:0
+msgid "active"
+msgstr "белсенді"
+
+#. module: base
+#: field:ir.actions.wizard,wiz_name:0
+msgid "Wizard Name"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:2160
+#, python-format
+msgid "Invalid group_by"
+msgstr ""
+
+#. module: base
+#: field:res.partner,credit_limit:0
+msgid "Credit Limit"
+msgstr ""
+
+#. module: base
+#: field:ir.model.data,date_update:0
+msgid "Update Date"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+msgid "Owner"
+msgstr "Иесі"
+
+#. module: base
+#: field:ir.actions.act_window,src_model:0
+msgid "Source Object"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.todo:0
+msgid "Config Wizard Steps"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_ui_view_sc
+msgid "ir.ui.view_sc"
+msgstr ""
+
+#. module: base
+#: field:res.widget.user,widget_id:0
+#: field:res.widget.wizard,widgets_list:0
+msgid "Widget"
+msgstr ""
+
+#. module: base
+#: view:ir.model.access:0
+#: field:ir.model.access,group_id:0
+#: view:res.config.users:0
+msgid "Group"
+msgstr "Тобы"
+
+#. 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 ""
+
+#. module: base
+#: wizard_view:server.action.create,init:0
+#: wizard_field:server.action.create,init,type:0
+msgid "Select Action Type"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tv
+msgid "Tuvalu"
+msgstr "Тувалу"
+
+#. module: base
+#: selection:ir.model,state:0
+msgid "Custom Object"
+msgstr ""
+
+#. module: base
+#: field:res.lang,date_format:0
+msgid "Date Format"
+msgstr "Уақыт таңба пшімі"
+
+#. module: base
+#: field:res.bank,email:0
+#: field:res.partner.address,email:0
+msgid "E-Mail"
+msgstr "Эл.поштасы"
+
+#. module: base
+#: model:res.country,name:base.an
+msgid "Netherlands Antilles"
+msgstr "Нидерландияның Антиль аралдары"
+
+#. module: base
+#: code:addons/base/res/res_user.py:389
+#, python-format
+msgid ""
+"You can not remove the admin user as it is used internally for resources "
+"created by OpenERP (updates, module installation, ...)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gf
+msgid "French Guyana"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Greek / Ελληνικά"
+msgstr "Греция"
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Bosnian / bosanski jezik"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.report.xml,attachment_use:0
+msgid ""
+"If you check this, then the second time the user prints with same attachment "
+"name, it returns the previous report."
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:904
+#, python-format
+msgid "The read method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: help:res.lang,iso_code:0
+msgid "This ISO code is the name of po files to use for translations"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "Your system will be updated."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.todo,note:0
+#: selection:ir.property,type:0
+msgid "Text"
+msgstr "Мәтін"
+
+#. module: base
+#: field:res.country,name:0
+msgid "Country Name"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.co
+msgid "Colombia"
+msgstr "Колумбия"
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Schedule Upgrade"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:838
+#, python-format
+msgid "Key/value '%s' not found in selection field '%s'"
+msgstr ""
+
+#. module: base
+#: help:res.country,code:0
+msgid ""
+"The ISO country code in two chars.\n"
+"You can use this field for quick search."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pw
+msgid "Palau"
+msgstr "Палау"
+
+#. module: base
+#: view:res.partner:0
+msgid "Sales & Purchases"
+msgstr ""
+
+#. module: base
+#: view:ir.translation:0
+msgid "Untranslated"
+msgstr "Аударылмаған"
+
+#. module: base
+#: help:ir.actions.act_window,context:0
+msgid ""
+"Context dictionary as Python expression, empty by default (Default: {})"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_action_wizard
+#: view:ir.actions.wizard:0
+#: model:ir.ui.menu,name:base.menu_ir_action_wizard
+msgid "Wizards"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_miscellaneoussuppliers0
+msgid "Miscellaneous Suppliers"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:255
+#, python-format
+msgid "Custom fields must have a name that starts with 'x_' !"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,action_id:0
+msgid "Select the Action Window, Report, Wizard to be executed."
+msgstr ""
+
+#. module: base
+#: view:res.config.users:0
+msgid "New User"
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+msgid "Export done"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+msgid "Model Description"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,src_model:0
+msgid ""
+"Optional model name of the objects on which this action should be visible"
+msgstr ""
+
+#. module: base
+#: field:workflow.transition,trigger_expr_id:0
+msgid "Trigger Expression"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.jo
+msgid "Jordan"
+msgstr "Хордан"
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Certified"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.er
+msgid "Eritrea"
+msgstr "Эритрея"
+
+#. module: base
+#: view:res.config:0
+#: view:res.config.installer:0
+msgid "description"
+msgstr "сипаттамасы"
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_base_action_rule
+msgid "Automated Actions"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_actions
+msgid "ir.actions.actions"
+msgstr ""
+
+#. module: base
+#: view:partner.wizard.ean.check:0
+msgid "Want to check Ean ? "
+msgstr ""
+
+#. module: base
+#: field:ir.values,key2:0
+msgid "Event Type"
+msgstr "Оқиға түрі"
+
+#. module: base
+#: view:base.language.export:0
+msgid ""
+"OpenERP translations (core, modules, clients) are managed through "
+"Launchpad.net, our open source project management facility. We use their "
+"online interface to synchronize all translations efforts."
+msgstr ""
+
+#. module: base
+#: field:res.partner,title:0
+msgid "Partner Form"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Swedish / svenska"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.rs
+msgid "Serbia"
+msgstr "Сербия"
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Wizard View"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.kh
+msgid "Cambodia, Kingdom of"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_sequence_form
+#: view:ir.sequence:0
+#: model:ir.ui.menu,name:base.menu_ir_sequence_form
+#: model:ir.ui.menu,name:base.next_id_5
+msgid "Sequences"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_language_import
+msgid "Language Import"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_config_users
+msgid "res.config.users"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Albanian / Shqip"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_crm_config_opportunity
+msgid "Opportunities"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_language_export
+msgid "base.language.export"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pg
+msgid "Papua New Guinea"
+msgstr "Папуа - Жаңа Гвинея"
+
+#. module: base
+#: help:ir.actions.report.xml,report_type:0
+msgid "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..."
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_4
+msgid "Basic Partner"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid ","
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+msgid "My Partners"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.report.xml:0
+msgid "XML Report"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.es
+msgid "Spain"
+msgstr "Испания"
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_translation_export
+msgid "Import / Export"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,domain:0
+msgid ""
+"Optional domain filtering of the destination data, as a Python expression"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade
+#: model:ir.model,name:base.model_base_module_upgrade
+msgid "Module Upgrade"
+msgstr ""
+
+#. module: base
+#: view:res.config.users:0
+msgid ""
+"Groups are used to define access rights on objects and the visibility of "
+"screens and menus"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (UY) / Español (UY)"
+msgstr ""
+
+#. module: base
+#: field:res.partner,mobile:0
+#: field:res.partner.address,mobile:0
+msgid "Mobile"
+msgstr "Қалтафон"
+
+#. module: base
+#: model:res.country,name:base.om
+msgid "Oman"
+msgstr "Оман"
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_payterm_form
+#: model:ir.model,name:base.model_res_payterm
+msgid "Payment term"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nu
+msgid "Niue"
+msgstr "Ниуэ"
+
+#. module: base
+#: selection:ir.cron,interval_type:0
+msgid "Work Days"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "Other OSI Approved Licence"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,context_lang:0
+#: help:res.users,context_lang:0
+msgid ""
+"Sets the language for the user's user interface, when UI translations are "
+"available"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1043
+#, python-format
+msgid "The unlink method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.act_menu_create
+#: view:wizard.ir.model.menu.create:0
+msgid "Create Menu"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.in
+msgid "India"
+msgstr "Үндістан"
+
+#. module: base
+#: 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 ""
+
+#. module: base
+#: view:ir.values:0
+msgid "client_action_multi, client_action_relate"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ad
+msgid "Andorra, Principality of"
+msgstr ""
+
+#. module: base
+#: field:ir.module.category,child_ids:0
+#: field:res.partner.category,child_ids:0
+msgid "Child Categories"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_config_parameter
+msgid "ir.config_parameter"
+msgstr ""
+
+#. module: base
+#: selection:base.language.export,format:0
+msgid "TGZ Archive"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%B - Full month name."
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+#: field:ir.attachment,type:0
+#: field:ir.model,state:0
+#: field:ir.model.fields,state:0
+#: field:ir.property,type:0
+#: field:ir.server.object.lines,type:0
+#: field:ir.translation,type:0
+#: view:ir.ui.view:0
+#: view:ir.values:0
+#: field:ir.values,key:0
+#: view:res.partner:0
+#: view:res.partner.address:0
+msgid "Type"
+msgstr "Түрі"
+
+#. module: base
+#: code:addons/orm.py:210
+#, python-format
+msgid ""
+"Language with code \"%s\" is not defined in your system !\n"
+"Define it through the Administration menu."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gu
+msgid "Guam (USA)"
+msgstr "Гуам (АҚШ)"
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_hr_project
+msgid "Human Resources Dashboard"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:507
+#, python-format
+msgid "Setting empty passwords is not allowed for security reasons!"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.server,state:0
+#: selection:workflow.activity,kind:0
+msgid "Dummy"
+msgstr "Жай"
+
+#. module: base
+#: constraint:ir.ui.view:0
+msgid "Invalid XML for View Architecture!"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ky
+msgid "Cayman Islands"
+msgstr "Кайман ар-ы"
+
+#. module: base
+#: model:res.country,name:base.kr
+msgid "South Korea"
+msgstr "Корей Республикасы"
+
+#. 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 ""
+
+#. module: base
+#: code:addons/orm.py:4020
+#, python-format
+msgid "Record #%d of %s not found, cannot copy!"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,contributors:0
+msgid "Contributors"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "Char"
+msgstr "Симв."
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_form
+#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract
+msgid "Contracts"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (AR) / Español (AR)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ug
+msgid "Uganda"
+msgstr "Уганда"
+
+#. module: base
+#: field:ir.model.access,perm_unlink:0
+msgid "Delete Access"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ne
+msgid "Niger"
+msgstr "Нигер"
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Chinese (HK)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ba
+msgid "Bosnia-Herzegovina"
+msgstr "Босния және Герцоговина"
+
+#. module: base
+#: view:base.language.export:0
+msgid ""
+"To improve or expand the official translations, you should use directly "
+"Lauchpad's web interface (Rosetta). If you need to perform mass translation, "
+"Launchpad also allows uploading full .po files at once"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (GT) / Español (GT)"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid ""
+"%W - Week number of the year (Monday as the first day of the week) as a "
+"decimal number [00,53]. All days in a new year preceding the first Monday "
+"are considered to be in week 0."
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,website:0
+#: field:res.partner,website:0
+msgid "Website"
+msgstr "Веб сайт"
+
+#. module: base
+#: model:res.country,name:base.gs
+msgid "S. Georgia & S. Sandwich Isls."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.url,url:0
+msgid "Action URL"
+msgstr ""
+
+#. module: base
+#: field:base.module.import,module_name:0
+msgid "Module Name"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mh
+msgid "Marshall Islands"
+msgstr "Маршалл аралдары"
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:328
+#, python-format
+msgid "Changing the model of a field is forbidden!"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ht
+msgid "Haiti"
+msgstr "Гаити"
+
+#. module: base
+#: view:ir.ui.view:0
+#: selection:ir.ui.view,type:0
+msgid "Search"
+msgstr "Іздеу"
+
+#. module: base
+#: code:addons/osv.py:136
+#, python-format
+msgid ""
+"The operation cannot be completed, probably due to the following:\n"
+"- deletion: you may be trying to delete a record while other records still "
+"reference it\n"
+"- creation/update: a mandatory field is not correctly set"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid ""
+"2. Group-specific rules are combined together with a logical AND operator"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:206
+#, python-format
+msgid "Operation Canceled"
+msgstr ""
+
+#. module: base
+#: help:base.language.export,lang:0
+msgid "To export a new language, do not select a language."
+msgstr ""
+
+#. module: base
+#: view:res.request:0
+msgid "Request Date"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_hr_dasboard
+msgid "Dashboard"
+msgstr "Аспаптар панелі"
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_purchase_root
+msgid "Purchases"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.md
+msgid "Moldavia"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Features"
+msgstr "Мүмкіндіктер"
+
+#. module: base
+#: view:ir.module.module:0
+#: report:ir.module.reference.graph:0
+msgid "Version"
+msgstr "Нұсқа"
+
+#. module: base
+#: view:ir.model.access:0
+#: field:ir.model.access,perm_read:0
+#: view:ir.rule:0
+msgid "Read Access"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_exports
+msgid "ir.exports"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_update_translations.py:38
+#, python-format
+msgid "No language with code \"%s\" exists"
+msgstr ""
+
+#. module: base
+#: code:addons/base/publisher_warranty/publisher_warranty.py:163
+#, python-format
+msgid "Error during communication with the publisher warranty server."
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,email:0
+msgid ""
+"Provides the fields that will be used to fetch the email address, e.g. when "
+"you select the invoice, then `object.invoice_address_id.email` is the field "
+"which gives the correct address"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%Y - Year with century."
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "-"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract.wizard:0
+msgid ""
+"This wizard helps you register a publisher warranty contract in your OpenERP "
+"system. After the contract has been registered, you will be able to send "
+"issues directly to OpenERP."
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1744
+#, python-format
+msgid "The search method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: view:wizard.ir.model.menu.create:0
+msgid "Create _Menu"
+msgstr ""
+
+#. module: base
+#: field:res.payterm,name:0
+msgid "Payment Term (short name)"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_bank
+#: view:res.bank:0
+#: field:res.partner.bank,bank:0
+msgid "Bank"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_exports_line
+msgid "ir.exports.line"
+msgstr ""
+
+#. module: base
+#: help:base.language.install,overwrite:0
+msgid ""
+"If you check this box, your customized translations will be overwritten and "
+"replaced by the official ones."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_rml:0
+msgid "Main report file path"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_action_report_xml
+#: field:ir.module.module,reports_by_module:0
+#: model:ir.ui.menu,name:base.menu_ir_action_report_xml
+msgid "Reports"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window.view,multi:0
+#: help:ir.actions.report.xml,multi:0
+msgid ""
+"If set to true, the action will not be displayed on the right toolbar of a "
+"form view."
+msgstr ""
+
+#. module: base
+#: field:workflow,on_create:0
+msgid "On Create"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:607
+#, python-format
+msgid ""
+"'%s' contains too many dots. XML ids should not contain dots ! These are "
+"used to refer to other modules data, as in module.reference_id"
+msgstr ""
+
+#. module: base
+#: field:partner.sms.send,user:0
+#: field:res.config.users,login:0
+#: field:res.users,login:0
+msgid "Login"
+msgstr "Кіру"
+
+#. module: base
+#: view:ir.actions.server:0
+msgid ""
+"Access all the fields related to the current object using expressions, i.e. "
+"object.partner_id.name "
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_country_state
+msgid "Country state"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "Float"
+msgstr "Қалқымалы"
+
+#. module: base
+#: model:ir.model,name:base.model_res_request_link
+msgid "res.request.link"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.wizard,name:0
+msgid "Wizard Info"
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+#: model:ir.actions.act_window,name:base.action_wizard_lang_export
+#: model:ir.ui.menu,name:base.menu_wizard_lang_export
+msgid "Export Translation"
+msgstr ""
+
+#. module: base
+#: help:res.log,secondary:0
+msgid ""
+"Do not display this log if it belongs to the same object the user is working "
+"on"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tp
+msgid "East Timor"
+msgstr "Шығыс Тимор"
+
+#. module: base
+#: model:res.company,follow_up_msg:base.main_company
+msgid ""
+"Date : %(date)s\n"
+"\n"
+"Dear %(partner_name)s,\n"
+"\n"
+"Please find in attachment a reminder of all your unpaid invoices, for a "
+"total amount due of:\n"
+"\n"
+"%(followup_amount).2f %(company_currency)s\n"
+"\n"
+"Thanks,\n"
+"--\n"
+"%(user_signature)s\n"
+"%(company_name)s"
+msgstr ""
+
+#. module: base
+#: field:res.currency,accuracy:0
+msgid "Computational Accuracy"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Sinhalese / සිංහල"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_wizard_ir_model_menu_create_line
+msgid "wizard.ir.model.menu.create.line"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,res_id:0
+msgid "Attached ID"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Day: %(day)s"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mv
+msgid "Maldives"
+msgstr "Мальдив ар-ы"
+
+#. module: base
+#: help:ir.values,res_id:0
+msgid "Keep 0 if the action must appear on all resources."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_rule
+msgid "ir.rule"
+msgstr ""
+
+#. module: base
+#: selection:ir.cron,interval_type:0
+msgid "Days"
+msgstr "күн"
+
+#. module: base
+#: help:ir.actions.server,condition:0
+msgid ""
+"Condition that is to be tested before action is executed, e.g. "
+"object.list_price > object.cost_price"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/partner/partner.py:155
+#: code:addons/base/res/res_company.py:66
+#, python-format
+msgid " (copy)"
+msgstr " (көшірме)"
+
+#. module: base
+#: view:res.lang:0
+msgid "7. %H:%M:%S ==> 18:25:20"
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+#: view:res.partner.category:0
+#: field:res.partner.category,partner_ids:0
+msgid "Partners"
+msgstr ""
+
+#. module: base
+#: field:res.partner.category,parent_left:0
+msgid "Left parent"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.res_widget_act_window
+#: model:ir.ui.menu,name:base.menu_res_widget_act_window
+msgid "Homepage Widgets"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,message:0
+msgid ""
+"Specify the message. You can use the fields from the object. e.g. `Dear [[ "
+"object.partner_id.name ]]`"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,res_model:0
+msgid "Attached Model"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid "Domain Setup"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,trigger_name:0
+msgid "Trigger Name"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_model_access
+msgid "ir.model.access"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,priority:0
+#: field:res.request,priority:0
+#: field:res.request.link,priority:0
+msgid "Priority"
+msgstr "Маңыздылығы"
+
+#. module: base
+#: field:workflow.transition,act_from:0
+msgid "Source Activity"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Legend (for prefix, suffix)"
+msgstr ""
+
+#. module: base
+#: selection:ir.server.object.lines,type:0
+msgid "Formula"
+msgstr "Формула"
+
+#. module: base
+#: code:addons/base/res/res_user.py:389
+#, python-format
+msgid "Can not remove root user!"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mw
+msgid "Malawi"
+msgstr "Малави"
+
+#. module: base
+#: code:addons/base/res/res_user.py:51
+#: code:addons/base/res/res_user.py:413
+#, python-format
+msgid "%s (copy)"
+msgstr ""
+
+#. module: base
+#: field:res.partner.address,type:0
+msgid "Address Type"
+msgstr ""
+
+#. module: base
+#: view:ir.ui.menu:0
+msgid "Full Path"
+msgstr "Толық жолы"
+
+#. module: base
+#: view:res.request:0
+msgid "References"
+msgstr "References"
+
+#. module: base
+#: view:res.lang:0
+msgid ""
+"%U - Week number of the year (Sunday as the first day of the week) as a "
+"decimal number [00,53]. All days in a new year preceding the first Sunday "
+"are considered to be in week 0."
+msgstr ""
+
+#. module: base
+#: view:ir.ui.view:0
+msgid "Advanced"
+msgstr "Жетелеу"
+
+#. module: base
+#: model:res.country,name:base.fi
+msgid "Finland"
+msgstr "Финляндия"
+
+#. module: base
+#: selection:ir.actions.act_window,view_type:0
+#: selection:ir.actions.act_window.view,view_mode:0
+#: view:ir.ui.view:0
+#: selection:ir.ui.view,type:0
+#: selection:wizard.ir.model.menu.create.line,view_type:0
+msgid "Tree"
+msgstr "Бұтақ"
+
+#. module: base
+#: help:res.config.users,password:0
+msgid ""
+"Keep empty if you don't want the user to be able to connect on the system."
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Create / Write / Copy"
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+msgid "https://help.launchpad.net/Translations"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,view_mode:0
+msgid "View Mode"
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid ""
+"When using CSV format, please also check that the first line of your file is "
+"one of the following:"
+msgstr ""
+
+#. module: base
+#: code:addons/fields.py:114
+#, python-format
+msgid "Not implemented search_memory method !"
+msgstr ""
+
+#. module: base
+#: view:res.log:0
+msgid "Logs"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish / Español"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Korean (KP) / 한국어 (KP)"
+msgstr ""
+
+#. module: base
+#: view:base.module.update:0
+msgid ""
+"This wizard will scan all module repositories on the server side to detect "
+"newly added modules as well as any change to existing modules."
+msgstr ""
+
+#. module: base
+#: field:res.company,logo:0
+msgid "Logo"
+msgstr ""
+
+#. module: base
+#: view:res.partner.address:0
+msgid "Search Contact"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Uninstall (beta)"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.act_window,target:0
+#: selection:ir.actions.url,target:0
+msgid "New Window"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bs
+msgid "Bahamas"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/partner/partner.py:250
+#, python-format
+msgid ""
+"Couldn't generate the next id because some partners have an alphabetic id !"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+msgid "Attachment"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ie
+msgid "Ireland"
+msgstr ""
+
+#. module: base
+#: field:base.module.update,update:0
+msgid "Number of modules updated"
+msgstr ""
+
+#. module: base
+#: code:addons/fields.py:100
+#, python-format
+msgid "Not implemented set_memory method !"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+msgid "Workflow Activity"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid ""
+"Example: GLOBAL_RULE_1 AND GLOBAL_RULE_2 AND ( (GROUP_A_RULE_1 AND "
+"GROUP_A_RULE_2) OR (GROUP_B_RULE_1 AND GROUP_B_RULE_2) )"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_ui_view
+msgid ""
+"Views allows you to personalize each view of OpenERP. You can add new "
+"fields, move fields, rename them or delete the ones that you do not need."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,groups_id:0
+#: model:ir.actions.act_window,name:base.action_res_groups
+#: view:ir.actions.report.xml:0
+#: field:ir.actions.report.xml,groups_id:0
+#: view:ir.actions.todo:0
+#: field:ir.actions.todo,groups_id:0
+#: field:ir.actions.wizard,groups_id:0
+#: view:ir.model:0
+#: field:ir.model.fields,groups:0
+#: field:ir.rule,groups:0
+#: view:ir.ui.menu:0
+#: field:ir.ui.menu,groups_id:0
+#: model:ir.ui.menu,name:base.menu_action_res_groups
+#: field:res.config.users,groups_id:0
+#: view:res.groups:0
+#: view:res.users:0
+#: field:res.users,groups_id:0
+msgid "Groups"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (CL) / Español (CL)"
+msgstr ""
+
+#. module: base
+#: view:res.config.users:0
+msgid ""
+"Create additional users and assign them groups that will allow them to have "
+"access to selected functionalities within the system. Click on 'Done' if you "
+"do not wish to add more users at this stage, you can always do this later."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bz
+msgid "Belize"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ge
+msgid "Georgia"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pl
+msgid "Poland"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,view_mode:0
+msgid ""
+"Comma-separated list of allowed view modes, such as 'form', 'tree', "
+"'calendar', etc. (Default: tree,form)"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3147
+#, python-format
+msgid "A document was modified since you last viewed it (%s:%d)"
+msgstr ""
+
+#. module: base
+#: view:workflow:0
+msgid "Workflow Editor"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,state:0
+#: selection:ir.module.module.dependency,state:0
+msgid "To be removed"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_sequence
+msgid "ir.sequence"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,expression:0
+msgid ""
+"Enter the field/expression that will return the list. E.g. select the sale "
+"order in Object, and you can have loop on the sales order line. Expression = "
+"`object.order_line`."
+msgstr ""
+
+#. module: base
+#: field:ir.property,fields_id:0
+#: selection:ir.translation,type:0
+#: field:multi_company.default,field_id:0
+msgid "Field"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid "Groups (no group = global)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.fo
+msgid "Faroe Islands"
+msgstr ""
+
+#. module: base
+#: selection:res.config.users,view:0
+#: selection:res.config.view,view:0
+#: selection:res.users,view:0
+msgid "Simplified"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.st
+msgid "Saint Tome (Sao Tome) and Principe"
+msgstr ""
+
+#. module: base
+#: selection:res.partner.address,type:0
+msgid "Invoice"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Portugese (BR) / Português (BR)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bb
+msgid "Barbados"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mg
+msgid "Madagascar"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:96
+#, python-format
+msgid ""
+"The Object name must start with x_ and not contain any special character !"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.configuration.wizard,note:0
+msgid "Next Wizard"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_menu_admin
+#: view:ir.ui.menu:0
+#: field:ir.ui.menu,name:0
+msgid "Menu"
+msgstr ""
+
+#. module: base
+#: field:res.currency,rate:0
+msgid "Current Rate"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view.custom,ref_id:0
+msgid "Original View"
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "Action To Launch"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.url,target:0
+msgid "Action Target"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ai
+msgid "Anguilla"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view_sc,name:0
+msgid "Shortcut Name"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,limit:0
+msgid "Default limit for the list view"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,write_id:0
+msgid ""
+"Provide the field name that the record id refers to for the write operation. "
+"If it is empty it will refer to the active id of the object."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.zw
+msgid "Zimbabwe"
+msgstr ""
+
+#. module: base
+#: view:base.module.update:0
+msgid "Please be patient, as this operation may take a few seconds..."
+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 ""
+
+#. module: base
+#: field:ir.actions.server,email:0
+msgid "Email Address"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "French (BE) / Français (BE)"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+#: field:workflow.activity,action_id:0
+msgid "Server Action"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tt
+msgid "Trinidad and Tobago"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lv
+msgid "Latvia"
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "Values"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Field Mappings"
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+msgid "Export Translations"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_custom
+msgid "Customization"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.py
+msgid "Paraguay"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_act_window_close
+msgid "ir.actions.act_window_close"
+msgstr ""
+
+#. module: base
+#: field:ir.server.object.lines,col1:0
+msgid "Destination"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lt
+msgid "Lithuania"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_view_partner_clear_ids
+#: model:ir.model,name:base.model_partner_clear_ids
+#: view:partner.clear.ids:0
+msgid "Clear IDs"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,model:0
+msgid ""
+"Name of object whose function will be called when this scheduler will run. "
+"e.g. 'res.partener'"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1040
+#, python-format
+msgid "The perm_read method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%y - Year without century [00,99]."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.si
+msgid "Slovenia"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pk
+msgid "Pakistan"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1350
+#, python-format
+msgid "Invalid Object Architecture!"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_email_gateway_form
+msgid "Messages"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:303
+#: code:addons/base/ir/ir_model.py:317
+#: code:addons/base/ir/ir_model.py:319
+#: code:addons/base/ir/ir_model.py:321
+#: code:addons/base/ir/ir_model.py:328
+#: code:addons/base/ir/ir_model.py:331
+#: code:addons/base/module/wizard/base_update_translations.py:38
+#, python-format
+msgid "Error!"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%p - Equivalent of either AM or PM."
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Iteration Actions"
+msgstr ""
+
+#. module: base
+#: help:multi_company.default,company_id:0
+msgid "Company where the user is connected"
+msgstr ""
+
+#. module: base
+#: field:publisher_warranty.contract,date_stop:0
+msgid "Ending Date"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nz
+msgid "New Zealand"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3366
+#, python-format
+msgid ""
+"One of the records you are trying to modify has already been deleted "
+"(Document type: %s)."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_country
+msgid ""
+"Display and manage the list of all countries that can be assigned to your "
+"partner records. You can create or delete countries to make sure the ones "
+"you are working on will be maintained."
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_7
+msgid "Openstuff.net"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nf
+msgid "Norfolk Island"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Korean (KR) / 한국어 (KR)"
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,model:0
+msgid "The technical name of the model this field belongs to"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,action_id:0
+#: selection:ir.actions.server,state:0
+msgid "Client Action"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bd
+msgid "Bangladesh"
+msgstr ""
+
+#. module: base
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr ""
+
+#. module: base
+#: selection:publisher_warranty.contract,state:0
+msgid "Valid"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "XSL"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:322
+#, python-format
+msgid "Can not upgrade module '%s'. It is not installed."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cu
+msgid "Cuba"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner_event
+msgid "res.partner.event"
+msgstr ""
+
+#. module: base
+#: model:res.widget,title:base.facebook_widget
+msgid "Facebook"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.am
+msgid "Armenia"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_property_form
+#: model:ir.ui.menu,name:base.menu_ir_property_form_all
+msgid "Configuration Parameters"
+msgstr ""
+
+#. module: base
+#: constraint:ir.cron:0
+msgid "Invalid arguments"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.se
+msgid "Sweden"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.act_window.view,view_mode:0
+#: selection:ir.ui.view,type:0
+#: selection:wizard.ir.model.menu.create.line,view_type:0
+msgid "Gantt"
+msgstr ""
+
+#. module: base
+#: view:ir.property:0
+msgid "Property"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner_bank_type
+#: view:res.partner.bank.type:0
+msgid "Bank Account Type"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,config_logo:0
+#: field:base.language.import,config_logo:0
+#: field:base.language.install,config_logo:0
+#: field:base.module.import,config_logo:0
+#: field:base.module.update,config_logo:0
+#: field:base.update.translations,config_logo:0
+#: field:ir.actions.configuration.wizard,config_logo:0
+#: field:ir.wizard.screen,config_logo:0
+#: field:publisher_warranty.contract.wizard,config_logo:0
+#: field:res.config,config_logo:0
+#: field:res.config.installer,config_logo:0
+#: field:res.config.users,config_logo:0
+#: field:res.config.view,config_logo:0
+msgid "Image"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Iteration Action Configuration"
+msgstr ""
+
+#. module: base
+#: selection:publisher_warranty.contract,state:0
+msgid "Canceled"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.at
+msgid "Austria"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,state:0
+#: selection:base.module.import,state:0
+#: selection:base.module.update,state:0
+msgid "done"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.act_window.view,view_mode:0
+#: model:ir.ui.menu,name:base.menu_calendar_configuration
+#: selection:ir.ui.view,type:0
+#: selection:wizard.ir.model.menu.create.line,view_type:0
+msgid "Calendar"
+msgstr ""
+
+#. module: base
+#: field:res.partner.address,partner_id:0
+msgid "Partner Name"
+msgstr ""
+
+#. module: base
+#: field:workflow.activity,signal_send:0
+msgid "Signal (subflow.*)"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_17
+msgid "HR sector"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3817
+#, python-format
+msgid ""
+"Invalid \"order\" specified. A valid \"order\" specification is a comma-"
+"separated list of valid field names (optionally followed by asc/desc for the "
+"direction)"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_module_module_dependency
+msgid "Module dependency"
+msgstr ""
+
+#. module: base
+#: selection:publisher_warranty.contract.wizard,state:0
+msgid "Draft"
+msgstr ""
+
+#. module: base
+#: selection:res.config.users,view:0
+#: selection:res.config.view,view:0
+#: selection:res.users,view:0
+msgid "Extended"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_partner_title_contact
+msgid ""
+"Manage the contact titles you want to have available in your system and the "
+"way you want to print them in letters and other documents. Some example: "
+"Mr., Mrs. "
+msgstr ""
+
+#. module: base
+#: field:res.company,rml_footer1:0
+msgid "Report Footer 1"
+msgstr ""
+
+#. module: base
+#: field:res.company,rml_footer2:0
+msgid "Report Footer 2"
+msgstr ""
+
+#. module: base
+#: view:ir.model.access:0
+#: view:res.groups:0
+#: field:res.groups,model_access:0
+msgid "Access Controls"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+#: field:ir.module.module,dependencies_id:0
+msgid "Dependencies"
+msgstr ""
+
+#. module: base
+#: field:multi_company.default,company_id:0
+msgid "Main Company"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,web_icon_hover:0
+msgid "Web Icon File (hover)"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid ""
+"If you use a formula type, use a python expression using the variable "
+"'object'."
+msgstr ""
+
+#. module: base
+#: field:res.partner.address,birthdate:0
+msgid "Birthdate"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_title_contact
+#: model:ir.ui.menu,name:base.menu_partner_title_contact
+msgid "Contact Titles"
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid ""
+"Please double-check that the file encoding is set to UTF-8 (sometimes called "
+"Unicode) when the translator exports it."
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (DO) / Español (DO)"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_workflow_activity
+msgid "workflow.activity"
+msgstr ""
+
+#. module: base
+#: help:ir.ui.view_sc,res_id:0
+msgid ""
+"Reference of the target resource, whose model/table depends on the 'Resource "
+"Name' field."
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,select_level:0
+msgid "Searchable"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.uy
+msgid "Uruguay"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Finnish / Suomi"
+msgstr ""
+
+#. module: base
+#: field:ir.rule,perm_write:0
+msgid "Apply For Write"
+msgstr ""
+
+#. module: base
+#: field:ir.sequence,prefix:0
+msgid "Prefix"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "German / Deutsch"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,trigger_name:0
+msgid "Select the Signal name that is to be used as the trigger."
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Fields Mapping"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Portugese / Português"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,name:base.res_partner_title_sir
+msgid "Sir"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1622
+#, python-format
+msgid "There is no view of type '%s' defined for the structure!"
+msgstr ""
+
+#. module: base
+#: field:ir.default,ref_id:0
+msgid "ID Ref."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.server,name:base.action_start_configurator
+#: model:ir.ui.menu,name:base.menu_view_base_module_configuration
+msgid "Start Configuration"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mt
+msgid "Malta"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,fields_lines:0
+msgid "Field Mappings."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_module_module
+#: view:ir.model.data:0
+#: field:ir.model.data,module:0
+#: view:ir.module.module:0
+#: field:ir.module.module.dependency,module_id:0
+#: report:ir.module.reference.graph:0
+#: field:ir.translation,module:0
+msgid "Module"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,description:0
+#: view:ir.module.module:0
+#: field:ir.module.module,description:0
+#: field:res.partner.bank,name:0
+#: view:res.partner.event:0
+#: field:res.partner.event,description:0
+#: view:res.request:0
+msgid "Description"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_workflow_instance_form
+#: model:ir.ui.menu,name:base.menu_workflow_instance
+msgid "Instances"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.aq
+msgid "Antarctica"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,auto:0
+msgid "Custom python parser"
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid "_Import"
+msgstr ""
+
+#. module: base
+#: view:res.partner.canal:0
+msgid "Channel"
+msgstr ""
+
+#. module: base
+#: field:res.lang,grouping:0
+msgid "Separator Format"
+msgstr ""
+
+#. module: base
+#: selection:publisher_warranty.contract,state:0
+msgid "Unvalidated"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.next_id_9
+msgid "Database Structure"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_mass_mail
+#: model:ir.model,name:base.model_partner_wizard_spam
+#: view:partner.wizard.spam:0
+msgid "Mass Mailing"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.yt
+msgid "Mayotte"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_actions.py:597
+#, python-format
+msgid "Please specify an action to launch !"
+msgstr ""
+
+#. module: base
+#: view:res.payterm:0
+msgid "Payment Term"
+msgstr ""
+
+#. module: base
+#: selection:res.lang,direction:0
+msgid "Right-to-Left"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+#: model:ir.actions.act_window,name:base.actions_ir_filters_view
+#: view:ir.filters:0
+#: model:ir.model,name:base.model_ir_filters
+#: model:ir.ui.menu,name:base.menu_ir_filters
+msgid "Filters"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:758
+#, python-format
+msgid "Please check that all your lines have %d columns."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_cron_act
+#: view:ir.cron:0
+#: model:ir.ui.menu,name:base.menu_ir_cron_act
+msgid "Scheduled Actions"
+msgstr ""
+
+#. module: base
+#: field:res.partner.address,title:0
+#: field:res.partner.title,name:0
+#: field:res.widget,title:0
+msgid "Title"
+msgstr ""
+
+#. module: base
+#: help:ir.property,res_id:0
+msgid "If not set, acts as a default value for new resources"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3448
+#, python-format
+msgid "Recursivity Detected."
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:262
+#, python-format
+msgid "Recursion error in modules dependencies !"
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+msgid ""
+"This wizard helps you add a new language to your OpenERP system. After "
+"loading a new language it becomes available as default interface language "
+"for users and partners."
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+msgid "Create a Menu"
+msgstr ""
+
+#. module: base
+#: help:res.partner,vat:0
+msgid ""
+"Value Added Tax number. Check the box if the partner is subjected to the "
+"VAT. Used by the VAT legal statement."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_maintenance_contract
+msgid "maintenance.contract"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ru
+msgid "Russian Federation"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Urdu / اردو"
+msgstr ""
+
+#. module: base
+#: field:res.company,name:0
+msgid "Company Name"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_country
+#: model:ir.ui.menu,name:base.menu_country_partner
+msgid "Countries"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "RML (deprecated - use Report)"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid "Record rules"
+msgstr ""
+
+#. module: base
+#: view:ir.property:0
+msgid "Field Information"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.todo:0
+msgid "Search Actions"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_view_partner_wizard_ean_check
+#: view:partner.wizard.ean.check:0
+msgid "Ean check"
+msgstr ""
+
+#. module: base
+#: field:res.partner,vat:0
+msgid "VAT"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "12. %w ==> 5 ( Friday is the 6th day)"
+msgstr ""
+
+#. module: base
+#: constraint:res.partner.category:0
+msgid "Error ! You can not create recursive categories."
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%x - Appropriate date representation."
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%d - Day of the month [01,31]."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tj
+msgid "Tajikistan"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "GPL-2 or later version"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,shortcut:base.res_partner_title_sir
+msgid "M."
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:429
+#, python-format
+msgid ""
+"Can not create the module file:\n"
+" %s"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:2973
+#, python-format
+msgid ""
+"Operation prohibited by access rules, or performed on an already deleted "
+"document (Operation: read, Document type: %s)."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nr
+msgid "Nauru"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:200
+#, python-format
+msgid "The certificate ID of the module must be unique !"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_property
+msgid "ir.property"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.act_window,view_type:0
+#: selection:ir.actions.act_window.view,view_mode:0
+#: view:ir.ui.view:0
+#: selection:ir.ui.view,type:0
+#: selection:wizard.ir.model.menu.create.line,view_type:0
+msgid "Form"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.me
+msgid "Montenegro"
+msgstr ""
+
+#. module: base
+#: view:ir.cron:0
+msgid "Technical Data"
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+#: field:res.partner,category_id:0
+msgid "Categories"
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid ""
+"If you need another language than the official ones available, you can "
+"import a language pack from here. Other OpenERP languages than the official "
+"ones can be found on launchpad."
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+#: selection:ir.module.module,state:0
+#: selection:ir.module.module.dependency,state:0
+msgid "To be upgraded"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ly
+msgid "Libya"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cf
+msgid "Central African Republic"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.li
+msgid "Liechtenstein"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_partner_sms_send
+#: view:partner.sms.send:0
+msgid "Send SMS"
+msgstr ""
+
+#. module: base
+#: field:res.partner,ean13:0
+msgid "EAN13"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1622
+#, python-format
+msgid "Invalid Architecture!"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pt
+msgid "Portugal"
+msgstr ""
+
+#. module: base
+#: sql_constraint:ir.model.data:0
+msgid ""
+"You cannot have multiple records with the same id for the same module !"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,certificate:0
+msgid "Quality Certificate"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "6. %d, %m ==> 05, 12"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,date:0
+#: field:res.users,date:0
+msgid "Last Connection"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,help:0
+msgid "Action description"
+msgstr ""
+
+#. module: base
+#: help:res.partner,customer:0
+msgid "Check this box if the partner is a customer."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.res_lang_act_window
+#: model:ir.model,name:base.model_res_lang
+#: model:ir.ui.menu,name:base.menu_res_lang_act_window
+#: view:res.lang:0
+msgid "Languages"
+msgstr ""
+
+#. module: base
+#: selection:workflow.activity,join_mode:0
+#: selection:workflow.activity,split_mode:0
+msgid "Xor"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ec
+msgid "Ecuador"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_export_language.py:52
+#, python-format
+msgid ""
+"Save this document to a .CSV file and open it with your favourite "
+"spreadsheet software. The file encoding is UTF-8. You have to translate the "
+"latest column before reimporting it."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_customer_form
+#: model:ir.actions.act_window,name:base.action_partner_form
+#: model:ir.ui.menu,name:base.menu_partner_form
+#: view:res.partner:0
+msgid "Customers"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.au
+msgid "Australia"
+msgstr ""
+
+#. module: base
+#: help:res.partner,lang:0
+msgid ""
+"If the selected language is loaded in the system, all documents related to "
+"this partner will be printed in this language. If not, it will be english."
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Menu :"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,state:0
+msgid "Base Field"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract:0
+msgid "Validate"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.todo,restart:0
+msgid "Restart"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_sxw_content:0
+#: field:ir.actions.report.xml,report_sxw_content_data:0
+msgid "SXW content"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.wizard:0
+#: field:wizard.ir.model.menu.create.line,wizard_id:0
+msgid "Wizard"
+msgstr ""
+
+#. module: base
+#: view:ir.cron:0
+msgid "Action to Trigger"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:136
+#, python-format
+msgid "\"email_from\" needs to be set to send welcome mails to users"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Constraint"
+msgstr ""
+
+#. module: base
+#: selection:ir.values,key:0
+#: selection:res.partner.address,type:0
+msgid "Default"
+msgstr ""
+
+#. module: base
+#: view:ir.model.fields:0
+#: field:ir.model.fields,required:0
+#: field:res.partner.bank.type.field,required:0
+msgid "Required"
+msgstr ""
+
+#. module: base
+#: view:res.users:0
+msgid "Default Filters"
+msgstr ""
+
+#. module: base
+#: field:res.request.history,name:0
+msgid "Summary"
+msgstr ""
+
+#. module: base
+#: field:multi_company.default,expression:0
+msgid "Expression"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,subject:0
+msgid ""
+"Specify the subject. You can use fields from the object, e.g. `Hello [[ "
+"object.partner_id.name ]]`"
+msgstr ""
+
+#. module: base
+#: view:res.company:0
+msgid "Header/Footer"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,help:0
+msgid ""
+"Optional help text for the users with a description of the target view, such "
+"as its usage and purpose."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.va
+msgid "Holy See (Vatican City State)"
+msgstr ""
+
+#. module: base
+#: field:base.module.import,module_file:0
+msgid "Module .ZIP file"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view,xml_id:0
+msgid "XML ID"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_16
+msgid "Telecom sector"
+msgstr ""
+
+#. module: base
+#: field:workflow.transition,trigger_model:0
+msgid "Trigger Object"
+msgstr ""
+
+#. module: base
+#: view:res.users:0
+msgid "Current Activity"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+#: field:workflow.activity,in_transitions:0
+msgid "Incoming Transitions"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sr
+msgid "Suriname"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.marketing_menu
+msgid "Marketing"
+msgstr ""
+
+#. module: base
+#: view:res.partner.bank:0
+#: model:res.partner.bank.type,name:base.bank_normal
+msgid "Bank account"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (HN) / Español (HN)"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence.type:0
+msgid "Sequence Type"
+msgstr ""
+
+#. module: base
+#: view:ir.ui.view.custom:0
+msgid "Customized Architecture"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,license:0
+msgid "License"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,url:0
+msgid "Url"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.todo,restart:0
+msgid "Always"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "SQL Constraint"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,srcmodel_id:0
+#: field:ir.model.fields,model_id:0
+msgid "Model"
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+msgid ""
+"The selected language has been successfully installed. You must change the "
+"preferences of the user and open a new menu to view the changes."
+msgstr ""
+
+#. module: base
+#: sql_constraint:ir.config_parameter:0
+msgid "Key must be unique."
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+msgid "Open a Window"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gq
+msgid "Equatorial Guinea"
+msgstr ""
+
+#. module: base
+#: view:base.module.import:0
+#: model:ir.actions.act_window,name:base.action_view_base_module_import
+msgid "Module Import"
+msgstr ""
+
+#. module: base
+#: field:res.bank,zip:0
+#: field:res.partner.address,zip:0
+#: field:res.partner.bank,zip:0
+msgid "Zip"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+#: field:ir.module.module,author:0
+msgid "Author"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mk
+msgid "FYROM"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%c - Appropriate date and time representation."
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_config.py:422
+#, python-format
+msgid ""
+"Your database is now fully configured.\n"
+"\n"
+"Click 'Continue' and enjoy your OpenERP experience..."
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Hebrew / עִבְרִי"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bo
+msgid "Bolivia"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gh
+msgid "Ghana"
+msgstr ""
+
+#. module: base
+#: field:res.lang,direction:0
+msgid "Direction"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+#: model:ir.actions.act_window,name:base.action_ui_view
+#: field:ir.actions.act_window,view_ids:0
+#: field:ir.actions.act_window,views:0
+#: field:ir.module.module,views_by_module:0
+#: model:ir.ui.menu,name:base.menu_action_ui_view
+#: view:ir.ui.view:0
+msgid "Views"
+msgstr ""
+
+#. module: base
+#: view:res.groups:0
+#: field:res.groups,rule_groups:0
+msgid "Rules"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:216
+#, python-format
+msgid "You try to remove a module that is installed or will be installed"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "The selected modules have been updated / installed !"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (PR) / Español (PR)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gt
+msgid "Guatemala"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_workflow_form
+#: model:ir.ui.menu,name:base.menu_low_workflow
+#: model:ir.ui.menu,name:base.menu_workflow
+#: model:ir.ui.menu,name:base.menu_workflow_root
+msgid "Workflows"
+msgstr ""
+
+#. module: base
+#: field:ir.translation,xml_id:0
+msgid "XML Id"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_config_user_form
+msgid "Create Users"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner_title
+msgid "res.partner.title"
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "tree_but_action, client_print_multi"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_retailers0
+msgid "Retailers"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,priority:0
+msgid ""
+"0=Very Urgent\n"
+"10=Not urgent"
+msgstr ""
+
+#. module: base
+#: view:res.config:0
+#: view:res.config.installer:0
+msgid "Skip"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ls
+msgid "Lesotho"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:114
+#, python-format
+msgid "You can not remove the model '%s' !"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ke
+msgid "Kenya"
+msgstr ""
+
+#. module: base
+#: view:res.partner.event:0
+msgid "Event"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_custom_reports
+msgid "Custom Reports"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Abkhazian / аҧсуа"
+msgstr ""
+
+#. module: base
+#: view:base.module.configuration:0
+msgid "System Configuration Done"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:929
+#, python-format
+msgid "Error occurred while validating the field(s) %s: %s"
+msgstr ""
+
+#. module: base
+#: view:ir.property:0
+msgid "Generic"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sm
+msgid "San Marino"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bm
+msgid "Bermuda"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pe
+msgid "Peru"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,on_delete:0
+msgid "Set NULL"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bj
+msgid "Benin"
+msgstr ""
+
+#. module: base
+#: code:addons/base/publisher_warranty/publisher_warranty.py:281
+#, python-format
+msgid "That contract is already registered in the system."
+msgstr ""
+
+#. module: base
+#: help:ir.sequence,suffix:0
+msgid "Suffix value of the record for the sequence"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (PY) / Español (PY)"
+msgstr ""
+
+#. module: base
+#: field:ir.config_parameter,key:0
+msgid "Key"
+msgstr ""
+
+#. module: base
+#: field:res.company,rml_header:0
+msgid "RML Header"
+msgstr ""
+
+#. module: base
+#: field:partner.sms.send,app_id:0
+msgid "API ID"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:486
+#, python-format
+msgid ""
+"You can not create this document (%s) ! Be sure your user belongs to one of "
+"these groups: %s."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mu
+msgid "Mauritius"
+msgstr ""
+
+#. module: base
+#: view:ir.model.access:0
+#: view:ir.rule:0
+msgid "Full Access"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+#: view:ir.actions.report.xml:0
+#: view:ir.actions.wizard:0
+#: view:ir.model.fields:0
+#: model:ir.ui.menu,name:base.menu_security
+msgid "Security"
+msgstr ""
+
+#. module: base
+#: model:res.widget,title:base.openerp_favorites_twitter_widget
+msgid "OpenERP Favorites"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.za
+msgid "South Africa"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+#: selection:ir.module.module,state:0
+#: selection:ir.module.module.dependency,state:0
+msgid "Installed"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Ukrainian / українська"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_translation
+#: model:ir.ui.menu,name:base.menu_action_translation
+msgid "Translation Terms"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sn
+msgid "Senegal"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.hu
+msgid "Hungary"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_groups
+msgid "res.groups"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.br
+msgid "Brazil"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%M - Minute [00,59]."
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "Affero GPL-3"
+msgstr ""
+
+#. module: base
+#: field:ir.sequence,number_next:0
+msgid "Next Number"
+msgstr ""
+
+#. module: base
+#: help:workflow.transition,condition:0
+msgid "Expression to be satisfied if we want the transition done."
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (PA) / Español (PA)"
+msgstr ""
+
+#. module: base
+#: view:res.currency:0
+#: field:res.currency,rate_ids:0
+msgid "Rates"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sy
+msgid "Syria"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "======================================================"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,mobile:0
+msgid ""
+"Provides fields that be used to fetch the mobile number, e.g. you select the "
+"invoice, then `object.invoice_address_id.mobile` is the field which gives "
+"the correct mobile number"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "System update completed"
+msgstr ""
+
+#. module: base
+#: selection:res.request,state:0
+msgid "draft"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+#: field:res.currency,date:0
+#: field:res.currency.rate,name:0
+#: field:res.partner,date:0
+#: field:res.partner.event,date:0
+#: field:res.request,date_sent:0
+msgid "Date"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_sxw:0
+msgid "SXW path"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+msgid "Data"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,parent_id:0
+#: field:wizard.ir.model.menu.create,menu_id:0
+msgid "Parent Menu"
+msgstr ""
+
+#. module: base
+#: field:ir.rule,perm_unlink:0
+msgid "Apply For Delete"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:319
+#, python-format
+msgid "Cannot rename column to %s, because that column already exists!"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+msgid "Attached To"
+msgstr ""
+
+#. module: base
+#: field:res.lang,decimal_point:0
+msgid "Decimal Separator"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_res_groups
+msgid ""
+"A group is a set of functional areas that will be assigned to the user in "
+"order to give them access and rights to specific applications and tasks in "
+"the system. You can create custom groups or edit the ones existing by "
+"default in order to customize the view of the menu that users will be able "
+"to see. Whether they can have a read, write, create and delete access right "
+"can be managed from here."
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+#: view:res.request:0
+#: field:res.request,history:0
+msgid "History"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,create_uid:0
+msgid "Creator"
+msgstr ""
+
+#. module: base
+#: model:res.company,overdue_msg:base.main_company
+msgid ""
+"Please note that the following payments are now due. If your payment "
+" has been sent, kindly forward your payment details. If "
+"payment will be delayed further, please contact us "
+"to discuss. \n"
+"Would your payment have been carried out after this mail was sent, please "
+"consider the present one as void."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mx
+msgid "Mexico"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_base_config_plugins
+msgid "Plugins"
+msgstr ""
+
+#. module: base
+#: field:res.company,child_ids:0
+msgid "Child Companies"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_users
+msgid "res.users"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ni
+msgid "Nicaragua"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1046
+#, python-format
+msgid "The write method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: view:res.partner.event:0
+msgid "General Description"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_config_simple_view_form
+#: view:res.config.view:0
+msgid "Configure Your Interface"
+msgstr ""
+
+#. module: base
+#: field:ir.values,meta:0
+msgid "Meta Datas"
+msgstr ""
+
+#. module: base
+#: sql_constraint:ir.ui.view_sc:0
+msgid "Shortcut for this menu already exists!"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ve
+msgid "Venezuela"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "9. %j ==> 340"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.zm
+msgid "Zambia"
+msgstr ""
+
+#. module: base
+#: help:res.partner,user_id:0
+msgid ""
+"The internal user that is in charge of communicating with this partner if "
+"any."
+msgstr ""
+
+#. module: base
+#: field:res.partner,parent_id:0
+msgid "Parent Partner"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Cancel Upgrade"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ci
+msgid "Ivory Coast (Cote D'Ivoire)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.kz
+msgid "Kazakhstan"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%w - Weekday number [0(Sunday),6]."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_partner_form
+msgid ""
+"A customer is an entity you do business with, like a company or an "
+"organization. A customer can have several contacts or addresses which are "
+"the people working for this company. You can use the history tab, to follow "
+"all transactions related to a customer: sales order, emails, opportunities, "
+"claims, etc. If you use the email gateway, the Outlook or the Thunderbird "
+"plugin, don't forget to register emails to each contact so that the gateway "
+"will automatically attach incoming emails to the right partner."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,name:0
+#: field:ir.actions.todo,name:0
+#: field:ir.cron,name:0
+#: field:ir.model.access,name:0
+#: field:ir.model.fields,name:0
+#: field:ir.module.category,name:0
+#: field:ir.module.module,name:0
+#: field:ir.module.module.dependency,name:0
+#: report:ir.module.reference.graph:0
+#: field:ir.property,name:0
+#: field:ir.rule,name:0
+#: field:ir.sequence,name:0
+#: field:ir.sequence.type,name:0
+#: field:ir.values,name:0
+#: field:multi_company.default,name:0
+#: field:res.bank,name:0
+#: field:res.config.view,name:0
+#: field:res.lang,name:0
+#: field:res.partner,name:0
+#: field:res.partner.bank.type,name:0
+#: view:res.partner.event:0
+#: field:res.request.link,name:0
+#: field:workflow,name:0
+#: field:workflow.activity,name:0
+msgid "Name"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,multi:0
+msgid ""
+"If set to true, the action will not be displayed on the right toolbar of a "
+"form view"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ms
+msgid "Montserrat"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:205
+#, python-format
+msgid ""
+"The Selection Options expression is not a valid Pythonic expression.Please "
+"provide an expression in the [('key','Label'), ...] format."
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_translation_app
+msgid "Application Terms"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,context_tz:0
+#: help:res.users,context_tz:0
+msgid ""
+"The user's timezone, used to perform timezone conversions between the server "
+"and the client."
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,demo:0
+msgid "Demo data"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "English (UK)"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Japanese / 日本語"
+msgstr ""
+
+#. module: base
+#: help:workflow.transition,act_from:0
+msgid ""
+"Source activity. When this activity is over, the condition is tested to "
+"determine if we can start the ACT_TO activity."
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_3
+msgid "Starter Partner"
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,relation_field:0
+msgid ""
+"For one2many fields, the field on the target model that implement the "
+"opposite many2one relationship"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_act_window_view
+msgid "ir.actions.act_window.view"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Web"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "English (CA)"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_publisher_warranty_contract
+msgid "publisher_warranty.contract"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.et
+msgid "Ethiopia"
+msgstr ""
+
+#. module: base
+#: help:res.country.state,code:0
+msgid "The state code in three chars.\n"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sj
+msgid "Svalbard and Jan Mayen Islands"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_wizard
+#: selection:ir.ui.menu,action:0
+msgid "ir.actions.wizard"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+#: view:ir.actions.report.xml:0
+#: view:ir.actions.server:0
+#: view:ir.filters:0
+#: view:res.request:0
+msgid "Group By"
+msgstr ""
+
+#. module: base
+#: view:res.config:0
+#: view:res.config.installer:0
+msgid "title"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_language_install
+msgid "Install Language"
+msgstr ""
+
+#. module: base
+#: view:ir.translation:0
+msgid "Translation"
+msgstr ""
+
+#. module: base
+#: selection:res.request,state:0
+msgid "closed"
+msgstr ""
+
+#. module: base
+#: selection:base.language.export,state:0
+msgid "get"
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,on_delete:0
+msgid "On delete property for many2one fields"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,write_id:0
+msgid "Write Id"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_product
+msgid "Products"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,domain:0
+#: field:ir.filters,domain:0
+msgid "Domain Value"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "SMS Configuration"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (BO) / Español (BO)"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_access_act
+#: model:ir.ui.menu,name:base.menu_ir_access_act
+msgid "Access Controls List"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.um
+msgid "USA Minor Outlying Islands"
+msgstr ""
+
+#. module: base
+#: field:res.partner.bank,state:0
+#: field:res.partner.bank.type.field,bank_type_id:0
+msgid "Bank Type"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:58
+#: code:addons/base/res/res_user.py:67
+#, python-format
+msgid "The name of the group can not start with \"-\""
+msgstr ""
+
+#. module: base
+#: view:ir.ui.view_sc:0
+#: field:res.partner.title,shortcut:0
+msgid "Shortcut"
+msgstr ""
+
+#. module: base
+#: field:ir.model.data,date_init:0
+msgid "Init Date"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Gujarati / ગુજરાતી"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:257
+#, python-format
+msgid ""
+"Unable to process module \"%s\" because an external dependency is not met: %s"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract.wizard:0
+msgid "Please enter the serial key provided in your contract document:"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+#: field:workflow.activity,flow_start:0
+msgid "Flow Start"
+msgstr ""
+
+#. module: base
+#: code:addons/__init__.py:834
+#, python-format
+msgid "module base cannot be loaded! (hint: verify addons-path)"
+msgstr ""
+
+#. module: base
+#: view:res.partner.bank:0
+msgid "Bank Account Owner"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.act_values_form
+msgid "Client Actions Connections"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,res_name:0
+#: field:ir.ui.view_sc,resource:0
+msgid "Resource Name"
+msgstr ""
+
+#. module: base
+#: selection:ir.cron,interval_type:0
+msgid "Hours"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gp
+msgid "Guadeloupe (French)"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_lang.py:157
+#: code:addons/base/res/res_lang.py:159
+#: code:addons/base/res/res_lang.py:161
+#, python-format
+msgid "User Error"
+msgstr ""
+
+#. module: base
+#: help:workflow.transition,signal:0
+msgid ""
+"When the operation of transition comes from a button pressed in the client "
+"form, signal tests the name of the pressed button. If signal is NULL, no "
+"button is necessary to validate this transition."
+msgstr ""
+
+#. module: base
+#: help:multi_company.default,object_id:0
+msgid "Object affected by this rule"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Directory"
+msgstr ""
+
+#. module: base
+#: field:wizard.ir.model.menu.create,name:0
+msgid "Menu Name"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Author Website"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+msgid "Month"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.my
+msgid "Malaysia"
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+#: model:ir.actions.act_window,name:base.action_view_base_language_install
+msgid "Load Official Translation"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_request_history
+msgid "res.request.history"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Client Action Configuration"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner_address
+#: view:res.partner.address:0
+msgid "Partner Addresses"
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,translate:0
+msgid ""
+"Whether values for this field can be translated (enables the translation "
+"mechanism for that field)"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%S - Seconds [00,61]."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cv
+msgid "Cape Verde"
+msgstr ""
+
+#. module: base
+#: view:base.module.import:0
+msgid "Select module package to import (.zip file):"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.act_res_partner_event
+#: field:res.partner,events:0
+#: field:res.partner.event,name:0
+#: model:res.widget,title:base.events_widget
+msgid "Events"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_url
+#: selection:ir.ui.menu,action:0
+msgid "ir.actions.url"
+msgstr ""
+
+#. module: base
+#: model:res.widget,title:base.currency_converter_widget
+msgid "Currency Converter"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:156
+#, python-format
+msgid "Wrong ID for the browse record, got %r, expected an integer."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_addess_tree
+#: view:res.partner:0
+msgid "Partner Contacts"
+msgstr ""
+
+#. module: base
+#: field:base.module.update,add:0
+msgid "Number of modules added"
+msgstr ""
+
+#. module: base
+#: view:res.currency:0
+msgid "Price Accuracy"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Latvian / latviešu valoda"
+msgstr ""
+
+#. module: base
+#: view:res.config:0
+#: view:res.config.installer:0
+msgid "vsep"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "French / Français"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1049
+#, python-format
+msgid "The create method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: field:workflow.triggers,workitem_id:0
+msgid "Workitem"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.todo:0
+msgid "Set as Todo"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window.view,act_window_id:0
+#: view:ir.actions.actions:0
+#: field:ir.actions.todo,action_id:0
+#: field:ir.ui.menu,action:0
+#: field:ir.values,action_id:0
+#: selection:ir.values,key:0
+#: view:res.users:0
+msgid "Action"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Email Configuration"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_cron
+msgid "ir.cron"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid "Combination of rules"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Current Year without Century: %(y)s"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,trigger_obj_id:0
+msgid "Trigger On"
+msgstr ""
+
+#. module: base
+#: sql_constraint:ir.rule:0
+msgid "Rule must have at least one checked access right !"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.fj
+msgid "Fiji"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,size:0
+msgid "Size"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sd
+msgid "Sudan"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.fm
+msgid "Micronesia"
+msgstr ""
+
+#. module: base
+#: view:res.request.history:0
+msgid "Request History"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,menus:0
+#: field:ir.module.module,menus_by_module:0
+#: view:res.groups:0
+msgid "Menus"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Serbian (Latin) / srpski"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.il
+msgid "Israel"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.wizard,name:base.wizard_server_action_create
+msgid "Create Action"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_model_model
+#: model:ir.model,name:base.model_ir_model
+#: model:ir.ui.menu,name:base.ir_model_model_menu
+msgid "Objects"
+msgstr ""
+
+#. module: base
+#: field:res.lang,time_format:0
+msgid "Time Format"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Defined Reports"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.report.xml:0
+msgid "Report xml"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,modules:0
+#: model:ir.actions.act_window,name:base.action_module_open_categ
+#: model:ir.actions.act_window,name:base.open_module_tree
+#: view:ir.module.module:0
+#: model:ir.ui.menu,name:base.menu_management
+#: model:ir.ui.menu,name:base.menu_module_tree
+msgid "Modules"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+#: selection:workflow.activity,kind:0
+#: field:workflow.activity,subflow_id:0
+#: field:workflow.workitem,subflow_id:0
+msgid "Subflow"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_config
+msgid "res.config"
+msgstr ""
+
+#. module: base
+#: field:workflow.transition,signal:0
+msgid "Signal (button Name)"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_res_bank_form
+#: model:ir.ui.menu,name:base.menu_action_res_bank_form
+#: view:res.bank:0
+#: field:res.partner,bank_ids:0
+msgid "Banks"
+msgstr ""
+
+#. module: base
+#: view:res.log:0
+msgid "Unread"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,doall:0
+msgid "Repeat Missed"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,state:0
+msgid "Type of the Action that is to be executed"
+msgstr ""
+
+#. module: base
+#: field:ir.server.object.lines,server_id:0
+msgid "Object Mapping"
+msgstr ""
+
+#. module: base
+#: help:res.currency,rate:0
+#: help:res.currency.rate,rate:0
+msgid "The rate of the currency to the currency of rate 1"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.uk
+msgid "United Kingdom"
+msgstr ""
+
+#. module: base
+#: view:res.config:0
+#: view:res.config.users:0
+#: view:res.config.view:0
+msgid "res_config_contents"
+msgstr ""
+
+#. module: base
+#: help:res.partner.category,active:0
+msgid "The active field allows you to hide the category without removing it."
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Object:"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bw
+msgid "Botswana"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_title_partner
+#: model:ir.ui.menu,name:base.menu_partner_title_partner
+#: view:res.partner.title:0
+msgid "Partner Titles"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,auto_refresh:0
+msgid "Add an auto-refresh on the view"
+msgstr ""
+
+#. module: base
+#: help:res.partner,employee:0
+msgid "Check this box if the partner is an Employee."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_rml_content:0
+#: field:ir.actions.report.xml,report_rml_content_data:0
+msgid "RML content"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_workflow_workitem_form
+#: model:ir.ui.menu,name:base.menu_workflow_workitem
+msgid "Workitems"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,advice:0
+msgid "Advice"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_attachment
+msgid "ir.attachment"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3533
+#, python-format
+msgid ""
+"You cannot perform this operation. New Record Creation is not allowed for "
+"this object as this object is for reporting purpose."
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid "- module,type,name,res_id,src,value"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Lithuanian / Lietuvių kalba"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,record_id:0
+msgid ""
+"Provide the field name where the record id is stored after the create "
+"operations. If it is empty, you can not track the new record."
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,relation:0
+msgid "For relationship fields, the technical name of the target model"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Indonesian / Bahasa Indonesia"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view,inherit_id:0
+msgid "Inherited View"
+msgstr ""
+
+#. module: base
+#: view:ir.translation:0
+msgid "Source Term"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_main_pm
+msgid "Project"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,web_icon_hover_data:0
+msgid "Web Icon Image (hover)"
+msgstr ""
+
+#. module: base
+#: view:base.module.import:0
+msgid "Module file successfully imported!"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.todo,state:0
+msgid "Cancelled"
+msgstr ""
+
+#. module: base
+#: view:res.config.users:0
+msgid "Create User"
+msgstr ""
+
+#. module: base
+#: view:partner.clear.ids:0
+msgid "Want to Clear Ids ? "
+msgstr ""
+
+#. module: base
+#: field:publisher_warranty.contract,name:0
+#: field:publisher_warranty.contract.wizard,name:0
+msgid "Serial Key"
+msgstr ""
+
+#. module: base
+#: selection:res.request,priority:0
+msgid "Low"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_audit
+msgid "Audit"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lc
+msgid "Saint Lucia"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract:0
+msgid "Maintenance Contract"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,trigger_obj_id:0
+msgid "Select the object from the model on which the workflow will executed."
+msgstr ""
+
+#. module: base
+#: field:res.partner,employee:0
+msgid "Employee"
+msgstr ""
+
+#. module: base
+#: field:ir.model.access,perm_create:0
+msgid "Create Access"
+msgstr ""
+
+#. module: base
+#: field:res.partner.address,state_id:0
+msgid "Fed. State"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,copy_object:0
+msgid "Copy Of"
+msgstr ""
+
+#. module: base
+#: field:ir.model,osv_memory:0
+msgid "In-memory model"
+msgstr ""
+
+#. module: base
+#: view:partner.clear.ids:0
+msgid "Clear Ids"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.io
+msgid "British Indian Ocean Territory"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,view:0
+#: field:res.config.view,view:0
+#: field:res.users,view:0
+msgid "Interface"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Field Mapping"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract:0
+msgid "Refresh Validation Dates"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+#: field:ir.model.fields,ttype:0
+msgid "Field Type"
+msgstr ""
+
+#. module: base
+#: field:res.country.state,code:0
+msgid "State Code"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,on_delete:0
+msgid "On delete"
+msgstr ""
+
+#. module: base
+#: selection:res.lang,direction:0
+msgid "Left-to-Right"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+#: field:res.lang,translatable:0
+msgid "Translatable"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.vn
+msgid "Vietnam"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,signature:0
+#: view:res.users:0
+#: field:res.users,signature:0
+msgid "Signature"
+msgstr ""
+
+#. module: base
+#: code:addons/fields.py:456
+#: code:addons/fields.py:654
+#: code:addons/fields.py:656
+#: code:addons/fields.py:658
+#: code:addons/fields.py:660
+#: code:addons/fields.py:662
+#: code:addons/fields.py:664
+#, python-format
+msgid "Not Implemented"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_widget_user
+msgid "res.widget.user"
+msgstr ""
+
+#. module: base
+#: field:res.partner.category,complete_name:0
+msgid "Full Name"
+msgstr ""
+
+#. module: base
+#: view:base.module.configuration:0
+msgid "_Ok"
+msgstr ""
+
+#. module: base
+#: help:ir.filters,user_id:0
+msgid "False means for every user"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:198
+#, python-format
+msgid "The name of the module must be unique !"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mz
+msgid "Mozambique"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_project_long_term
+msgid "Long Term Planning"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,message:0
+#: view:partner.sms.send:0
+#: field:partner.wizard.spam,text:0
+#: field:res.log,name:0
+msgid "Message"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window.view,multi:0
+msgid "On Multiple Doc."
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+#: field:res.partner,user_id:0
+msgid "Salesman"
+msgstr ""
+
+#. module: base
+#: field:res.partner,address:0
+#: view:res.partner.address:0
+msgid "Contacts"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3199
+#, python-format
+msgid ""
+"Unable to delete this document because it is used as a default property"
+msgstr ""
+
+#. module: base
+#: view:res.widget.wizard:0
+msgid "Add"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_window
+#: model:ir.ui.menu,name:base.menu_view_base_module_upgrade
+msgid "Apply Scheduled Upgrades"
+msgstr ""
+
+#. module: base
+#: view:res.widget:0
+msgid "Widgets"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cz
+msgid "Czech Republic"
+msgstr ""
+
+#. module: base
+#: view:res.widget.wizard:0
+msgid "Widget Wizard"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.act_ir_actions_todo_form
+msgid ""
+"The configuration wizards are used to help you configure a new instance of "
+"OpenERP. They are launched during the installation of new modules, but you "
+"can choose to restart some wizards manually from this menu."
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:206
+#, python-format
+msgid ""
+"Please use the change password wizard (in User Preferences or User menu) to "
+"change your own password."
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1350
+#, python-format
+msgid "Insufficient fields for Calendar View!"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "Integer"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.report.xml,report_rml:0
+msgid ""
+"The path to the main report file (depending on Report Type) or NULL if the "
+"content is in another data field"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,company_id:0
+#: help:res.users,company_id:0
+msgid "The company this user is currently working for."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_wizard_ir_model_menu_create
+msgid "wizard.ir.model.menu.create"
+msgstr ""
+
+#. module: base
+#: view:workflow.transition:0
+msgid "Transition"
+msgstr ""
+
+#. module: base
+#: field:res.groups,menu_access:0
+msgid "Access Menu"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.na
+msgid "Namibia"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mn
+msgid "Mongolia"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Created Menus"
+msgstr ""
+
+#. module: base
+#: selection:ir.ui.view,type:0
+msgid "mdx"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bi
+msgid "Burundi"
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+#: view:base.module.import:0
+#: view:base.module.update:0
+#: view:publisher_warranty.contract.wizard:0
+#: view:res.request:0
+#: wizard_button:server.action.create,init,end:0
+#: wizard_button:server.action.create,step_1,end:0
+msgid "Close"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (MX) / Español (MX)"
+msgstr ""
+
+#. module: base
+#: view:res.log:0
+msgid "My Logs"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bt
+msgid "Bhutan"
+msgstr ""
+
+#. module: base
+#: help:ir.sequence,number_next:0
+msgid "Next number of this sequence"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_11
+msgid "Textile Suppliers"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.url,target:0
+msgid "This Window"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract:0
+msgid "Publisher Warranty Contracts"
+msgstr ""
+
+#. module: base
+#: help:res.log,name:0
+msgid "The logging message."
+msgstr ""
+
+#. module: base
+#: field:base.language.export,format:0
+msgid "File Format"
+msgstr ""
+
+#. module: base
+#: field:res.lang,iso_code:0
+msgid "ISO code"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_config_view
+msgid "res.config.view"
+msgstr ""
+
+#. module: base
+#: view:res.log:0
+#: field:res.log,read:0
+msgid "Read"
+msgstr ""
+
+#. module: base
+#: sql_constraint:res.country:0
+msgid "The name of the country must be unique !"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_country_state
+msgid ""
+"If you are working on the American market, you can manage the different "
+"federal states you are working on from here. Each state is attached to one "
+"country."
+msgstr ""
+
+#. module: base
+#: view:workflow.workitem:0
+msgid "Workflow Workitems"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.vc
+msgid "Saint Vincent & Grenadines"
+msgstr ""
+
+#. module: base
+#: field:partner.sms.send,password:0
+#: field:res.config.users,password:0
+#: field:res.users,password:0
+msgid "Password"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_model_fields
+#: view:ir.model:0
+#: field:ir.model,field_id:0
+#: model:ir.model,name:base.model_ir_model_fields
+#: view:ir.model.fields:0
+#: model:ir.ui.menu,name:base.ir_model_model_fields
+msgid "Fields"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_employee_form
+msgid "Employees"
+msgstr ""
+
+#. module: base
+#: help:res.log,read:0
+msgid ""
+"If this log item has been read, get() should not send it to the client"
+msgstr ""
+
+#. module: base
+#: field:res.company,rml_header2:0
+#: field:res.company,rml_header3:0
+msgid "RML Internal Header"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,search_view_id:0
+msgid "Search View Ref."
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,installed_version:0
+msgid "Latest version"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.res_partner_canal-act
+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 ""
+
+#. module: base
+#: model:res.partner.bank.type.field,name:base.bank_normal_field
+msgid "acc_number"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_address_form
+#: model:ir.ui.menu,name:base.menu_partner_address_form
+msgid "Addresses"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mm
+msgid "Myanmar"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Chinese (CN) / 简体中文"
+msgstr ""
+
+#. module: base
+#: field:res.bank,street:0
+#: field:res.partner.address,street:0
+#: field:res.partner.bank,street:0
+msgid "Street"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.yu
+msgid "Yugoslavia"
+msgstr ""
+
+#. module: base
+#: field:ir.model.data,name:0
+msgid "XML Identifier"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ca
+msgid "Canada"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module.dependency,state:0
+msgid "Unknown"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_res_users_my
+msgid "Change My Preferences"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_actions.py:164
+#, python-format
+msgid "Invalid model name in the action definition."
+msgstr ""
+
+#. module: base
+#: field:partner.sms.send,text:0
+msgid "SMS Message"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cm
+msgid "Cameroon"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bf
+msgid "Burkina Faso"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.todo,state:0
+msgid "Skipped"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,state:0
+msgid "Custom Field"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,web:0
+msgid "Has a web component"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cc
+msgid "Cocos (Keeling) Islands"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,state:0
+#: selection:base.module.import,state:0
+#: selection:base.module.update,state:0
+msgid "init"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "11. %U or %W ==> 48 (49th week)"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner_bank_type_field
+msgid "Bank type fields"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Dutch / Nederlands"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_config.py:384
+#, python-format
+msgid ""
+"\n"
+"\n"
+"This addon is already installed on your system"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,interval_number:0
+msgid "Repeat every x."
+msgstr ""
+
+#. module: base
+#: wizard_view:server.action.create,step_1:0
+#: wizard_field:server.action.create,step_1,report:0
+msgid "Select Report"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "1cm 28cm 20cm 28cm"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,maintainer:0
+msgid "Maintainer"
+msgstr ""
+
+#. module: base
+#: field:ir.sequence,suffix:0
+msgid "Suffix"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mo
+msgid "Macau"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.report.xml,name:base.res_partner_address_report
+msgid "Labels"
+msgstr ""
+
+#. module: base
+#: field:partner.wizard.spam,email_from:0
+msgid "Sender's email"
+msgstr ""
+
+#. module: base
+#: field:ir.default,field_name:0
+msgid "Object Field"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (PE) / Español (PE)"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "French (CH) / Français (CH)"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,action_id:0
+#: help:res.users,action_id:0
+msgid ""
+"If specified, this action will be opened at logon for this user, in addition "
+"to the standard menu."
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "Client Actions"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1806
+#, python-format
+msgid "The exists method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:336
+#, python-format
+msgid ""
+"You try to upgrade a module that depends on the module: %s.\n"
+"But this module is not available in your system."
+msgstr ""
+
+#. module: base
+#: field:workflow.transition,act_to:0
+msgid "Destination Activity"
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "Connect Events to Actions"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_update_translations
+msgid "base.update.translations"
+msgstr ""
+
+#. module: base
+#: field:ir.module.category,parent_id:0
+#: field:res.partner.category,parent_id:0
+msgid "Parent Category"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "Integer Big"
+msgstr ""
+
+#. module: base
+#: selection:res.partner.address,type:0
+#: selection:res.partner.title,domain:0
+#: view:res.users:0
+msgid "Contact"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_ui_menu
+msgid "ir.ui.menu"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.us
+msgid "United States"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Cancel Uninstall"
+msgstr ""
+
+#. module: base
+#: view:res.bank:0
+#: view:res.partner:0
+#: view:res.partner.address:0
+msgid "Communication"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.report.xml:0
+msgid "RML Report"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_server_object_lines
+msgid "ir.server.object.lines"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:531
+#, python-format
+msgid "Module %s: Invalid Quality Certificate"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.kw
+msgid "Kuwait"
+msgstr ""
+
+#. module: base
+#: field:workflow.workitem,inst_id:0
+msgid "Instance"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.report.xml,attachment:0
+msgid ""
+"This is the filename of the attachment used to store the printing result. "
+"Keep empty to not save the printed reports. You can use a python expression "
+"with the object and time variables."
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "Many2One"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ng
+msgid "Nigeria"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:250
+#, python-format
+msgid "For selection fields, the Selection Options must be given!"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_sms_send
+msgid "SMS Send"
+msgstr ""
+
+#. module: base
+#: field:res.company,user_ids:0
+msgid "Accepted Users"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,web_icon_data:0
+msgid "Web Icon Image"
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "Values for Event Type"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,select_level:0
+msgid "Always Searchable"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.hk
+msgid "Hong Kong"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,name:0
+msgid "Easy to Refer action by name e.g. One Sales Order -> Many Invoices"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_partner_address_form
+msgid ""
+"Customers (also called Partners in other areas of the system) helps you "
+"manage your address book of companies whether they are prospects, customers "
+"and/or suppliers. The partner form allows you to track and record all the "
+"necessary information to interact with your partners from the company "
+"address to their contacts as well as pricelists, and much more. If you "
+"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 ""
+
+#. module: base
+#: model:res.country,name:base.ph
+msgid "Philippines"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ma
+msgid "Morocco"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "2. %a ,%A ==> Fri, Friday"
+msgstr ""
+
+#. module: base
+#: field:res.widget,content:0
+msgid "Content"
+msgstr ""
+
+#. module: base
+#: help:ir.rule,global:0
+msgid "If no group is specified the rule is global and applied to everyone"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.td
+msgid "Chad"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_workflow_transition
+msgid "workflow.transition"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%a - Abbreviated weekday name."
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Introspection report on objects"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pf
+msgid "Polynesia (French)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.dm
+msgid "Dominica"
+msgstr ""
+
+#. module: base
+#: sql_constraint:publisher_warranty.contract:0
+msgid ""
+"Your publisher warranty contract is already subscribed in the system !"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,nextcall:0
+msgid "Next planned execution date for this scheduler"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,view:0
+#: help:res.users,view:0
+msgid "Choose between the simplified interface and the extended one"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.np
+msgid "Nepal"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:2307
+#, python-format
+msgid ""
+"Invalid value for reference field \"%s\" (last part must be a non-zero "
+"integer): \"%s\""
+msgstr ""
+
+#. module: base
+#: help:ir.cron,args:0
+msgid "Arguments to be passed to the method. e.g. (uid,)"
+msgstr ""
+
+#. module: base
+#: help:ir.ui.menu,groups_id:0
+msgid ""
+"If you have groups, the visibility of this menu will be based on these "
+"groups. If this field is empty, OpenERP will compute visibility based on the "
+"related object's read access."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_ui_view_custom
+#: model:ir.ui.menu,name:base.menu_action_ui_view_custom
+#: view:ir.ui.view.custom:0
+msgid "Customized Views"
+msgstr ""
+
+#. module: base
+#: view:partner.sms.send:0
+msgid "Bulk SMS send"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Seconde: %(sec)s"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_view_base_module_update
+msgid "Update Modules List"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:255
+#, python-format
+msgid ""
+"Unable to upgrade module \"%s\" because an external dependency is not met: %s"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:257
+#, python-format
+msgid ""
+"Please keep in mind that documents currently displayed may not be relevant "
+"after switching to another company. If you have unsaved changes, please make "
+"sure to save and close all forms before switching to a different company. "
+"(You can click on Cancel in the User Preferences now)"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.configuration.wizard:0
+msgid "Continue"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Thai / ภาษาไทย"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:158
+#, python-format
+msgid "Object %s does not exists"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Slovenian / slovenščina"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,attachment_use:0
+msgid "Reload from Attachment"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bv
+msgid "Bouvet Island"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,name:0
+msgid "Attachment Name"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,data:0
+#: field:base.language.import,data:0
+msgid "File"
+msgstr ""
+
+#. module: base
+#: view:res.config.users:0
+msgid "Add User"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade_install
+msgid "Module Upgrade Install"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_configuration_wizard
+msgid "ir.actions.configuration.wizard"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%b - Abbreviated month name."
+msgstr ""
+
+#. module: base
+#: field:res.partner,supplier:0
+#: view:res.partner.address:0
+#: field:res.partner.address,is_supplier_add:0
+#: model:res.partner.category,name:base.res_partner_category_8
+msgid "Supplier"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+#: selection:ir.actions.server,state:0
+msgid "Multi Actions"
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+#: view:base.language.import:0
+#: view:wizard.ir.model.menu.create:0
+msgid "_Close"
+msgstr ""
+
+#. module: base
+#: field:multi_company.default,company_dest_id:0
+msgid "Default Company"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (EC) / Español (EC)"
+msgstr ""
+
+#. module: base
+#: help:ir.ui.view,xml_id:0
+msgid "ID of the view defined in xml file"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_module_import
+#: model:ir.ui.menu,name:base.menu_view_base_module_import
+msgid "Import Module"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.as
+msgid "American Samoa"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,res_model:0
+msgid "Model name of the object to open in the view window"
+msgstr ""
+
+#. module: base
+#: field:res.log,secondary:0
+msgid "Secondary Log"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,selectable:0
+msgid "Selectable"
+msgstr ""
+
+#. module: base
+#: view:res.request.link:0
+msgid "Request Link"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+#: selection:ir.attachment,type:0
+#: field:ir.module.module,url:0
+msgid "URL"
+msgstr ""
+
+#. module: base
+#: help:res.country,name:0
+msgid "The full name of the country."
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.server,state:0
+msgid "Iteration"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3448
+#: code:addons/orm.py:3532
+#, python-format
+msgid "UserError"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ae
+msgid "United Arab Emirates"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_crm_case_job_req_main
+msgid "Recruitment"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.re
+msgid "Reunion (French)"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:321
+#, python-format
+msgid ""
+"New column name must still start with x_ , because it is a custom field!"
+msgstr ""
+
+#. module: base
+#: view:ir.model.access:0
+#: view:ir.rule:0
+#: field:ir.rule,global:0
+msgid "Global"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mp
+msgid "Northern Mariana Islands"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sb
+msgid "Solomon Islands"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:490
+#: code:addons/orm.py:1897
+#: code:addons/orm.py:2972
+#: code:addons/orm.py:3165
+#: code:addons/orm.py:3365
+#: code:addons/orm.py:3817
+#, python-format
+msgid "AccessError"
+msgstr ""
+
+#. module: base
+#: view:res.request:0
+msgid "Waiting"
+msgstr ""
+
+#. module: base
+#: code:addons/__init__.py:834
+#, python-format
+msgid "Could not load base module"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "8. %I:%M:%S %p ==> 06:25:20 PM"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:1803
+#, python-format
+msgid "The copy method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: field:res.log,create_date:0
+msgid "Creation Date"
+msgstr ""
+
+#. module: base
+#: view:ir.translation:0
+#: model:ir.ui.menu,name:base.menu_translation
+msgid "Translations"
+msgstr ""
+
+#. module: base
+#: field:ir.sequence,padding:0
+msgid "Number padding"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.report.xml:0
+msgid "Report"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ua
+msgid "Ukraine"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.to
+msgid "Tonga"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_module_category
+#: view:ir.module.category:0
+msgid "Module Category"
+msgstr ""
+
+#. module: base
+#: view:partner.wizard.ean.check:0
+msgid "Ignore"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Reference Guide"
+msgstr ""
+
+#. module: base
+#: view:ir.ui.view:0
+msgid "Architecture"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ml
+msgid "Mali"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,email:0
+#: help:res.users,email:0
+msgid ""
+"If an email is provided, the user will be sent a message welcoming him.\n"
+"\n"
+"Warning: if \"email_from\" and \"smtp_server\" aren't configured, it won't "
+"be possible to email new users."
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Flemish (BE) / Vlaams (BE)"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,interval_number:0
+msgid "Interval Number"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tk
+msgid "Tokelau"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_xsl:0
+msgid "XSL path"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bn
+msgid "Brunei Darussalam"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+#: field:ir.actions.act_window,view_type:0
+#: field:ir.actions.act_window.view,view_mode:0
+#: field:ir.ui.view,type:0
+#: field:wizard.ir.model.menu.create.line,view_type:0
+msgid "View Type"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.next_id_2
+msgid "User Interface"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,create_date:0
+msgid "Date Created"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_todo
+msgid "ir.actions.todo"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_config.py:94
+#, python-format
+msgid "Couldn't find previous ir.actions.todo"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+msgid "General Settings"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_administration_shortcut
+msgid "Custom Shortcuts"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Vietnamese / Tiếng Việt"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.dz
+msgid "Algeria"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.be
+msgid "Belgium"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_osv_memory_autovacuum
+msgid "osv_memory.autovacuum"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,lang:0
+#: field:base.language.install,lang:0
+#: field:base.update.translations,lang:0
+#: field:ir.translation,lang:0
+#: field:res.config.users,context_lang:0
+#: field:res.partner,lang:0
+#: field:res.users,context_lang:0
+msgid "Language"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gm
+msgid "Gambia"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_res_company_form
+#: model:ir.model,name:base.model_res_company
+#: model:ir.ui.menu,name:base.menu_action_res_company_form
+#: model:ir.ui.menu,name:base.menu_res_company_global
+#: view:res.company:0
+#: field:res.config.users,company_ids:0
+#: view:res.users:0
+#: field:res.users,company_ids:0
+msgid "Companies"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%H - Hour (24-hour clock) [00,23]."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_widget
+msgid "res.widget"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:258
+#, python-format
+msgid "Model %s does not exist!"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_lang.py:159
+#, python-format
+msgid "You cannot delete the language which is User's Preferred Language !"
+msgstr ""
+
+#. module: base
+#: code:addons/fields.py:103
+#, python-format
+msgid "Not implemented get_memory method !"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+#: field:ir.actions.server,code:0
+#: selection:ir.actions.server,state:0
+msgid "Python Code"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_module_import.py:67
+#, python-format
+msgid "Can not create the module file: %s !"
+msgstr ""
+
+#. module: base
+#: model:ir.module.module,description:base.module_meta_information
+msgid "The kernel of OpenERP, needed for all installation."
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+#: view:base.module.import:0
+#: view:base.module.update:0
+#: view:base.module.upgrade:0
+#: view:base.update.translations:0
+#: view:partner.clear.ids:0
+#: view:partner.sms.send:0
+#: view:partner.wizard.spam:0
+#: view:publisher_warranty.contract.wizard:0
+#: view:res.widget.wizard:0
+msgid "Cancel"
+msgstr ""
+
+#. module: base
+#: selection:base.language.export,format:0
+msgid "PO File"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nt
+msgid "Neutral Zone"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Hindi / हिंदी"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+msgid "Custom"
+msgstr ""
+
+#. module: base
+#: view:res.request:0
+msgid "Current"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_9
+msgid "Components Supplier"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_res_users
+#: field:ir.default,uid:0
+#: model:ir.ui.menu,name:base.menu_action_res_users
+#: model:ir.ui.menu,name:base.menu_users
+#: view:res.groups:0
+#: field:res.groups,users:0
+#: view:res.users:0
+msgid "Users"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,published_version:0
+msgid "Published Version"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.is
+msgid "Iceland"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_action_window
+#: model:ir.ui.menu,name:base.menu_ir_action_window
+msgid "Window Actions"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%I - Hour (12-hour clock) [01,12]."
+msgstr ""
+
+#. module: base
+#: selection:publisher_warranty.contract.wizard,state:0
+msgid "Finished"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.de
+msgid "Germany"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Week of the year: %(woy)s"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_14
+msgid "Bad customers"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Reports :"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gy
+msgid "Guyana"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,view_type:0
+msgid ""
+"View type: set to 'tree' for a hierarchical tree view, or 'form' for other "
+"views"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_config.py:421
+#, python-format
+msgid "Click 'Continue' to configure the next addon..."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,record_id:0
+msgid "Create Id"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.hn
+msgid "Honduras"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,menu_tips:0
+#: help:res.users,menu_tips:0
+msgid ""
+"Check out this box if you want to always display tips on each menu action"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.eg
+msgid "Egypt"
+msgstr ""
+
+#. module: base
+#: field:ir.rule,perm_read:0
+msgid "Apply For Read"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,model_id:0
+msgid ""
+"Select the object on which the action will work (read, write, create)."
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_actions.py:629
+#, python-format
+msgid "Please specify server option --email-from !"
+msgstr ""
+
+#. module: base
+#: field:base.language.import,name:0
+msgid "Language Name"
+msgstr ""
+
+#. module: base
+#: selection:ir.property,type:0
+msgid "Boolean"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+msgid "Fields Description"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+#: view:ir.cron:0
+#: view:ir.model.access:0
+#: view:ir.model.data:0
+#: view:ir.model.fields:0
+#: view:ir.module.module:0
+#: view:ir.rule:0
+#: view:ir.ui.view:0
+#: view:ir.values:0
+#: view:res.partner:0
+#: view:res.partner.address:0
+#: view:workflow.activity:0
+msgid "Group By..."
+msgstr ""
+
+#. module: base
+#: view:ir.model.fields:0
+#: field:ir.model.fields,readonly:0
+#: field:res.partner.bank.type.field,readonly:0
+msgid "Readonly"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window.view,view_id:0
+#: field:ir.default,page:0
+#: selection:ir.translation,type:0
+#: field:wizard.ir.model.menu.create.line,view_id:0
+msgid "View"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,state:0
+#: selection:ir.module.module.dependency,state:0
+msgid "To be installed"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.act_window,display_menu_tip:0
+msgid ""
+"It gives the status if the tip has to be displayed or not when a user "
+"executes an action"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+#: model:ir.module.module,shortdesc:base.module_meta_information
+#: field:res.currency,base:0
+msgid "Base"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Telugu / తెలుగు"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lr
+msgid "Liberia"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+#: view:ir.model:0
+#: view:res.groups:0
+#: view:res.partner:0
+#: field:res.partner,comment:0
+#: model:res.widget,title:base.note_widget
+msgid "Notes"
+msgstr ""
+
+#. module: base
+#: field:ir.config_parameter,value:0
+#: field:ir.property,value_binary:0
+#: field:ir.property,value_datetime:0
+#: field:ir.property,value_float:0
+#: field:ir.property,value_integer:0
+#: field:ir.property,value_reference:0
+#: field:ir.property,value_text:0
+#: selection:ir.server.object.lines,type:0
+#: field:ir.server.object.lines,value:0
+#: view:ir.values:0
+#: field:ir.values,value:0
+#: field:ir.values,value_unpickle:0
+msgid "Value"
+msgstr ""
+
+#. module: base
+#: field:ir.sequence,code:0
+#: field:ir.sequence.type,code:0
+#: selection:ir.translation,type:0
+#: field:res.bank,code:0
+#: field:res.partner.bank.type,code:0
+msgid "Code"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_config_installer
+msgid "res.config.installer"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mc
+msgid "Monaco"
+msgstr ""
+
+#. module: base
+#: selection:ir.cron,interval_type:0
+msgid "Minutes"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Help"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,menu_id:0
+#: help:res.users,menu_id:0
+msgid ""
+"If specified, the action will replace the standard menu for this user."
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.server,state:0
+msgid "Write Object"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_fundrising
+msgid "Fund Raising"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_sequence_type
+#: model:ir.ui.menu,name:base.menu_ir_sequence_type
+msgid "Sequence Codes"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (CO) / Español (CO)"
+msgstr ""
+
+#. module: base
+#: view:base.module.configuration:0
+msgid ""
+"All pending configuration wizards have been executed. You may restart "
+"individual wizards via the list of configuration wizards."
+msgstr ""
+
+#. module: base
+#: wizard_button:server.action.create,step_1,create:0
+msgid "Create"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Current Year with Century: %(year)s"
+msgstr ""
+
+#. module: base
+#: field:ir.exports,export_fields:0
+msgid "Export ID"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.fr
+msgid "France"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_log
+msgid "res.log"
+msgstr ""
+
+#. module: base
+#: help:ir.translation,module:0
+#: help:ir.translation,xml_id:0
+msgid "Maps to the ir_model_data for which this translation is provided."
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+#: field:workflow.activity,flow_stop:0
+msgid "Flow Stop"
+msgstr ""
+
+#. module: base
+#: selection:ir.cron,interval_type:0
+msgid "Weeks"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.af
+msgid "Afghanistan, Islamic State of"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_module_import.py:67
+#, python-format
+msgid "Error !"
+msgstr ""
+
+#. module: base
+#: model:res.partner.bank.type.field,name:base.bank_normal_field_contry
+msgid "country_id"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,interval_type:0
+msgid "Interval Unit"
+msgstr ""
+
+#. module: base
+#: field:publisher_warranty.contract,kind:0
+#: field:workflow.activity,kind:0
+msgid "Kind"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3775
+#, python-format
+msgid "This method does not exist anymore"
+msgstr ""
+
+#. module: base
+#: field:res.bank,fax:0
+#: field:res.partner.address,fax:0
+msgid "Fax"
+msgstr ""
+
+#. module: base
+#: field:res.lang,thousands_sep:0
+msgid "Thousands Separator"
+msgstr ""
+
+#. module: base
+#: field:res.request,create_date:0
+msgid "Created Date"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,loop_action:0
+msgid ""
+"Select the action that will be executed. Loop action will not be avaliable "
+"inside loop."
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Chinese (TW) / 正體字"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_request
+msgid "res.request"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+msgid "In Memory"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.todo:0
+msgid "Todo"
+msgstr ""
+
+#. module: base
+#: field:ir.attachment,datas:0
+msgid "File Content"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pa
+msgid "Panama"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,name:base.res_partner_title_ltd
+msgid "Ltd"
+msgstr ""
+
+#. module: base
+#: help:workflow.transition,group_id:0
+msgid ""
+"The group that a user must have to be authorized to validate this transition."
+msgstr ""
+
+#. module: base
+#: constraint:res.config.users:0
+#: constraint:res.users:0
+msgid "The chosen company is not in the allowed companies for this user"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gi
+msgid "Gibraltar"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_name:0
+msgid "Service Name"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pn
+msgid "Pitcairn Island"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid ""
+"We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_rule
+#: model:ir.ui.menu,name:base.menu_action_rule
+msgid "Record Rules"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,name:0
+#: field:res.users,name:0
+msgid "User Name"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Day of the year: %(doy)s"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+#: view:ir.model.fields:0
+#: view:workflow.activity:0
+msgid "Properties"
+msgstr ""
+
+#. module: base
+#: help:ir.sequence,padding:0
+msgid ""
+"OpenERP will automatically adds some '0' on the left of the 'Next Number' to "
+"get the required padding size."
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%A - Full weekday name."
+msgstr ""
+
+#. module: base
+#: selection:ir.cron,interval_type:0
+msgid "Months"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,search_view:0
+msgid "Search View"
+msgstr ""
+
+#. module: base
+#: sql_constraint:res.lang:0
+msgid "The code of the language must be unique !"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_attachment
+#: view:ir.actions.report.xml:0
+#: view:ir.attachment:0
+#: model:ir.ui.menu,name:base.menu_action_attachment
+msgid "Attachments"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_base_partner
+#: model:ir.ui.menu,name:base.menu_sale_config_sales
+#: model:ir.ui.menu,name:base.menu_sales
+msgid "Sales"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,child_ids:0
+msgid "Other Actions"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.todo,state:0
+#: view:res.config.users:0
+msgid "Done"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,name:base.res_partner_title_miss
+msgid "Miss"
+msgstr ""
+
+#. module: base
+#: view:ir.model.access:0
+#: field:ir.model.access,perm_write:0
+#: view:ir.rule:0
+msgid "Write Access"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%m - Month number [01,12]."
+msgstr ""
+
+#. module: base
+#: field:res.bank,city:0
+#: field:res.partner,city:0
+#: field:res.partner.address,city:0
+#: field:res.partner.bank,city:0
+msgid "City"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.qa
+msgid "Qatar"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.it
+msgid "Italy"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.todo:0
+#: selection:ir.actions.todo,state:0
+msgid "To Do"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Estonian / Eesti keel"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,email:0
+#: field:res.partner,email:0
+#: field:res.users,email:0
+msgid "E-mail"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "GPL-3 or later version"
+msgstr ""
+
+#. module: base
+#: field:workflow.activity,action:0
+msgid "Python Action"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "English (US)"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_model_data
+#: view:ir.model.data:0
+#: model:ir.ui.menu,name:base.ir_model_data_menu
+msgid "Object Identifiers"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_partner_title_partner
+msgid ""
+"Manage the partner titles you want to have available in your system. The "
+"partner titles is the legal status of the company: Private Limited, SA, etc."
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+msgid "To browse official translations, you can start with these links:"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:484
+#, python-format
+msgid ""
+"You can not read this document (%s) ! Be sure your user belongs to one of "
+"these groups: %s."
+msgstr ""
+
+#. module: base
+#: view:res.bank:0
+#: field:res.config.users,address_id:0
+#: view:res.partner.address:0
+#: view:res.users:0
+#: field:res.users,address_id:0
+msgid "Address"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,latest_version:0
+msgid "Installed version"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Mongolian / монгол"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mr
+msgid "Mauritania"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_translation
+msgid "ir.translation"
+msgstr ""
+
+#. module: base
+#: view:base.module.update:0
+msgid "Module update result"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+#: field:workflow.workitem,act_id:0
+msgid "Activity"
+msgstr ""
+
+#. module: base
+#: view:res.partner:0
+#: view:res.partner.address:0
+msgid "Postal Address"
+msgstr ""
+
+#. module: base
+#: field:res.company,parent_id:0
+msgid "Parent Company"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (CR) / Español (CR)"
+msgstr ""
+
+#. module: base
+#: field:res.currency.rate,rate:0
+msgid "Rate"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cg
+msgid "Congo"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "Examples"
+msgstr ""
+
+#. module: base
+#: field:ir.default,value:0
+msgid "Default Value"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_tools
+msgid "Tools"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.kn
+msgid "Saint Kitts & Nevis Anguilla"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_currency.py:100
+#, python-format
+msgid ""
+"No rate found \n"
+"for the currency: %s \n"
+"at the date: %s"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_ui_view_custom
+msgid ""
+"Customized views are used when users reorganize the content of their "
+"dashboard views (via web client)"
+msgstr ""
+
+#. module: base
+#: field:ir.model,name:0
+#: field:ir.model.fields,model:0
+#: field:ir.values,model:0
+msgid "Object Name"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,srcmodel_id:0
+msgid ""
+"Object in which you want to create / write the object. If it is empty then "
+"refer to the Object field."
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+#: selection:ir.module.module,state:0
+#: selection:ir.module.module.dependency,state:0
+msgid "Not Installed"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+#: field:workflow.activity,out_transitions:0
+msgid "Outgoing Transitions"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,icon:0
+msgid "Icon"
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,model_id:0
+msgid "The model this field belongs to"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.mq
+msgid "Martinique (French)"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence.type:0
+msgid "Sequences Type"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.res_request-act
+#: model:ir.ui.menu,name:base.menu_res_request_act
+#: model:ir.ui.menu,name:base.menu_resquest_ref
+#: view:res.request:0
+msgid "Requests"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ye
+msgid "Yemen"
+msgstr ""
+
+#. module: base
+#: selection:workflow.activity,split_mode:0
+msgid "Or"
+msgstr ""
+
+#. module: base
+#: 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 ""
+
+#. module: base
+#: model:res.country,name:base.al
+msgid "Albania"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ws
+msgid "Samoa"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_lang.py:161
+#, python-format
+msgid ""
+"You cannot delete the language which is Active !\n"
+"Please de-activate the language first."
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+#: view:base.module.import:0
+msgid ""
+"Please be patient, this operation may take a few minutes (depending on the "
+"number of modules currently installed)..."
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,child_id:0
+msgid "Child IDs"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_actions.py:713
+#: code:addons/base/ir/ir_actions.py:716
+#, python-format
+msgid "Problem in configuration `Record Id` in Server Action!"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:2306
+#: code:addons/orm.py:2316
+#, python-format
+msgid "ValidateError"
+msgstr ""
+
+#. module: base
+#: view:base.module.import:0
+#: view:base.module.update:0
+msgid "Open Modules"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_res_bank_form
+msgid "Manage bank records you want to be used in the system."
+msgstr ""
+
+#. module: base
+#: view:base.module.import:0
+msgid "Import module"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,loop_action:0
+msgid "Loop Action"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.report.xml,report_file:0
+msgid ""
+"The path to the main report file (depending on Report Type) or NULL if the "
+"content is in another field"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.la
+msgid "Laos"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.server,state:0
+#: field:res.config.users,user_email:0
+#: field:res.users,user_email:0
+msgid "Email"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,action_id:0
+#: field:res.users,action_id:0
+msgid "Home Action"
+msgstr ""
+
+#. module: base
+#: code:addons/custom.py:558
+#, python-format
+msgid ""
+"The sum of the data (2nd field) is null.\n"
+"We can't draw a pie chart !"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_lunch_reporting
+#: model:ir.ui.menu,name:base.menu_project_report
+#: model:ir.ui.menu,name:base.menu_report_association
+#: model:ir.ui.menu,name:base.menu_report_marketing
+#: model:ir.ui.menu,name:base.menu_reporting
+#: model:ir.ui.menu,name:base.next_id_64
+#: model:ir.ui.menu,name:base.next_id_73
+#: model:ir.ui.menu,name:base.reporting_menu
+msgid "Reporting"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tg
+msgid "Togo"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "Other Proprietary"
+msgstr ""
+
+#. module: base
+#: selection:workflow.activity,kind:0
+msgid "Stop All"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:412
+#, python-format
+msgid "The read_group method is not implemented on this object !"
+msgstr ""
+
+#. module: base
+#: view:ir.model.data:0
+msgid "Updatable"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "3. %x ,%X ==> 12/05/08, 18:25:20"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,on_delete:0
+msgid "Cascade"
+msgstr ""
+
+#. module: base
+#: field:workflow.transition,group_id:0
+msgid "Group Required"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.configuration.wizard:0
+msgid "Next Configuration Step"
+msgstr ""
+
+#. module: base
+#: field:res.groups,comment:0
+msgid "Comment"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ro
+msgid "Romania"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,doall:0
+msgid ""
+"Enable this if you want to execute missed occurences as soon as the server "
+"restarts."
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "Start update"
+msgstr ""
+
+#. module: base
+#: code:addons/base/publisher_warranty/publisher_warranty.py:144
+#, python-format
+msgid "Contract validation error"
+msgstr ""
+
+#. module: base
+#: field:res.country.state,name:0
+msgid "State Name"
+msgstr ""
+
+#. module: base
+#: field:workflow.activity,join_mode:0
+msgid "Join Mode"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,context_tz:0
+#: field:res.users,context_tz:0
+msgid "Timezone"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_report_xml
+#: selection:ir.ui.menu,action:0
+msgid "ir.actions.report.xml"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,shortcut:base.res_partner_title_miss
+msgid "Mss"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_ui_view
+msgid "ir.ui.view"
+msgstr ""
+
+#. module: base
+#: constraint:res.partner:0
+msgid "Error ! You can not create recursive associated members."
+msgstr ""
+
+#. module: base
+#: help:res.lang,code:0
+msgid "This field is used to set/get locales for user"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_2
+msgid "OpenERP Partners"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_hr_manager
+msgid "HR Manager Dashboard"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:253
+#, python-format
+msgid ""
+"Unable to install module \"%s\" because an external dependency is not met: %s"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Search modules"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.by
+msgid "Belarus"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,name:0
+#: field:ir.actions.act_window_close,name:0
+#: field:ir.actions.actions,name:0
+#: field:ir.actions.server,name:0
+#: field:ir.actions.url,name:0
+#: field:ir.filters,name:0
+msgid "Action Name"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_res_users
+msgid ""
+"Create and manage users that will connect to the system. Users can be "
+"deactivated should there be a period of time during which they will/should "
+"not connect to the system. You can assign them groups in order to give them "
+"specific access to the applications they need to use in the system."
+msgstr ""
+
+#. module: base
+#: selection:res.request,priority:0
+msgid "Normal"
+msgstr ""
+
+#. module: base
+#: field:res.bank,street2:0
+#: field:res.partner.address,street2:0
+msgid "Street2"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_view_base_module_update
+msgid "Module Update"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_module_upgrade.py:95
+#, python-format
+msgid "Following modules are not installed or unknown: %s"
+msgstr ""
+
+#. module: base
+#: view:ir.cron:0
+#: field:ir.cron,user_id:0
+#: view:ir.filters:0
+#: field:ir.filters,user_id:0
+#: field:ir.ui.view.custom,user_id:0
+#: field:ir.values,user_id:0
+#: field:res.log,user_id:0
+#: field:res.partner.event,user_id:0
+#: view:res.users:0
+#: field:res.widget.user,user_id:0
+msgid "User"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pr
+msgid "Puerto Rico"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+msgid "Open Window"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,auto_search:0
+msgid "Auto Search"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,filter:0
+msgid "Filter"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,shortcut:base.res_partner_title_madam
+msgid "Ms."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ch
+msgid "Switzerland"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gd
+msgid "Grenada"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.wf
+msgid "Wallis and Futuna Islands"
+msgstr ""
+
+#. module: base
+#: selection:server.action.create,init,type:0
+msgid "Open Report"
+msgstr ""
+
+#. module: base
+#: field:res.currency,rounding:0
+msgid "Rounding factor"
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+msgid "Load"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,name:0
+#: help:res.users,name:0
+msgid "The new user's real name, used for searching and most listings"
+msgstr ""
+
+#. module: base
+#: code:addons/osv.py:154
+#: code:addons/osv.py:156
+#, python-format
+msgid "Integrity Error"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_wizard_screen
+msgid "ir.wizard.screen"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:223
+#, python-format
+msgid "Size of the field can never be less than 1 !"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.so
+msgid "Somalia"
+msgstr ""
+
+#. module: base
+#: selection:publisher_warranty.contract,state:0
+msgid "Terminated"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_13
+msgid "Important customers"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "Update Terms"
+msgstr ""
+
+#. module: base
+#: field:partner.sms.send,mobile_to:0
+#: field:res.request,act_to:0
+#: field:res.request.history,act_to:0
+msgid "To"
+msgstr ""
+
+#. module: base
+#: view:ir.cron:0
+#: field:ir.cron,args:0
+msgid "Arguments"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:716
+#, python-format
+msgid "Database ID doesn't exist: %s : %s"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "GPL Version 2"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,license:0
+msgid "GPL Version 3"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:836
+#, python-format
+msgid "key '%s' not found in selection field '%s'"
+msgstr ""
+
+#. module: base
+#: view:partner.wizard.ean.check:0
+msgid "Correct EAN13"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:2317
+#, python-format
+msgid "The value \"%s\" for the field \"%s\" is not in the selection"
+msgstr ""
+
+#. module: base
+#: field:res.partner,customer:0
+#: view:res.partner.address:0
+#: field:res.partner.address,is_customer_add:0
+#: model:res.partner.category,name:base.res_partner_category_0
+msgid "Customer"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (NI) / Español (NI)"
+msgstr ""
+
+#. module: base
+#: field:ir.module.module,shortdesc:0
+msgid "Short Description"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,context:0
+#: field:ir.filters,context:0
+msgid "Context Value"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Hour 00->24: %(h24)s"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,nextcall:0
+msgid "Next Execution Date"
+msgstr ""
+
+#. module: base
+#: help:multi_company.default,field_id:0
+msgid "Select field property"
+msgstr ""
+
+#. module: base
+#: field:res.request.history,date_sent:0
+msgid "Date sent"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Month: %(month)s"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window.view,sequence:0
+#: field:ir.actions.server,sequence:0
+#: field:ir.actions.todo,sequence:0
+#: view:ir.cron:0
+#: view:ir.sequence:0
+#: field:ir.ui.menu,sequence:0
+#: view:ir.ui.view:0
+#: field:ir.ui.view,priority:0
+#: field:ir.ui.view_sc,sequence:0
+#: field:multi_company.default,sequence:0
+#: field:res.partner.bank,sequence:0
+#: field:res.widget.user,sequence:0
+#: field:wizard.ir.model.menu.create.line,sequence:0
+msgid "Sequence"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tn
+msgid "Tunisia"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_mrp_root
+msgid "Manufacturing"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.km
+msgid "Comoros"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_server_action
+#: view:ir.actions.server:0
+#: model:ir.ui.menu,name:base.menu_server_action
+msgid "Server Actions"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Cancel Install"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,selection:0
+msgid "Selection Options"
+msgstr ""
+
+#. module: base
+#: field:res.partner.category,parent_right:0
+msgid "Right parent"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "Legends for Date and Time Formats"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.server,state:0
+msgid "Copy Object"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:581
+#, python-format
+msgid ""
+"Group(s) cannot be deleted, because some user(s) still belong to them: %s !"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_country_state
+#: model:ir.ui.menu,name:base.menu_country_state_partner
+msgid "Fed. States"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+#: view:res.groups:0
+msgid "Access Rules"
+msgstr ""
+
+#. module: base
+#: field:ir.default,ref_table:0
+msgid "Table Ref."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,res_model:0
+#: field:ir.actions.report.xml,model:0
+#: field:ir.actions.server,model_id:0
+#: field:ir.actions.wizard,model:0
+#: field:ir.cron,model:0
+#: field:ir.default,field_tbl:0
+#: field:ir.filters,model_id:0
+#: field:ir.model,model:0
+#: view:ir.model.access:0
+#: field:ir.model.access,model_id:0
+#: view:ir.model.data:0
+#: field:ir.model.data,model:0
+#: view:ir.model.fields:0
+#: view:ir.rule:0
+#: field:ir.rule,model_id:0
+#: selection:ir.translation,type:0
+#: view:ir.ui.view:0
+#: field:ir.ui.view,model:0
+#: view:ir.values:0
+#: field:ir.values,model_id:0
+#: field:multi_company.default,object_id:0
+#: field:res.log,res_model:0
+#: field:res.request.link,object:0
+#: field:workflow.triggers,model:0
+msgid "Object"
+msgstr ""
+
+#. module: base
+#: code:addons/osv.py:151
+#, python-format
+msgid ""
+"\n"
+"\n"
+"[object with reference: %s - %s]"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_default
+msgid "ir.default"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Minute: %(min)s"
+msgstr ""
+
+#. module: base
+#: view:base.update.translations:0
+#: model:ir.actions.act_window,name:base.action_wizard_update_translations
+#: model:ir.ui.menu,name:base.menu_wizard_update_translations
+msgid "Synchronize Translations"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.next_id_10
+msgid "Scheduler"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,numbercall:0
+msgid ""
+"Number of time the function is called,\n"
+"a negative number indicates no limit"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:331
+#, python-format
+msgid ""
+"Changing the type of a column is not yet supported. Please drop it and "
+"create it again!"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view_sc,user_id:0
+msgid "User Ref."
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:580
+#, python-format
+msgid "Warning !"
+msgstr ""
+
+#. module: base
+#: model:res.widget,title:base.google_maps_widget
+msgid "Google Maps"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_base_config
+#: model:ir.ui.menu,name:base.menu_config
+#: model:ir.ui.menu,name:base.menu_event_config
+#: model:ir.ui.menu,name:base.menu_lunch_survey_root
+#: model:ir.ui.menu,name:base.menu_marketing_config_association
+#: model:ir.ui.menu,name:base.menu_marketing_config_root
+#: view:res.company:0
+msgid "Configuration"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_publisher_warranty_contract_wizard
+msgid "publisher_warranty.contract.wizard"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,expression:0
+msgid "Loop Expression"
+msgstr ""
+
+#. module: base
+#: field:publisher_warranty.contract,date_start:0
+msgid "Starting Date"
+msgstr ""
+
+#. module: base
+#: help:res.partner,website:0
+msgid "Website of Partner"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_5
+msgid "Gold Partner"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner
+#: field:res.company,partner_id:0
+#: view:res.partner.address:0
+#: field:res.partner.bank,partner_id:0
+#: field:res.partner.event,partner_id:0
+#: selection:res.partner.title,domain:0
+#: model:res.request.link,name:base.req_link_partner
+msgid "Partner"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tr
+msgid "Turkey"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.fk
+msgid "Falkland Islands"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lb
+msgid "Lebanon"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.report.xml:0
+#: field:ir.actions.report.xml,report_type:0
+msgid "Report Type"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.todo,state:0
+#: view:ir.module.module:0
+#: field:ir.module.module,state:0
+#: field:ir.module.module.dependency,state:0
+#: field:publisher_warranty.contract,state:0
+#: field:res.bank,state:0
+#: view:res.country.state:0
+#: field:res.partner.bank,state_id:0
+#: view:res.request:0
+#: field:res.request,state:0
+#: field:workflow.instance,state:0
+#: field:workflow.workitem,state:0
+msgid "State"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Galician / Galego"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.no
+msgid "Norway"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "4. %b, %B ==> Dec, December"
+msgstr ""
+
+#. module: base
+#: view:base.language.install:0
+#: model:ir.ui.menu,name:base.menu_view_base_language_install
+msgid "Load an Official Translation"
+msgstr ""
+
+#. module: base
+#: view:res.currency:0
+msgid "Miscelleanous"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_10
+msgid "Open Source Service Company"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.kg
+msgid "Kyrgyz Republic (Kyrgyzstan)"
+msgstr ""
+
+#. module: base
+#: selection:res.request,state:0
+msgid "waiting"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_file:0
+msgid "Report file"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_workflow_triggers
+msgid "workflow.triggers"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:62
+#, python-format
+msgid "Invalid search criterions"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+msgid "Created"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.wizard,multi:0
+msgid ""
+"If set to true, the wizard will not be displayed on the right toolbar of a "
+"form view."
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid "- type,name,res_id,src,value"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.hm
+msgid "Heard and McDonald Islands"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,view_id:0
+msgid "View Ref."
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Selection"
+msgstr ""
+
+#. module: base
+#: field:res.company,rml_header1:0
+msgid "Report Header"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,type:0
+#: field:ir.actions.act_window_close,type:0
+#: field:ir.actions.actions,type:0
+#: field:ir.actions.report.xml,type:0
+#: view:ir.actions.server:0
+#: field:ir.actions.server,state:0
+#: field:ir.actions.server,type:0
+#: field:ir.actions.url,type:0
+#: field:ir.actions.wizard,type:0
+msgid "Action Type"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/module.py:268
+#, python-format
+msgid ""
+"You try to install module '%s' that depends on module '%s'.\n"
+"But the latter module is not available in your system."
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+#: model:ir.actions.act_window,name:base.action_view_base_import_language
+#: model:ir.ui.menu,name:base.menu_view_base_import_language
+msgid "Import Translation"
+msgstr ""
+
+#. module: base
+#: field:res.partner.bank.type,field_ids:0
+msgid "Type fields"
+msgstr ""
+
+#. module: base
+#: view:ir.module.module:0
+#: field:ir.module.module,category_id:0
+msgid "Category"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+#: selection:ir.attachment,type:0
+#: selection:ir.property,type:0
+msgid "Binary"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,sms:0
+#: selection:ir.actions.server,state:0
+msgid "SMS"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cr
+msgid "Costa Rica"
+msgstr ""
+
+#. module: base
+#: view:workflow.activity:0
+msgid "Conditions"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_other_form
+msgid "Other Partners"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_currency_form
+#: model:ir.ui.menu,name:base.menu_action_currency_form
+#: view:res.currency:0
+msgid "Currencies"
+msgstr ""
+
+#. module: base
+#: sql_constraint:res.groups:0
+msgid "The name of the group must be unique !"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Hour 00->12: %(h12)s"
+msgstr ""
+
+#. module: base
+#: help:res.partner.address,active:0
+msgid "Uncheck the active field to hide the contact."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_widget_wizard
+msgid "Add a widget for User"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.dk
+msgid "Denmark"
+msgstr ""
+
+#. module: base
+#: field:res.country,code:0
+msgid "Country Code"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_workflow_instance
+msgid "workflow.instance"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:278
+#, python-format
+msgid "Unknown attribute %s in %s "
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "10. %S ==> 20"
+msgstr ""
+
+#. module: base
+#: code:addons/fields.py:106
+#, python-format
+msgid "undefined get method !"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Norwegian Bokmål / Norsk bokmål"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,new_password:0
+#: help:res.users,new_password:0
+msgid ""
+"Only specify a value if you want to change the user password. This user will "
+"have to logout and login again!"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,name:base.res_partner_title_madam
+msgid "Madam"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ee
+msgid "Estonia"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.dashboard
+msgid "Dashboards"
+msgstr ""
+
+#. module: base
+#: help:ir.attachment,type:0
+msgid "Binary File or external URL"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,new_password:0
+#: field:res.users,new_password:0
+msgid "Change password"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nl
+msgid "Netherlands"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.next_id_4
+msgid "Low Level Objects"
+msgstr ""
+
+#. module: base
+#: view:res.company:0
+msgid "Your Logo - Use a size of about 450x150 pixels."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_values
+msgid "ir.values"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Occitan (FR, post 1500) / Occitan"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.open_module_tree
+msgid ""
+"You can install new modules in order to activate new features, menu, reports "
+"or data in your OpenERP instance. To install some modules, click on the "
+"button \"Schedule for Installation\" from the form view, then click on "
+"\"Apply Scheduled Upgrades\" to migrate your system."
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_emails
+#: model:ir.ui.menu,name:base.menu_mail_gateway
+msgid "Emails"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cd
+msgid "Congo, The Democratic Republic of the"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Malayalam / മലയാളം"
+msgstr ""
+
+#. module: base
+#: view:res.request:0
+#: field:res.request,body:0
+#: field:res.request.history,req_id:0
+msgid "Request"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.jp
+msgid "Japan"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,numbercall:0
+msgid "Number of Calls"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+#: field:base.module.upgrade,module_info:0
+msgid "Modules to update"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,sequence:0
+msgid ""
+"Important when you deal with multiple actions, the execution order will be "
+"decided based on this, low number is higher priority."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,header:0
+msgid "Add RML header"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gr
+msgid "Greece"
+msgstr ""
+
+#. module: base
+#: field:res.request,trigger_date:0
+msgid "Trigger Date"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Croatian / hrvatski jezik"
+msgstr ""
+
+#. module: base
+#: field:base.language.install,overwrite:0
+msgid "Overwrite Existing Terms"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,code:0
+msgid "Python code to be executed"
+msgstr ""
+
+#. module: base
+#: sql_constraint:res.country:0
+msgid "The code of the country must be unique !"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module.dependency,state:0
+msgid "Uninstallable"
+msgstr ""
+
+#. module: base
+#: view:res.partner.category:0
+msgid "Partner Category"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+#: selection:ir.actions.server,state:0
+msgid "Trigger"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_module_update
+msgid "Update Module"
+msgstr ""
+
+#. module: base
+#: view:ir.model.fields:0
+#: field:ir.model.fields,translate:0
+msgid "Translate"
+msgstr ""
+
+#. module: base
+#: field:res.request.history,body:0
+msgid "Body"
+msgstr ""
+
+#. module: base
+#: view:partner.wizard.spam:0
+msgid "Send Email"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,menu_id:0
+#: field:res.users,menu_id:0
+msgid "Menu Action"
+msgstr ""
+
+#. module: base
+#: help:ir.model.fields,selection:0
+msgid ""
+"List of options for a selection field, specified as a Python expression "
+"defining a list of (key, label) pairs. For example: "
+"[('blue','Blue'),('yellow','Yellow')]"
+msgstr ""
+
+#. module: base
+#: selection:base.language.export,state:0
+msgid "choose"
+msgstr ""
+
+#. module: base
+#: help:ir.model,osv_memory:0
+msgid ""
+"Indicates whether this object model lives in memory only, i.e. is not "
+"persisted (osv.osv_memory)"
+msgstr ""
+
+#. module: base
+#: field:res.partner,child_ids:0
+#: field:res.request,ref_partner_id:0
+msgid "Partner Ref."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_supplier_form
+#: model:ir.ui.menu,name:base.menu_procurement_management_supplier_name
+#: view:res.partner:0
+msgid "Suppliers"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract.wizard:0
+msgid "Register"
+msgstr ""
+
+#. module: base
+#: field:res.request,ref_doc2:0
+msgid "Document Ref 2"
+msgstr ""
+
+#. module: base
+#: field:res.request,ref_doc1:0
+msgid "Document Ref 1"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ga
+msgid "Gabon"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_model_data
+msgid "ir.model.data"
+msgstr ""
+
+#. module: base
+#: view:ir.model:0
+#: view:ir.rule:0
+#: view:res.groups:0
+msgid "Access Rights"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gl
+msgid "Greenland"
+msgstr ""
+
+#. module: base
+#: field:res.partner.bank,acc_number:0
+msgid "Account Number"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "1. %c ==> Fri Dec 5 18:25:20 2008"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.nc
+msgid "New Caledonia (French)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cy
+msgid "Cyprus"
+msgstr ""
+
+#. module: base
+#: view:base.module.import:0
+msgid ""
+"This wizard helps you add a new language to you OpenERP system. After "
+"loading a new language it becomes available as default interface language "
+"for users and partners."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,subject:0
+#: field:partner.wizard.spam,subject:0
+#: field:res.request,name:0
+msgid "Subject"
+msgstr ""
+
+#. module: base
+#: field:res.request,act_from:0
+#: field:res.request.history,act_from:0
+msgid "From"
+msgstr ""
+
+#. module: base
+#: view:res.users:0
+msgid "Preferences"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_consumers0
+msgid "Consumers"
+msgstr ""
+
+#. module: base
+#: view:res.config:0
+#: wizard_button:server.action.create,init,step_1:0
+msgid "Next"
+msgstr ""
+
+#. module: base
+#: help:ir.cron,function:0
+msgid ""
+"Name of the method to be called on the object when this scheduler is "
+"executed."
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:219
+#, python-format
+msgid ""
+"The Selection Options expression is must be in the [('key','Label'), ...] "
+"format!"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.report.xml:0
+msgid "Miscellaneous"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cn
+msgid "China"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:516
+#, python-format
+msgid ""
+"--\n"
+"%(name)s %(email)s\n"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.eh
+msgid "Western Sahara"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_workflow
+msgid "workflow"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_res_company_form
+msgid ""
+"Create and manage the companies that will be managed by OpenERP from here. "
+"Shops or subsidiaries can be created and maintained from here."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.id
+msgid "Indonesia"
+msgstr ""
+
+#. module: base
+#: view:base.update.translations:0
+msgid ""
+"This wizard will detect new terms to translate in the application, so that "
+"you can then add translations manually or perform a complete export (as a "
+"template for a new language example)."
+msgstr ""
+
+#. module: base
+#: help:multi_company.default,expression:0
+msgid ""
+"Expression, must be True to match\n"
+"use context.get or user (browse)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bg
+msgid "Bulgaria"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract.wizard:0
+msgid "Publisher warranty contract successfully registered!"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ao
+msgid "Angola"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tf
+msgid "French Southern Territories"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_currency
+#: field:res.company,currency_id:0
+#: field:res.company,currency_ids:0
+#: view:res.currency:0
+#: field:res.currency,name:0
+#: field:res.currency.rate,currency_id:0
+msgid "Currency"
+msgstr ""
+
+#. module: base
+#: field:res.partner.canal,name:0
+msgid "Channel Name"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "5. %y, %Y ==> 08, 2008"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,shortcut:base.res_partner_title_ltd
+msgid "ltd"
+msgstr ""
+
+#. module: base
+#: field:ir.values,res_id:0
+#: field:res.log,res_id:0
+msgid "Object ID"
+msgstr ""
+
+#. module: base
+#: view:res.company:0
+msgid "Landscape"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_administration
+msgid "Administration"
+msgstr ""
+
+#. module: base
+#: view:base.module.update:0
+msgid "Click on Update below to start the process..."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ir
+msgid "Iran"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.res_widget_user_act_window
+#: model:ir.ui.menu,name:base.menu_res_widget_user_act_window
+msgid "Widgets per User"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Slovak / Slovenský jazyk"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,state:0
+#: field:ir.ui.menu,icon_pict:0
+#: field:publisher_warranty.contract.wizard,state:0
+msgid "unknown"
+msgstr ""
+
+#. module: base
+#: field:res.currency,symbol:0
+msgid "Symbol"
+msgstr ""
+
+#. module: base
+#: help:res.config.users,login:0
+#: help:res.users,login:0
+msgid "Used to log into the system"
+msgstr ""
+
+#. module: base
+#: view:base.update.translations:0
+msgid "Synchronize Translation"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view_sc,res_id:0
+msgid "Resource Ref."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ki
+msgid "Kiribati"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.iq
+msgid "Iraq"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_association
+msgid "Association"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cl
+msgid "Chile"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_address_book
+#: model:ir.ui.menu,name:base.menu_config_address_book
+#: model:ir.ui.menu,name:base.menu_procurement_management_supplier
+msgid "Address Book"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_sequence_type
+msgid "ir.sequence.type"
+msgstr ""
+
+#. module: base
+#: selection:base.language.export,format:0
+msgid "CSV File"
+msgstr ""
+
+#. module: base
+#: field:res.company,account_no:0
+msgid "Account No."
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_lang.py:157
+#, python-format
+msgid "Base Language 'en_US' can not be deleted !"
+msgstr ""
+
+#. module: base
+#: selection:ir.model,state:0
+msgid "Base Object"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "Dependencies :"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,field_description:0
+msgid "Field Label"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.dj
+msgid "Djibouti"
+msgstr ""
+
+#. module: base
+#: field:ir.translation,value:0
+msgid "Translation Value"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ag
+msgid "Antigua and Barbuda"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:3166
+#, python-format
+msgid ""
+"Operation prohibited by access rules, or performed on an already deleted "
+"document (Operation: %s, Document type: %s)."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.zr
+msgid "Zaire"
+msgstr ""
+
+#. module: base
+#: field:ir.model.data,res_id:0
+#: field:ir.translation,res_id:0
+#: field:workflow.instance,res_id:0
+#: field:workflow.triggers,res_id:0
+msgid "Resource ID"
+msgstr ""
+
+#. module: base
+#: view:ir.cron:0
+#: field:ir.model,info:0
+msgid "Information"
+msgstr ""
+
+#. module: base
+#: view:res.widget.user:0
+msgid "User Widgets"
+msgstr ""
+
+#. module: base
+#: view:base.module.update:0
+msgid "Update Module List"
+msgstr ""
+
+#. module: base
+#: selection:res.partner.address,type:0
+msgid "Other"
+msgstr ""
+
+#. module: base
+#: view:res.request:0
+msgid "Reply"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Turkish / Türkçe"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_workflow_activity_form
+#: model:ir.ui.menu,name:base.menu_workflow_activity
+#: view:workflow:0
+#: field:workflow,activities:0
+msgid "Activities"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,auto_refresh:0
+msgid "Auto-Refresh"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:62
+#, python-format
+msgid "The osv_memory field can only be compared with = and != operator."
+msgstr ""
+
+#. module: base
+#: selection:ir.ui.view,type:0
+msgid "Diagram"
+msgstr ""
+
+#. module: base
+#: help:multi_company.default,name:0
+msgid "Name it to easily find a record"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.grant_menu_access
+#: model:ir.ui.menu,name:base.menu_grant_menu_access
+msgid "Menu Items"
+msgstr ""
+
+#. module: base
+#: constraint:ir.rule:0
+msgid "Rules are not supported for osv_memory objects !"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_event_association
+#: model:ir.ui.menu,name:base.menu_event_main
+msgid "Events Organisation"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.ir_sequence_actions
+#: model:ir.ui.menu,name:base.menu_custom_action
+#: model:ir.ui.menu,name:base.menu_ir_sequence_actions
+#: model:ir.ui.menu,name:base.next_id_6
+#: view:workflow.activity:0
+msgid "Actions"
+msgstr ""
+
+#. module: base
+#: selection:res.request,priority:0
+msgid "High"
+msgstr ""
+
+#. module: base
+#: field:ir.exports.line,export_id:0
+msgid "Export"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.hr
+msgid "Croatia"
+msgstr ""
+
+#. module: base
+#: help:res.bank,bic:0
+msgid "Bank Identifier Code"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tm
+msgid "Turkmenistan"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_actions.py:597
+#: code:addons/base/ir/ir_actions.py:629
+#: code:addons/base/ir/ir_actions.py:713
+#: code:addons/base/ir/ir_actions.py:716
+#: code:addons/base/ir/ir_model.py:114
+#: code:addons/base/ir/ir_model.py:204
+#: code:addons/base/ir/ir_model.py:218
+#: code:addons/base/ir/ir_model.py:232
+#: code:addons/base/ir/ir_model.py:250
+#: code:addons/base/ir/ir_model.py:255
+#: code:addons/base/ir/ir_model.py:258
+#: code:addons/base/module/module.py:215
+#: code:addons/base/module/module.py:258
+#: code:addons/base/module/module.py:262
+#: code:addons/base/module/module.py:268
+#: code:addons/base/module/module.py:303
+#: code:addons/base/module/module.py:321
+#: code:addons/base/module/module.py:336
+#: code:addons/base/module/module.py:429
+#: code:addons/base/module/module.py:531
+#: code:addons/base/publisher_warranty/publisher_warranty.py:163
+#: code:addons/base/publisher_warranty/publisher_warranty.py:281
+#: code:addons/base/res/res_currency.py:100
+#: code:addons/base/res/res_user.py:57
+#: code:addons/base/res/res_user.py:66
+#: code:addons/custom.py:558
+#: code:addons/orm.py:3199
+#, python-format
+msgid "Error"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.pm
+msgid "Saint Pierre and Miquelon"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.report.xml,header:0
+msgid "Add or not the coporate RML header"
+msgstr ""
+
+#. module: base
+#: help:workflow.transition,act_to:0
+msgid "The destination activity."
+msgstr ""
+
+#. module: base
+#: view:base.module.update:0
+#: view:base.update.translations:0
+msgid "Update"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.report.xml,name:base.ir_module_reference_print
+msgid "Technical guide"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tz
+msgid "Tanzania"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Danish / Dansk"
+msgstr ""
+
+#. module: base
+#: selection:ir.model.fields,select_level:0
+msgid "Advanced Search (deprecated)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.cx
+msgid "Christmas Island"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Other Actions Configuration"
+msgstr ""
+
+#. module: base
+#: view:res.config.installer:0
+msgid "Install Modules"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.res_partner_canal-act
+#: model:ir.model,name:base.model_res_partner_canal
+#: model:ir.ui.menu,name:base.menu_res_partner_canal-act
+#: view:res.partner.canal:0
+msgid "Channels"
+msgstr ""
+
+#. module: base
+#: view:ir.ui.view:0
+msgid "Extra Info"
+msgstr ""
+
+#. module: base
+#: 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 ""
+
+#. module: base
+#: view:ir.module.module:0
+msgid "Schedule for Installation"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_partner_wizard_ean_check
+msgid "Ean Check"
+msgstr ""
+
+#. module: base
+#: sql_constraint:res.config.users:0
+#: sql_constraint:res.users:0
+msgid "You can not have two users with the same login !"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_multi_company_default
+msgid "Default multi company"
+msgstr ""
+
+#. module: base
+#: view:res.request:0
+msgid "Send"
+msgstr ""
+
+#. module: base
+#: field:res.config.users,menu_tips:0
+#: field:res.users,menu_tips:0
+msgid "Menu Tips"
+msgstr ""
+
+#. module: base
+#: field:ir.translation,src:0
+msgid "Source"
+msgstr ""
+
+#. module: base
+#: help:res.partner.address,partner_id:0
+msgid "Keep empty for a private address, not related to partner."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.vu
+msgid "Vanuatu"
+msgstr ""
+
+#. module: base
+#: view:res.company:0
+msgid "Internal Header/Footer"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_export_language.py:59
+#, python-format
+msgid ""
+"Save this document to a .tgz file. This archive containt UTF-8 %s files and "
+"may be uploaded to launchpad."
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "Start configuration"
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+msgid "_Export"
+msgstr ""
+
+#. module: base
+#: field:base.language.install,state:0
+#: field:base.module.import,state:0
+#: field:base.module.update,state:0
+msgid "state"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Catalan / Català"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.do
+msgid "Dominican Republic"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Serbian (Cyrillic) / српски"
+msgstr ""
+
+#. module: base
+#: code:addons/orm.py:2161
+#, python-format
+msgid ""
+"Invalid group_by specification: \"%s\".\n"
+"A group_by specification must be a list of valid fields."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sa
+msgid "Saudi Arabia"
+msgstr ""
+
+#. module: base
+#: help:res.partner,supplier:0
+msgid ""
+"Check this box if the partner is a supplier. If it's not checked, purchase "
+"people will not see it when encoding a purchase order."
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,relation_field:0
+msgid "Relation Field"
+msgstr ""
+
+#. module: base
+#: view:res.partner.event:0
+msgid "Event Logs"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_module_configuration.py:37
+#, python-format
+msgid "System Configuration done"
+msgstr ""
+
+#. module: base
+#: field:workflow.triggers,instance_id:0
+msgid "Destination Instance"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,multi:0
+#: field:ir.actions.wizard,multi:0
+msgid "Action on Multiple Doc."
+msgstr ""
+
+#. module: base
+#: view:base.language.export:0
+msgid "https://translations.launchpad.net/openobject"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,report_xml:0
+msgid "XML path"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.todo,restart:0
+msgid "On Skip"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gn
+msgid "Guinea"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lu
+msgid "Luxembourg"
+msgstr ""
+
+#. module: base
+#: help:ir.values,key2:0
+msgid ""
+"The kind of action or button in the client side that will trigger the action."
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_ui_menu.py:285
+#, python-format
+msgid "Error ! You can not create recursive Menu."
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_publisher_warranty_contract_add_wizard
+#: model:ir.ui.menu,name:base.menu_publisher_warranty_contract_add
+#: view:publisher_warranty.contract.wizard:0
+msgid "Register a Contract"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid ""
+"3. If user belongs to several groups, the results from step 2 are combined "
+"with logical OR operator"
+msgstr ""
+
+#. module: base
+#: code:addons/base/publisher_warranty/publisher_warranty.py:145
+#, python-format
+msgid "Please check your publisher warranty contract name and validity."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sv
+msgid "El Salvador"
+msgstr ""
+
+#. module: base
+#: field:res.bank,phone:0
+#: field:res.partner,phone:0
+#: field:res.partner.address,phone:0
+msgid "Phone"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,active:0
+#: field:ir.sequence,active:0
+#: field:res.bank,active:0
+#: field:res.config.users,active:0
+#: field:res.currency,active:0
+#: field:res.lang,active:0
+#: field:res.partner,active:0
+#: field:res.partner.address,active:0
+#: field:res.partner.canal,active:0
+#: field:res.partner.category,active:0
+#: field:res.request,active:0
+#: field:res.users,active:0
+#: view:workflow.instance:0
+#: view:workflow.workitem:0
+msgid "Active"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.th
+msgid "Thailand"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_crm_config_lead
+msgid "Leads & Opportunities"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Romanian / română"
+msgstr ""
+
+#. module: base
+#: view:res.log:0
+msgid "System Logs"
+msgstr ""
+
+#. module: base
+#: selection:workflow.activity,join_mode:0
+#: selection:workflow.activity,split_mode:0
+msgid "And"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,relation:0
+msgid "Object Relation"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+#: view:res.partner:0
+msgid "General"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.uz
+msgid "Uzbekistan"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_act_window
+#: selection:ir.ui.menu,action:0
+msgid "ir.actions.act_window"
+msgstr ""
+
+#. module: base
+#: field:ir.rule,perm_create:0
+msgid "Apply For Create"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.vi
+msgid "Virgin Islands (USA)"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tw
+msgid "Taiwan"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_currency_rate
+msgid "Currency Rate"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.grant_menu_access
+msgid ""
+"Manage and customize the items available and displayed in your OpenERP "
+"system menu. You can delete an item by clicking on the box at the beginning "
+"of each line and then delete it through the button that appeared. Items can "
+"be assigned to specific groups in order to make them accessible to some "
+"users within the system."
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view,field_parent:0
+msgid "Child Field"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,usage:0
+#: field:ir.actions.act_window_close,usage:0
+#: field:ir.actions.actions,usage:0
+#: field:ir.actions.report.xml,usage:0
+#: field:ir.actions.server,usage:0
+#: field:ir.actions.wizard,usage:0
+msgid "Action Usage"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_workflow_workitem
+msgid "workflow.workitem"
+msgstr ""
+
+#. module: base
+#: selection:ir.module.module,state:0
+msgid "Not Installable"
+msgstr ""
+
+#. module: base
+#: report:ir.module.reference.graph:0
+msgid "View :"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,view_load:0
+msgid "View Auto-Load"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:232
+#, python-format
+msgid "You cannot remove the field '%s' !"
+msgstr ""
+
+#. module: base
+#: field:ir.exports,resource:0
+#: view:ir.property:0
+#: field:ir.property,res_id:0
+msgid "Resource"
+msgstr ""
+
+#. module: base
+#: field:ir.ui.menu,web_icon:0
+msgid "Web Icon File"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Persian / فارس"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+msgid "View Ordering"
+msgstr ""
+
+#. module: base
+#: code:addons/base/module/wizard/base_module_upgrade.py:95
+#, python-format
+msgid "Unmet dependency !"
+msgstr ""
+
+#. module: base
+#: view:base.language.import:0
+msgid ""
+"Supported file formats: *.csv (Comma-separated values) or *.po (GetText "
+"Portable Objects)"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:487
+#, python-format
+msgid ""
+"You can not delete this document (%s) ! Be sure your user belongs to one of "
+"these groups: %s."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_base_module_configuration
+msgid "base.module.configuration"
+msgstr ""
+
+#. module: base
+#: field:base.language.export,name:0
+#: field:ir.attachment,datas_fname:0
+msgid "Filename"
+msgstr ""
+
+#. module: base
+#: field:ir.model,access_ids:0
+#: view:ir.model.access:0
+msgid "Access"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sk
+msgid "Slovak Republic"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.publisher_warranty
+msgid "Publisher Warranty"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.aw
+msgid "Aruba"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ar
+msgid "Argentina"
+msgstr ""
+
+#. module: base
+#: field:res.groups,name:0
+msgid "Group Name"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.bh
+msgid "Bahrain"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_12
+msgid "Segmentation"
+msgstr ""
+
+#. module: base
+#: view:ir.attachment:0
+#: field:ir.attachment,company_id:0
+#: field:ir.default,company_id:0
+#: field:ir.property,company_id:0
+#: field:ir.sequence,company_id:0
+#: field:ir.values,company_id:0
+#: view:res.company:0
+#: field:res.config.users,company_id:0
+#: field:res.currency,company_id:0
+#: field:res.partner,company_id:0
+#: field:res.partner.address,company_id:0
+#: view:res.users:0
+#: field:res.users,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: base
+#: view:res.users:0
+msgid "Email & Signature"
+msgstr ""
+
+#. module: base
+#: view:publisher_warranty.contract:0
+msgid "Publisher Warranty Contract"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Bulgarian / български език"
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_aftersale
+msgid "After-Sale Services"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.todo:0
+msgid "Launch"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.act_window,limit:0
+msgid "Limit"
+msgstr ""
+
+#. module: base
+#: help:ir.actions.server,wkf_model_id:0
+msgid "Workflow to be executed on this model."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.jm
+msgid "Jamaica"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_partner_category_form
+msgid ""
+"Manage the partner categories in order to better classify them for tracking "
+"and analysis purposes. A partner may belong to several categories and "
+"categories have a hierarchy structure: a partner belonging to a category "
+"also belong to his parent category."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.az
+msgid "Azerbaijan"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/partner/partner.py:250
+#, python-format
+msgid "Warning"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Arabic / الْعَرَبيّة"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.vg
+msgid "Virgin Islands (British)"
+msgstr ""
+
+#. module: base
+#: view:ir.property:0
+#: model:ir.ui.menu,name:base.next_id_15
+msgid "Parameters"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Czech / Čeština"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Trigger Configuration"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,help:base.action_partner_supplier_form
+msgid ""
+"You can access all information regarding your suppliers from the supplier "
+"form: accounting data, history of emails, meetings, purchases, etc. You can "
+"uncheck the 'Suppliers' filter button in order to search in all your "
+"partners, including customers and prospects."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.rw
+msgid "Rwanda"
+msgstr ""
+
+#. module: base
+#: view:ir.sequence:0
+msgid "Day of the week (0:Monday): %(weekday)s"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.ck
+msgid "Cook Islands"
+msgstr ""
+
+#. module: base
+#: field:ir.model.data,noupdate:0
+msgid "Non Updatable"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Klingon"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sg
+msgid "Singapore"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.act_window,target:0
+msgid "Current Window"
+msgstr ""
+
+#. module: base
+#: view:ir.values:0
+msgid "Action Source"
+msgstr ""
+
+#. module: base
+#: view:res.config.view:0
+msgid ""
+"If you use OpenERP for the first time we strongly advise you to select the "
+"simplified interface, which has less features but is easier. You can always "
+"switch later from the user preferences."
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_country
+#: field:res.bank,country:0
+#: view:res.country:0
+#: field:res.country.state,country_id:0
+#: field:res.partner,country:0
+#: view:res.partner.address:0
+#: field:res.partner.address,country_id:0
+#: field:res.partner.bank,country_id:0
+msgid "Country"
+msgstr ""
+
+#. module: base
+#: field:ir.model.fields,complete_name:0
+#: field:ir.ui.menu,complete_name:0
+msgid "Complete Name"
+msgstr ""
+
+#. module: base
+#: field:ir.values,object:0
+msgid "Is Object"
+msgstr ""
+
+#. module: base
+#: view:ir.rule:0
+msgid ""
+"1. Global rules are combined together with a logical AND operator, and with "
+"the result of the following steps"
+msgstr ""
+
+#. module: base
+#: field:res.partner.category,name:0
+msgid "Category Name"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_15
+msgid "IT sector"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.act_window:0
+msgid "Select Groups"
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%X - Appropriate time representation."
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Spanish (SV) / Español (SV)"
+msgstr ""
+
+#. module: base
+#: help:res.lang,grouping:0
+msgid ""
+"The Separator Format should be like [,n] where 0 < n :starting from Unit "
+"digit.-1 will end the separation. e.g. [3,2,-1] will represent 106500 to be "
+"1,06,500;[1,2,-1] will represent it to be 106,50,0;[3] will represent it as "
+"106,500. Provided ',' as the thousand separator in each case."
+msgstr ""
+
+#. module: base
+#: view:res.company:0
+msgid "Portrait"
+msgstr ""
+
+#. module: base
+#: code:addons/base/ir/ir_model.py:317
+#, python-format
+msgid "Can only rename one column at a time!"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Wizard Button"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Report/Template"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.act_window.view,view_mode:0
+#: selection:ir.ui.view,type:0
+#: selection:wizard.ir.model.menu.create.line,view_type:0
+msgid "Graph"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_ir_actions_server
+#: selection:ir.ui.menu,action:0
+msgid "ir.actions.server"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.configuration.wizard,progress:0
+#: field:res.config,progress:0
+#: field:res.config.installer,progress:0
+#: field:res.config.users,progress:0
+#: field:res.config.view,progress:0
+msgid "Configuration Progress"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.act_ir_actions_todo_form
+#: model:ir.ui.menu,name:base.menu_ir_actions_todo_form
+#: model:ir.ui.menu,name:base.next_id_11
+msgid "Configuration Wizards"
+msgstr ""
+
+#. module: base
+#: field:res.lang,code:0
+msgid "Locale Code"
+msgstr ""
+
+#. module: base
+#: field:workflow.activity,split_mode:0
+msgid "Split Mode"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "Note that this operation might take a few minutes."
+msgstr ""
+
+#. module: base
+#: model:ir.ui.menu,name:base.menu_localisation
+msgid "Localisation"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid "Action to Launch"
+msgstr ""
+
+#. module: base
+#: view:ir.cron:0
+msgid "Execution"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,condition:0
+#: field:workflow.transition,condition:0
+msgid "Condition"
+msgstr ""
+
+#. module: base
+#: help:ir.values,model_id:0
+msgid "This field is not used, it only helps you to select a good model."
+msgstr ""
+
+#. module: base
+#: field:ir.ui.view,name:0
+msgid "View Name"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Italian / Italiano"
+msgstr ""
+
+#. module: base
+#: field:ir.actions.report.xml,attachment:0
+msgid "Save As Attachment Prefix"
+msgstr ""
+
+#. module: base
+#: view:ir.actions.server:0
+msgid ""
+"Only one client action will be executed, last client action will be "
+"considered in case of multiple client actions."
+msgstr ""
+
+#. module: base
+#: view:res.lang:0
+msgid "%j - Day of the year [001,366]."
+msgstr ""
+
+#. module: base
+#: field:ir.actions.server,mobile:0
+msgid "Mobile No"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_partner_by_category
+#: model:ir.actions.act_window,name:base.action_partner_category_form
+#: model:ir.model,name:base.model_res_partner_category
+#: model:ir.ui.menu,name:base.menu_partner_category_form
+#: view:res.partner.category:0
+msgid "Partner Categories"
+msgstr ""
+
+#. module: base
+#: view:base.module.upgrade:0
+msgid "System Update"
+msgstr ""
+
+#. module: base
+#: selection:ir.translation,type:0
+msgid "Wizard Field"
+msgstr ""
+
+#. module: base
+#: help:ir.sequence,prefix:0
+msgid "Prefix value of the record for the sequence"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sc
+msgid "Seychelles"
+msgstr ""
+
+#. module: base
+#: model:ir.model,name:base.model_res_partner_bank
+#: view:res.partner.bank:0
+msgid "Bank Accounts"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.sl
+msgid "Sierra Leone"
+msgstr ""
+
+#. module: base
+#: view:res.company:0
+#: view:res.partner:0
+msgid "General Information"
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.tc
+msgid "Turks and Caicos Islands"
+msgstr ""
+
+#. module: base
+#: field:res.partner.bank,owner_name:0
+msgid "Account Owner"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/res_user.py:256
+#, python-format
+msgid "Company Switch Warning"
+msgstr ""
+
+#. module: base
+#: model:ir.actions.act_window,name:base.action_res_widget_wizard
+msgid "Homepage Widgets Management"
+msgstr ""
+
+#. module: base
+#: field:workflow,osv:0
+#: field:workflow.instance,res_type:0
+msgid "Resource Object"
+msgstr ""
+
+#. module: base
+#: help:ir.sequence,number_increment:0
+msgid "The next number of the sequence will be incremented by this number"
+msgstr ""
+
+#. module: base
+#: field:ir.cron,function:0
+#: field:res.partner.address,function:0
+#: selection:workflow.activity,kind:0
+msgid "Function"
+msgstr ""
+
+#. module: base
+#: view:res.widget:0
+msgid "Search Widget"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.todo,restart:0
+msgid "Never"
+msgstr ""
+
+#. module: base
+#: selection:res.partner.address,type:0
+msgid "Delivery"
+msgstr ""
+
+#. module: base
+#: model:res.partner.title,name:base.res_partner_title_pvt_ltd
+#: model:res.partner.title,shortcut:base.res_partner_title_pvt_ltd
+msgid "Corp."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.gw
+msgid "Guinea Bissau"
+msgstr ""
+
+#. module: base
+#: view:workflow.instance:0
+msgid "Workflow Instances"
+msgstr ""
+
+#. module: base
+#: code:addons/base/res/partner/partner.py:261
+#, python-format
+msgid "Partners: "
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.kp
+msgid "North Korea"
+msgstr ""
+
+#. module: base
+#: selection:ir.actions.server,state:0
+msgid "Create Object"
+msgstr ""
+
+#. module: base
+#: view:ir.filters:0
+#: field:res.log,context:0
+msgid "Context"
+msgstr ""
+
+#. module: base
+#: field:res.bank,bic:0
+msgid "BIC/Swift code"
+msgstr ""
+
+#. module: base
+#: model:res.partner.category,name:base.res_partner_category_1
+msgid "Prospect"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Polish / Język polski"
+msgstr ""
+
+#. module: base
+#: field:ir.exports,name:0
+msgid "Export Name"
+msgstr ""
+
+#. module: base
+#: help:res.partner.address,type:0
+msgid ""
+"Used to select automatically the right address according to the context in "
+"sales and purchases documents."
+msgstr ""
+
+#. module: base
+#: model:res.country,name:base.lk
+msgid "Sri Lanka"
+msgstr ""
+
+#. module: base
+#: selection:base.language.install,lang:0
+msgid "Russian / русский язык"
+msgstr ""
diff --git a/openerp/addons/base/ir/__init__.py b/openerp/addons/base/ir/__init__.py
index 9b4eb96df5f..4a6bd3c614c 100644
--- a/openerp/addons/base/ir/__init__.py
+++ b/openerp/addons/base/ir/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
-#
+#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL ().
#
@@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
+# along with this program. If not, see .
#
##############################################################################
@@ -36,6 +36,7 @@ import ir_rule
import wizard
import ir_config_parameter
import osv_memory_autovacuum
+import ir_mail_server
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/addons/base/ir/ir.xml b/openerp/addons/base/ir/ir.xml
index adbab648798..2792259773d 100644
--- a/openerp/addons/base/ir/ir.xml
+++ b/openerp/addons/base/ir/ir.xml
@@ -28,7 +28,7 @@
-
+
@@ -1274,7 +1274,7 @@
- Objects
+ Modelsir.modelform{'manual':True}
@@ -1740,7 +1740,7 @@
Property multi-company
- ['|',('company_id','=',user.company_id.id),('company_id','=',False)]
+ ['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)]
@@ -1766,7 +1766,9 @@
-
+
@@ -1995,5 +1997,76 @@
5
+
+
+ ir.mail.server.form
+ ir.mail_server
+ form
+
+
+
+
+
+
+ ir.mail.server.list
+ ir.mail_server
+ tree
+
+
+
+
+
+
+
+
+
+
+
+
+ ir.mail.server.search
+ ir.mail_server
+ search
+
+
+
+
+
+
+
+
+
+
+
+ Outgoing Mail Servers
+ ir.mail_server
+ form
+ tree,form
+
+
+
+
+
diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py
index 3ce3d9c0335..a2e107e741e 100644
--- a/openerp/addons/base/ir/ir_actions.py
+++ b/openerp/addons/base/ir/ir_actions.py
@@ -418,7 +418,10 @@ class server_object_lines(osv.osv):
_columns = {
'server_id': fields.many2one('ir.actions.server', 'Object Mapping'),
'col1': fields.many2one('ir.model.fields', 'Destination', required=True),
- 'value': fields.text('Value', required=True),
+ 'value': fields.text('Value', required=True, help="Expression containing a value specification. \n"
+ "When Formula type is selected, this field may be a Python expression "
+ " that can use the same values as for the condition field on the server action.\n"
+ "If Value type is selected, the value will be used directly without evaluation."),
'type': fields.selection([
('value','Value'),
('equation','Formula')
@@ -435,14 +438,15 @@ server_object_lines()
class actions_server(osv.osv):
def _select_signals(self, cr, uid, context=None):
- cr.execute("SELECT distinct w.osv, t.signal FROM wkf w, wkf_activity a, wkf_transition t \
- WHERE w.id = a.wkf_id AND t.act_from = a.id OR t.act_to = a.id AND t.signal!='' \
- AND t.signal NOT IN (null, NULL)")
+ cr.execute("""SELECT distinct w.osv, t.signal FROM wkf w, wkf_activity a, wkf_transition t
+ WHERE w.id = a.wkf_id AND
+ (t.act_from = a.id OR t.act_to = a.id) AND
+ t.signal IS NOT NULL""")
result = cr.fetchall() or []
res = []
for rs in result:
if rs[0] is not None and rs[1] is not None:
- line = rs[0], "%s - (%s)" % (rs[1], rs[0])
+ line = rs[1], "%s - (%s)" % (rs[1], rs[0])
res.append(line)
return res
@@ -453,13 +457,15 @@ class actions_server(osv.osv):
return [(r['model'], r['name']) for r in res] + [('','')]
def change_object(self, cr, uid, ids, copy_object, state, context=None):
- if state == 'object_copy':
+ if state == 'object_copy' and copy_object:
+ if context is None:
+ context = {}
model_pool = self.pool.get('ir.model')
model = copy_object.split(',')[0]
mid = model_pool.search(cr, uid, [('model','=',model)])
return {
- 'value':{'srcmodel_id':mid[0]},
- 'context':context
+ 'value': {'srcmodel_id': mid[0]},
+ 'context': context
}
else:
return {}
@@ -469,8 +475,19 @@ class actions_server(osv.osv):
_sequence = 'ir_actions_id_seq'
_order = 'sequence,name'
_columns = {
- 'name': fields.char('Action Name', required=True, size=64, help="Easy to Refer action by name e.g. One Sales Order -> Many Invoices", translate=True),
- 'condition' : fields.char('Condition', size=256, required=True, help="Condition that is to be tested before action is executed, e.g. object.list_price > object.cost_price"),
+ 'name': fields.char('Action Name', required=True, size=64, translate=True),
+ 'condition' : fields.char('Condition', size=256, required=True,
+ help="Condition that is tested before the action is executed, "
+ "and prevent execution if it is not verified.\n"
+ "Example: object.list_price > 5000\n"
+ "It is a Python expression that can use the following values:\n"
+ " - self: ORM model of the record on which the action is triggered\n"
+ " - object or obj: browse_record of the record on which the action is triggered\n"
+ " - pool: ORM model pool (i.e. self.pool)\n"
+ " - time: Python time module\n"
+ " - cr: database cursor\n"
+ " - uid: current user id\n"
+ " - context: current context"),
'state': fields.selection([
('client_action','Client Action'),
('dummy','Dummy'),
@@ -484,16 +501,20 @@ class actions_server(osv.osv):
('object_write','Write Object'),
('other','Multi Actions'),
], 'Action Type', required=True, size=32, help="Type of the Action that is to be executed"),
- 'code':fields.text('Python Code', help="Python code to be executed"),
+ 'code':fields.text('Python Code', help="Python code to be executed if condition is met.\n"
+ "It is a Python block that can use the same values as for the condition field"),
'sequence': fields.integer('Sequence', help="Important when you deal with multiple actions, the execution order will be decided based on this, low number is higher priority."),
'model_id': fields.many2one('ir.model', 'Object', required=True, help="Select the object on which the action will work (read, write, create)."),
'action_id': fields.many2one('ir.actions.actions', 'Client Action', help="Select the Action Window, Report, Wizard to be executed."),
- 'trigger_name': fields.selection(_select_signals, string='Trigger Name', size=128, help="Select the Signal name that is to be used as the trigger."),
- 'wkf_model_id': fields.many2one('ir.model', 'Workflow On', help="Workflow to be executed on this model."),
- 'trigger_obj_id': fields.many2one('ir.model.fields','Trigger On', help="Select the object from the model on which the workflow will executed."),
- 'email': fields.char('Email Address', size=512, help="Provides the fields that will be used to fetch the email address, e.g. when you select the invoice, then `object.invoice_address_id.email` is the field which gives the correct address"),
- 'subject': fields.char('Subject', size=1024, translate=True, help="Specify the subject. You can use fields from the object, e.g. `Hello [[ object.partner_id.name ]]`"),
- 'message': fields.text('Message', translate=True, help="Specify the message. You can use the fields from the object. e.g. `Dear [[ object.partner_id.name ]]`"),
+ 'trigger_name': fields.selection(_select_signals, string='Trigger Signal', size=128, help="The workflow signal to trigger"),
+ 'wkf_model_id': fields.many2one('ir.model', 'Target Object', help="The object that should receive the workflow signal (must have an associated workflow)"),
+ 'trigger_obj_id': fields.many2one('ir.model.fields','Relation Field', help="The field on the current object that links to the target object record (must be a many2one, or an integer field with the record ID)"),
+ 'email': fields.char('Email Address', size=512, help="Expression that returns the email address to send to. Can be based on the same values as for the condition field.\n"
+ "Example: object.invoice_address_id.email, or 'me@example.com'"),
+ 'subject': fields.char('Subject', size=1024, translate=True, help="Email subject, may contain expressions enclosed in double brackets based on the same values as those "
+ "available in the condition field, e.g. `Hello [[ object.partner_id.name ]]`"),
+ 'message': fields.text('Message', translate=True, help="Email contents, may contain expressions enclosed in double brackets based on the same values as those "
+ "available in the condition field, e.g. `Dear [[ object.partner_id.name ]]`"),
'mobile': fields.char('Mobile No', size=512, help="Provides fields that be used to fetch the mobile number, e.g. you select the invoice, then `object.invoice_address_id.mobile` is the field which gives the correct mobile number"),
'sms': fields.char('SMS', size=160, translate=True),
'child_ids': fields.many2many('ir.actions.server', 'rel_server_actions', 'server_id', 'action_id', 'Other Actions'),
@@ -512,12 +533,14 @@ class actions_server(osv.osv):
'condition': lambda *a: 'True',
'type': lambda *a: 'ir.actions.server',
'sequence': lambda *a: 5,
- 'code': lambda *a: """# You can use the following variables
-# - object or obj
-# - time
-# - cr
-# - uid
-# - ids
+ 'code': lambda *a: """# You can use the following variables:
+# - self: ORM model of the record on which the action is triggered
+# - object: browse_record of the record on which the action is triggered if there is one, otherwise None
+# - pool: ORM model pool (i.e. self.pool)
+# - time: Python time module
+# - cr: database cursor
+# - uid: current user id
+# - context: current context
# If you plan to return an action, assign: action = {...}
""",
}
@@ -567,6 +590,7 @@ class actions_server(osv.osv):
def merge_message(self, cr, uid, keystr, action, context=None):
if context is None:
context = {}
+
def merge(match):
obj_pool = self.pool.get(action.model_id.model)
id = context.get('active_id')
@@ -602,15 +626,17 @@ class actions_server(osv.osv):
user = self.pool.get('res.users').browse(cr, uid, uid)
for action in self.browse(cr, uid, ids, context):
obj = None
+ obj_pool = self.pool.get(action.model_id.model)
if context.get('active_model') == action.model_id.model and context.get('active_id'):
- obj_pool = self.pool.get(action.model_id.model)
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
cxt = {
- 'context': dict(context), # copy context to prevent side-effects of eval
+ 'self': obj_pool,
'object': obj,
+ 'obj': obj,
+ 'pool': self.pool,
'time': time,
'cr': cr,
- 'pool': self.pool,
+ 'context': dict(context), # copy context to prevent side-effects of eval
'uid': uid,
'user': user
}
@@ -625,21 +651,9 @@ class actions_server(osv.osv):
.read(cr, uid, action.action_id.id, context=context)
if action.state=='code':
- localdict = {
- 'self': self.pool.get(action.model_id.model),
- 'pool': self.pool,
- 'context': dict(context), # copy context to prevent side-effects of eval
- 'time': time,
- 'ids': ids,
- 'cr': cr,
- 'uid': uid,
- 'object':obj,
- 'obj': obj,
- 'user': user,
- }
- eval(action.code, localdict, mode="exec", nocopy=True) # nocopy allows to return 'action'
- if 'action' in localdict:
- return localdict['action']
+ eval(action.code, cxt, mode="exec", nocopy=True) # nocopy allows to return 'action'
+ if 'action' in cxt:
+ return cxt['action']
if action.state == 'email':
email_from = config['email_from']
@@ -652,7 +666,7 @@ class actions_server(osv.osv):
if not address:
logger.info('No partner email address specified, not sending any email.')
continue
-
+
if not email_from:
logger.debug('--email-from command line option is not specified, using a fallback value instead.')
if user.user_email:
@@ -663,7 +677,10 @@ class actions_server(osv.osv):
subject = self.merge_message(cr, uid, action.subject, action, context)
body = self.merge_message(cr, uid, action.message, action, context)
- if tools.email_send(email_from, [address], subject, body, debug=False, subtype='html') == True:
+ ir_mail_server = self.pool.get('ir.mail_server')
+ msg = ir_mail_server.build_email(email_from, [address], subject, body)
+ res_email = ir_mail_server.send_email(cr, uid, msg)
+ if res_email:
logger.info('Email successfully sent to: %s', address)
else:
logger.warning('Failed to send email to: %s', address)
@@ -671,10 +688,10 @@ class actions_server(osv.osv):
if action.state == 'trigger':
wf_service = netsvc.LocalService("workflow")
model = action.wkf_model_id.model
- obj_pool = self.pool.get(action.model_id.model)
- res_id = self.pool.get(action.model_id.model).read(cr, uid, [context.get('active_id')], [action.trigger_obj_id.name])
- id = res_id [0][action.trigger_obj_id.name]
- wf_service.trg_validate(uid, model, int(id), action.trigger_name, cr)
+ m2o_field_name = action.trigger_obj_id.name
+ target_id = obj_pool.read(cr, uid, context.get('active_id'), [m2o_field_name])[m2o_field_name]
+ target_id = target_id[0] if isinstance(target_id,tuple) else target_id
+ wf_service.trg_validate(uid, model, int(target_id), action.trigger_name, cr)
if action.state == 'sms':
#TODO: set the user and password from the system
@@ -689,20 +706,9 @@ class actions_server(osv.osv):
result = self.run(cr, uid, [act.id], context)
if result:
res.append(result)
-
return res
if action.state == 'loop':
- obj_pool = self.pool.get(action.model_id.model)
- obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
- cxt = {
- 'context': dict(context), # copy context to prevent side-effects of eval
- 'object': obj,
- 'time': time,
- 'cr': cr,
- 'pool' : self.pool,
- 'uid' : uid
- }
expr = eval(str(action.expression), cxt)
context['object'] = obj
for i in expr:
@@ -714,13 +720,6 @@ class actions_server(osv.osv):
for exp in action.fields_lines:
euq = exp.value
if exp.type == 'equation':
- obj_pool = self.pool.get(action.model_id.model)
- obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
- cxt = {
- 'context': dict(context), # copy context to prevent side-effects of eval
- 'object': obj,
- 'time': time,
- }
expr = eval(euq, cxt)
else:
expr = exp.value
@@ -754,14 +753,7 @@ class actions_server(osv.osv):
for exp in action.fields_lines:
euq = exp.value
if exp.type == 'equation':
- obj_pool = self.pool.get(action.model_id.model)
- obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
- expr = eval(euq,
- {
- 'context': dict(context), # copy context to prevent side-effects of eval
- 'object': obj,
- 'time': time,
- })
+ expr = eval(euq, cxt)
else:
expr = exp.value
res[exp.col1.name] = expr
@@ -778,21 +770,11 @@ class actions_server(osv.osv):
for exp in action.fields_lines:
euq = exp.value
if exp.type == 'equation':
- obj_pool = self.pool.get(action.model_id.model)
- obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
- expr = eval(euq,
- {
- 'context': dict(context), # copy context to prevent side-effects of eval
- 'object': obj,
- 'time': time,
- })
+ expr = eval(euq, cxt)
else:
expr = exp.value
res[exp.col1.name] = expr
- obj_pool = None
- res_id = False
-
model = action.copy_object.split(',')[0]
cid = action.copy_object.split(',')[1]
obj_pool = self.pool.get(model)
diff --git a/openerp/addons/base/ir/ir_attachment.py b/openerp/addons/base/ir/ir_attachment.py
index 95a4cd8cab0..0612c1861d8 100644
--- a/openerp/addons/base/ir/ir_attachment.py
+++ b/openerp/addons/base/ir/ir_attachment.py
@@ -50,8 +50,7 @@ class ir_attachment(osv.osv):
for model, mids in res_ids.items():
# ignore attachments that are not attached to a resource anymore when checking access rights
# (resource was deleted but attachment was not)
- cr.execute('select id from '+self.pool.get(model)._table+' where id in %s', (tuple(mids),))
- mids = [x[0] for x in cr.fetchall()]
+ mids = self.pool.get(model).exists(cr, uid, mids)
ima.check(cr, uid, model, mode)
self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context)
diff --git a/openerp/addons/base/ir/ir_config_parameter.py b/openerp/addons/base/ir/ir_config_parameter.py
index f8c0348e8f6..981dfd2798e 100644
--- a/openerp/addons/base/ir/ir_config_parameter.py
+++ b/openerp/addons/base/ir/ir_config_parameter.py
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
+# Copyright (C) 2011 OpenERP SA ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -19,7 +19,7 @@
#
##############################################################################
"""
-A module to store some configuration parameters relative to a whole database.
+Store database-specific configuration parameters
"""
from osv import osv,fields
@@ -36,23 +36,19 @@ _default_parameters = {
}
class ir_config_parameter(osv.osv):
- """ An osv to old configuration parameters for a given database.
-
- To be short, it's just a global dictionary of strings stored in a table. """
-
+ """Per-database storage of configuration key-value pairs."""
+
_name = 'ir.config_parameter'
-
+
_columns = {
- # The key of the configuration parameter.
'key': fields.char('Key', size=256, required=True, select=1),
- # The value of the configuration parameter.
'value': fields.text('Value', required=True),
}
-
+
_sql_constraints = [
('key_uniq', 'unique (key)', 'Key must be unique.')
]
-
+
def init(self, cr):
"""
Initializes the parameters listed in _default_parameters.
@@ -63,12 +59,12 @@ class ir_config_parameter(osv.osv):
self.set_param(cr, 1, key, func())
def get_param(self, cr, uid, key, default=False, context=None):
- """ Get the value of a parameter.
-
- @param key: The key of the parameter.
- @type key: string
- @return: The value of the parameter, False if it does not exist.
- @rtype: string
+ """Retrieve the value for a given key.
+
+ :param string key: The key of the parameter value to retrieve.
+ :param string default: default value if parameter is missing.
+ :return: The value of the parameter, or ``default`` if it does not exist.
+ :rtype: string
"""
ids = self.search(cr, uid, [('key','=',key)], context=context)
if not ids:
@@ -78,15 +74,13 @@ class ir_config_parameter(osv.osv):
return value
def set_param(self, cr, uid, key, value, context=None):
- """ Set the value of a parameter.
+ """Sets the value of a parameter.
- @param key: The key of the parameter.
- @type key: string
- @param value: The value of the parameter.
- @type value: string
- @return: Return the previous value of the parameter of False if it did
- not existed.
- @rtype: string
+ :param string key: The key of the parameter value to set.
+ :param string value: The value to set.
+ :return: the previous value of the parameter or False if it did
+ not exist.
+ :rtype: string
"""
ids = self.search(cr, uid, [('key','=',key)], context=context)
if ids:
@@ -97,5 +91,3 @@ class ir_config_parameter(osv.osv):
else:
self.create(cr, uid, {'key': key, 'value': value}, context=context)
return False
-
-ir_config_parameter()
diff --git a/openerp/addons/base/ir/ir_mail_server.py b/openerp/addons/base/ir/ir_mail_server.py
new file mode 100644
index 00000000000..96fa9f52a88
--- /dev/null
+++ b/openerp/addons/base/ir/ir_mail_server.py
@@ -0,0 +1,436 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2011 OpenERP S.A ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+from email.MIMEText import MIMEText
+from email.MIMEBase import MIMEBase
+from email.MIMEMultipart import MIMEMultipart
+from email.Header import Header
+from email.Utils import formatdate, make_msgid, COMMASPACE
+from email import Encoders
+import logging
+import re
+import smtplib
+
+from osv import osv
+from osv import fields
+from openerp.tools.translate import _
+from openerp.tools import html2text
+from openerp.tools.func import wraps
+import openerp.tools as tools
+
+# ustr was originally from tools.misc.
+# it is moved to loglevels until we refactor tools.
+from openerp.loglevels import ustr
+
+_logger = logging.getLogger('ir.mail_server')
+
+class MailDeliveryException(osv.except_osv):
+ """Specific exception subclass for mail delivery errors"""
+ def __init__(self, name, value, exc_type='warning'):
+ super(MailDeliveryException, self).__init__(name, value, exc_type=exc_type)
+
+class WriteToLogger(object):
+ """debugging helper: behave as a fd and pipe to logger at the given level"""
+ def __init__(self, logger, level=logging.DEBUG):
+ self.logger = logger
+ self.level = level
+
+ def write(self, s):
+ self.logger.log(self.level, s)
+
+
+def try_coerce_ascii(string_utf8):
+ """Attempts to decode the given utf8-encoded string
+ as ASCII after coercing it to UTF-8, then return
+ the confirmed 7-bit ASCII string.
+
+ If the process fails (because the string
+ contains non-ASCII characters) returns ``None``.
+ """
+ try:
+ string_utf8.decode('ascii')
+ except UnicodeDecodeError:
+ return
+ return string_utf8
+
+def encode_header(header_text):
+ """Returns an appropriate representation of the given header value,
+ suitable for direct assignment as a header value in an
+ email.message.Message. RFC2822 assumes that headers contain
+ only 7-bit characters, so we ensure it is the case, using
+ RFC2047 encoding when needed.
+
+ :param header_text: unicode or utf-8 encoded string with header value
+ :rtype: string | email.header.Header
+ :return: if ``header_text`` represents a plain ASCII string,
+ return the same 7-bit string, otherwise returns an email.header.Header
+ that will perform the appropriate RFC2047 encoding of
+ non-ASCII values.
+ """
+ if not header_text: return ""
+ # convert anything to utf-8, suitable for testing ASCIIness, as 7-bit chars are
+ # encoded as ASCII in utf-8
+ header_text_utf8 = tools.ustr(header_text).encode('utf-8')
+ header_text_ascii = try_coerce_ascii(header_text_utf8)
+ # if this header contains non-ASCII characters,
+ # we'll need to wrap it up in a message.header.Header
+ # that will take care of RFC2047-encoding it as
+ # 7-bit string.
+ return header_text_ascii if header_text_ascii\
+ else Header(header_text_utf8, 'utf-8')
+
+name_with_email_pattern = re.compile(r'("[^<@>]+")\s*<([^ ,<@]+@[^> ,]+)>')
+address_pattern = re.compile(r'([^ ,<@]+@[^> ,]+)')
+
+def extract_rfc2822_addresses(text):
+ """Returns a list of valid RFC2822 addresses
+ that can be found in ``source``, ignoring
+ malformed ones and non-ASCII ones.
+ """
+ if not text: return []
+ candidates = address_pattern.findall(tools.ustr(text).encode('utf-8'))
+ return filter(try_coerce_ascii, candidates)
+
+def encode_rfc2822_address_header(header_text):
+ """If ``header_text`` contains non-ASCII characters,
+ attempts to locate patterns of the form
+ ``"Name" `` and replace the
+ ``"Name"`` portion by the RFC2047-encoded
+ version, preserving the address part untouched.
+ """
+ header_text_utf8 = tools.ustr(header_text).encode('utf-8')
+ header_text_ascii = try_coerce_ascii(header_text_utf8)
+ if header_text_ascii:
+ return header_text_ascii
+ # non-ASCII characters are present, attempt to
+ # replace all "Name" patterns with the RFC2047-
+ # encoded version
+ def replace(match_obj):
+ name, email = match_obj.group(1), match_obj.group(2)
+ name_encoded = str(Header(name, 'utf-8'))
+ return "%s <%s>" % (name_encoded, email)
+ header_text_utf8 = name_with_email_pattern.sub(replace,
+ header_text_utf8)
+ # try again after encoding
+ header_text_ascii = try_coerce_ascii(header_text_utf8)
+ if header_text_ascii:
+ return header_text_ascii
+ # fallback to extracting pure addresses only, which could
+ # still cause a failure downstream if the actual addresses
+ # contain non-ASCII characters
+ return COMMASPACE.join(extract_rfc2822_addresses(header_text_utf8))
+
+
+class ir_mail_server(osv.osv):
+ """Represents an SMTP server, able to send outgoing e-mails, with SSL and TLS capabilities."""
+ _name = "ir.mail_server"
+
+ _columns = {
+ 'name': fields.char('Description', size=64, required=True, select=True),
+ 'smtp_host': fields.char('Server Name', size=128, required=True, help="Hostname or IP of SMTP server"),
+ 'smtp_port': fields.integer('SMTP Port', size=5, required=True, help="SMTP Port. Usually 465 for SSL, and 25 or 587 for other cases."),
+ 'smtp_user': fields.char('Username', size=64, help="Optional username for SMTP authentication"),
+ 'smtp_pass': fields.char('Password', size=64, help="Optional password for SMTP authentication"),
+ 'smtp_encryption': fields.selection([('none','None'),
+ ('starttls','TLS (STARTTLS)'),
+ ('ssl','SSL/TLS')],
+ string='Connection Security',
+ help="Choose the connection encryption scheme:\n"
+ "- None: SMTP sessions are done in cleartext.\n"
+ "- TLS (STARTTLS): TLS encryption is requested at start of SMTP session (Recommended)\n"
+ "- SSL/TLS: SMTP sessions are encrypted with SSL/TLS through a dedicated port (default: 465)"),
+ 'smtp_debug': fields.boolean('Debugging', help="If enabled, the full output of SMTP sessions will "
+ "be written to the server log at DEBUG level"
+ "(this is very verbose and may include confidential info!)"),
+ 'sequence': fields.integer('Priority', help="When no specific mail server is requested for a mail, the highest priority one "
+ "is used. Default priority is 10 (smaller number = higher priority)"),
+ }
+
+ _defaults = {
+ 'smtp_port': 25,
+ 'sequence': 10,
+ 'smtp_encryption': 'none',
+ }
+
+ def __init__(self, *args, **kwargs):
+ # Make sure we pipe the smtplib outputs to our own DEBUG logger
+ if not isinstance(smtplib.stderr, WriteToLogger):
+ logpiper = WriteToLogger(_logger)
+ smtplib.stderr = logpiper
+ smtplib.stdout = logpiper
+ return super(ir_mail_server, self).__init__(*args,**kwargs)
+
+ def name_get(self, cr, uid, ids, context=None):
+ return [(a["id"], "(%s)" % (a['name'])) for a in self.read(cr, uid, ids, ['name'], context=context)]
+
+ def test_smtp_connection(self, cr, uid, ids, context=None):
+ for smtp_server in self.browse(cr, uid, ids, context=context):
+ smtp = False
+ try:
+ smtp = self.connect(smtp_server.smtp_host, smtp_server.smtp_port, user=smtp_server.smtp_user,
+ password=smtp_server.smtp_pass, encryption=smtp_server.smtp_encryption,
+ smtp_debug=smtp_server.smtp_debug)
+ except Exception, e:
+ raise osv.except_osv(_("Connection test failed!"), _("Here is what we got instead:\n %s") % tools.ustr(e))
+ finally:
+ try:
+ if smtp: smtp.quit()
+ except Exception:
+ # ignored, just a consequence of the previous exception
+ pass
+ raise osv.except_osv(_("Connection test succeeded!"), _("Everything seems properly set up!"))
+
+ def connect(self, host, port, user=None, password=None, encryption=False, smtp_debug=False):
+ """Returns a new SMTP connection to the give SMTP server, authenticated
+ with ``user`` and ``password`` if provided, and encrypted as requested
+ by the ``encryption`` parameter.
+
+ :param host: host or IP of SMTP server to connect to
+ :param int port: SMTP port to connect to
+ :param user: optional username to authenticate with
+ :param password: optional password to authenticate with
+ :param string encryption: optional: ``'ssl'`` | ``'starttls'``
+ :param bool smtp_debug: toggle debugging of SMTP sessions (all i/o
+ will be output in logs)
+ """
+ if encryption == 'ssl':
+ if not 'SMTP_SSL' in smtplib.__all__:
+ raise osv.except_osv(
+ _("SMTP-over-SSL mode unavailable"),
+ _("Your OpenERP Server does not support SMTP-over-SSL. You could use STARTTLS instead."
+ "If SSL is needed, an upgrade to Python 2.6 on the server-side should do the trick."))
+ connection = smtplib.SMTP_SSL(host, port)
+ else:
+ connection = smtplib.SMTP(host, port)
+ connection.set_debuglevel(smtp_debug)
+ if encryption == 'starttls':
+ # starttls() will perform ehlo() if needed first
+ # and will discard the previous list of services
+ # after successfully performing STARTTLS command,
+ # (as per RFC 3207) so for example any AUTH
+ # capability that appears only on encrypted channels
+ # will be correctly detected for next step
+ connection.starttls()
+
+ if user:
+ # Attempt authentication - will raise if AUTH service not supported
+ connection.login(user, password)
+ return connection
+
+ def build_email(self, email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False,
+ attachments=None, message_id=None, references=None, object_id=False, subtype='plain', headers=None):
+ """Constructs an RFC2822 email.message.Message object based on the keyword arguments passed, and returns it.
+
+ :param string email_from: sender email address
+ :param list email_to: list of recipient addresses (to be joined with commas)
+ :param string subject: email subject (no pre-encoding/quoting necessary)
+ :param string body: email body, according to the ``subtype`` (by default, plaintext).
+ If html subtype is used, the message will be automatically converted
+ to plaintext and wrapped in multipart/alternative.
+ :param string reply_to: optional value of Reply-To header
+ :param string object_id: optional tracking identifier, to be included in the message-id for
+ recognizing replies. Suggested format for object-id is "res_id-model",
+ e.g. "12345-crm.lead".
+ :param string subtype: optional mime subtype for the text body (usually 'plain' or 'html'),
+ must match the format of the ``body`` parameter. Default is 'plain',
+ making the content part of the mail "text/plain".
+ :param list attachments: list of (filename, filecontents) pairs, where filecontents is a string
+ containing the bytes of the attachment
+ :param list email_cc: optional list of string values for CC header (to be joined with commas)
+ :param list email_bcc: optional list of string values for BCC header (to be joined with commas)
+ :param dict headers: optional map of headers to set on the outgoing mail (may override the
+ other headers, including Subject, Reply-To, Message-Id, etc.)
+ :rtype: email.message.Message (usually MIMEMultipart)
+ :return: the new RFC2822 email message
+ """
+ email_from = email_from or tools.config.get('email_from')
+ assert email_from, "You must either provide a sender address explicitly or configure "\
+ "a global sender address in the server configuration or with the "\
+ "--email-from startup parameter."
+
+ # Note: we must force all strings to to 8-bit utf-8 when crafting message,
+ # or use encode_header() for headers, which does it automatically.
+
+ headers = headers or {} # need valid dict later
+
+ if not email_cc: email_cc = []
+ if not email_bcc: email_bcc = []
+ if not body: body = u''
+
+ email_body_utf8 = ustr(body).encode('utf-8')
+ email_text_part = MIMEText(email_body_utf8 or '', _subtype=subtype, _charset='utf-8')
+ msg = MIMEMultipart()
+
+ if not message_id:
+ if object_id:
+ message_id = tools.generate_tracking_message_id(object_id)
+ else:
+ message_id = make_msgid()
+ msg['Message-Id'] = encode_header(message_id)
+ if references:
+ msg['references'] = encode_header(references)
+ msg['Subject'] = encode_header(subject)
+ msg['From'] = encode_rfc2822_address_header(email_from)
+ del msg['Reply-To']
+ if reply_to:
+ msg['Reply-To'] = encode_rfc2822_address_header(reply_to)
+ else:
+ msg['Reply-To'] = msg['From']
+ msg['To'] = encode_rfc2822_address_header(COMMASPACE.join(email_to))
+ if email_cc:
+ msg['Cc'] = encode_rfc2822_address_header(COMMASPACE.join(email_cc))
+ if email_bcc:
+ msg['Bcc'] = encode_rfc2822_address_header(COMMASPACE.join(email_bcc))
+ msg['Date'] = formatdate(localtime=True)
+ # Custom headers may override normal headers or provide additional ones
+ for key, value in headers.iteritems():
+ msg[ustr(key).encode('utf-8')] = encode_header(value)
+
+ if html2text and subtype == 'html':
+ # Always provide alternative text body if possible.
+ text_utf8 = tools.html2text(email_body_utf8.decode('utf-8')).encode('utf-8')
+ alternative_part = MIMEMultipart(_subtype="alternative")
+ alternative_part.attach(MIMEText(text_utf8, _charset='utf-8', _subtype='plain'))
+ alternative_part.attach(email_text_part)
+ msg.attach(alternative_part)
+ else:
+ msg.attach(email_text_part)
+
+ if attachments:
+ for (fname, fcontent) in attachments:
+ filename_utf8 = ustr(fname).encode('utf-8')
+ part = MIMEBase('application', "octet-stream")
+ part.set_payload(fcontent)
+ Encoders.encode_base64(part)
+ # Force RFC2231 encoding for attachment filename
+ # See email.message.Message.add_header doc
+ part.add_header('Content-Disposition', 'attachment',
+ filename=('utf-8',None,filename_utf8))
+ msg.attach(part)
+ return msg
+
+ def send_email(self, cr, uid, message, mail_server_id=None, smtp_server=None, smtp_port=None,
+ smtp_user=None, smtp_password=None, smtp_encryption='none', smtp_debug=False,
+ context=None):
+ """Sends an email directly (no queuing).
+
+ No retries are done, the caller should handle MailDeliveryException in order to ensure that
+ the mail is never lost.
+
+ If the mail_server_id is provided, sends using this mail server, ignoring other smtp_* arguments.
+ If mail_server_id is None and smtp_server is None, use the default mail server (highest priority).
+ If mail_server_id is None and smtp_server is not None, use the provided smtp_* arguments.
+ If both mail_server_id and smtp_server are None, look for an 'smtp_server' value in server config,
+ and fails if not found.
+
+ :param message: the email.message.Message to send. The envelope sender will be extracted from the
+ ``Return-Path`` or ``From`` headers. The envelope recipients will be
+ extracted from the combined list of ``To``, ``CC`` and ``BCC`` headers.
+ :param mail_server_id: optional id of ir.mail_server to use for sending. overrides other smtp_* arguments.
+ :param smtp_server: optional hostname of SMTP server to use
+ :param smtp_encryption: one of 'none', 'starttls' or 'ssl' (see ir.mail_server fields for explanation)
+ :param smtp_port: optional SMTP port, if mail_server_id is not passed
+ :param smtp_user: optional SMTP user, if mail_server_id is not passed
+ :param smtp_password: optional SMTP password to use, if mail_server_id is not passed
+ :param smtp_debug: optional SMTP debug flag, if mail_server_id is not passed
+ :param debug: whether to turn on the SMTP level debugging, output to DEBUG log level
+ :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises
+ MailDeliveryException and logs root cause.
+ """
+ smtp_from = message['Return-Path'] or message['From']
+ assert smtp_from, "The Return-Path or From header is required for any outbound e-mail"
+
+ # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
+ from_rfc2822 = extract_rfc2822_addresses(smtp_from)
+ assert len(from_rfc2822) == 1, "Malformed 'Return-Path' or 'From' address - it may only contain plain ASCII characters"
+ smtp_from = from_rfc2822[0]
+ email_to = message['To']
+ email_cc = message['Cc']
+ email_bcc = message['Bcc']
+ smtp_to_list = filter(None, tools.flatten(map(extract_rfc2822_addresses,[email_to, email_cc, email_bcc])))
+ assert smtp_to_list, "At least one valid recipient address should be specified for outgoing emails (To/Cc/Bcc)"
+
+ # Get SMTP Server Details from Mail Server
+ mail_server = None
+ if mail_server_id:
+ mail_server = self.browse(cr, uid, mail_server_id)
+ elif not smtp_server:
+ mail_server_ids = self.search(cr, uid, [], order='sequence', limit=1)
+ if mail_server_ids:
+ mail_server = self.browse(cr, uid, mail_server_ids[0])
+ else:
+ # we were passed an explicit smtp_server or nothing at all
+ smtp_server = smtp_server or tools.config.get('smtp_server')
+ smtp_port = tools.config.get('smtp_port', 25) if smtp_port is None else smtp_port
+ smtp_user = smtp_user or tools.config.get('smtp_user')
+ smtp_password = smtp_password or tools.config.get('smtp_password')
+
+ if mail_server:
+ smtp_server = mail_server.smtp_host
+ smtp_user = mail_server.smtp_user
+ smtp_password = mail_server.smtp_pass
+ smtp_port = mail_server.smtp_port
+ smtp_encryption = mail_server.smtp_encryption
+ smtp_debug = smtp_debug or mail_server.smtp_debug
+
+ if not smtp_server:
+ raise osv.except_osv(
+ _("Missing SMTP Server"),
+ _("Please define at least one SMTP server, or provide the SMTP parameters explicitly."))
+
+ try:
+ message_id = message['Message-Id']
+
+ # Add email in Maildir if smtp_server contains maildir.
+ if smtp_server.startswith('maildir:/'):
+ from mailbox import Maildir
+ maildir_path = smtp_server[8:]
+ mdir = Maildir(maildir_path, factory=None, create = True)
+ mdir.add(message.as_string(True))
+ return message_id
+
+ try:
+ smtp = self.connect(smtp_server, smtp_port, smtp_user, smtp_password, smtp_encryption, smtp_debug)
+ smtp.sendmail(smtp_from, smtp_to_list, message.as_string())
+ finally:
+ try:
+ # Close Connection of SMTP Server
+ smtp.quit()
+ except Exception:
+ # ignored, just a consequence of the previous exception
+ pass
+ except Exception, e:
+ msg = _("Mail delivery failed via SMTP server '%s'.\n%s: %s") % (smtp_server, e.__class__.__name__, e)
+ _logger.exception(msg)
+ raise MailDeliveryException(_("Mail delivery failed"), msg)
+ return message_id
+
+ def on_change_encryption(self, cr, uid, ids, smtp_encryption):
+ if smtp_encryption == 'ssl':
+ result = {'value': {'smtp_port': 465}}
+ if not 'SMTP_SSL' in smtplib.__all__:
+ result['warning'] = {'title': _('Warning'),
+ 'message': _('Your server does not seem to support SSL, you may want to try STARTTLS instead')}
+ else:
+ result = {'value': {'smtp_port': 25}}
+ return result
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py
index 1ae54af0cb9..2e273f53b69 100644
--- a/openerp/addons/base/ir/ir_model.py
+++ b/openerp/addons/base/ir/ir_model.py
@@ -56,7 +56,7 @@ def _in_modules(self, cr, uid, ids, field_name, arg, context=None):
class ir_model(osv.osv):
_name = 'ir.model'
- _description = "Objects"
+ _description = "Models"
_order = 'model'
def _is_osv_memory(self, cr, uid, ids, field_name, arg, context=None):
@@ -85,8 +85,8 @@ class ir_model(osv.osv):
return res
_columns = {
- 'name': fields.char('Object Name', size=64, translate=True, required=True),
- 'model': fields.char('Object', size=64, required=True, select=1),
+ 'name': fields.char('Model Description', size=64, translate=True, required=True),
+ 'model': fields.char('Model', size=64, required=True, select=1),
'info': fields.text('Information'),
'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True),
'state': fields.selection([('manual','Custom Object'),('base','Base Object')],'Type',readonly=True),
@@ -97,12 +97,12 @@ class ir_model(osv.osv):
'modules': fields.function(_in_modules, method=True, type='char', size=128, string='In modules', help='List of modules in which the object is defined or inherited'),
'view_ids': fields.function(_view_ids, method=True, type='one2many', obj='ir.ui.view', string='Views'),
}
-
+
_defaults = {
'model': lambda *a: 'x_',
'state': lambda self,cr,uid,ctx=None: (ctx and ctx.get('manual',False)) and 'manual' or 'base',
}
-
+
def _check_model_name(self, cr, uid, ids, context=None):
for model in self.browse(cr, uid, ids, context=context):
if model.state=='manual':
@@ -114,9 +114,13 @@ class ir_model(osv.osv):
def _model_name_msg(self, cr, uid, ids, context=None):
return _('The Object name must start with x_ and not contain any special character !')
+
_constraints = [
(_check_model_name, _model_name_msg, ['model']),
]
+ _sql_constraints = [
+ ('obj_name_uniq', 'unique (model)', 'Each model must be unique!'),
+ ]
# overridden to allow searching both on model name (model field)
# and model description (name field)
@@ -616,7 +620,7 @@ class ir_model_data(osv.osv):
"""Returns the id of the ir.model.data record corresponding to a given module and xml_id (cached) or raise a ValueError if not found"""
ids = self.search(cr, uid, [('module','=',module), ('name','=', xml_id)])
if not ids:
- raise ValueError('No references to %s.%s' % (module, xml_id))
+ raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
# the sql constraints ensure us we have only one result
return ids[0]
@@ -626,7 +630,7 @@ class ir_model_data(osv.osv):
data_id = self._get_id(cr, uid, module, xml_id)
res = self.read(cr, uid, data_id, ['model', 'res_id'])
if not res['res_id']:
- raise ValueError('No references to %s.%s' % (module, xml_id))
+ raise ValueError('No such external ID currently defined in the system: %s.%s' % (module, xml_id))
return (res['model'], res['res_id'])
def get_object(self, cr, uid, module, xml_id, context=None):
diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py
index ab9de808cec..44f5d24823d 100644
--- a/openerp/addons/base/ir/ir_translation.py
+++ b/openerp/addons/base/ir/ir_translation.py
@@ -108,8 +108,8 @@ class ir_translation(osv.osv):
for res_id in tr:
if tr[res_id]:
self._get_source.clear_cache(self, uid, name, tt, lang, tr[res_id])
+ self._get_ids.clear_cache(self, uid, name, tt, lang, res_id)
self._get_source.clear_cache(self, uid, name, tt, lang)
- self._get_ids.clear_cache(self, uid, name, tt, lang, ids)
cr.execute('delete from ir_translation ' \
'where lang=%s ' \
diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py
index 90990834c9b..c44ff716519 100644
--- a/openerp/addons/base/ir/ir_ui_view.py
+++ b/openerp/addons/base/ir/ir_ui_view.py
@@ -96,6 +96,19 @@ class view(osv.osv):
if not cr.fetchone():
cr.execute('CREATE INDEX ir_ui_view_model_type_inherit_id ON ir_ui_view (model, type, inherit_id)')
+ def get_inheriting_views_arch(self, cr, uid, view_id, model, context=None):
+ """Retrieves the architecture of views that inherit from the given view.
+
+ :param int view_id: id of the view whose inheriting views should be retrieved
+ :param str model: model identifier of the view's related model (for double-checking)
+ :rtype: list of tuples
+ :return: [(view_arch,view_id), ...]
+ """
+ cr.execute("""SELECT arch, id FROM ir_ui_view WHERE inherit_id=%s AND model=%s
+ ORDER BY priority""",
+ (view_id, model))
+ return cr.fetchall()
+
def write(self, cr, uid, ids, vals, context={}):
if not isinstance(ids, (list, tuple)):
ids = [ids]
@@ -159,10 +172,10 @@ class view(osv.osv):
label_string = ""
if label:
for lbl in eval(label):
- if t.has_key(str(lbl)) and str(t[lbl])=='False':
+ if t.has_key(tools.ustr(lbl)) and tools.ustr(t[lbl])=='False':
label_string = label_string + ' '
else:
- label_string = label_string + " " + t[lbl]
+ label_string = label_string + " " + tools.ustr(t[lbl])
labels[str(t['id'])] = (a['id'],label_string)
g = graph(nodes, transitions, no_ancester)
g.process(start)
diff --git a/openerp/addons/base/ir/ir_values.py b/openerp/addons/base/ir/ir_values.py
index c2a59ada55e..f079e5764c9 100644
--- a/openerp/addons/base/ir/ir_values.py
+++ b/openerp/addons/base/ir/ir_values.py
@@ -79,7 +79,10 @@ class ir_values(osv.osv):
method=True, type='text', string='Value'),
'object': fields.boolean('Is Object'),
'key': fields.selection([('action','Action'),('default','Default')], 'Type', size=128, select=True),
- 'key2' : fields.char('Event Type',help="The kind of action or button in the client side that will trigger the action.", size=128, select=True),
+ 'key2' : fields.char('Event Type', size=128, select=True, help="The kind of action or button on the client side "
+ "that will trigger the action. One of: "
+ "client_action_multi, client_action_relate, tree_but_open, "
+ "client_print_multi"),
'meta': fields.text('Meta Datas'),
'meta_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle,
method=True, type='text', string='Metadata'),
diff --git a/openerp/addons/base/ir/wizard/__init__.py b/openerp/addons/base/ir/wizard/__init__.py
index 99c6cdcd0de..3f5495524f5 100644
--- a/openerp/addons/base/ir/wizard/__init__.py
+++ b/openerp/addons/base/ir/wizard/__init__.py
@@ -20,6 +20,5 @@
##############################################################################
import wizard_menu
import wizard_screen
-import create_action
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/addons/base/ir/wizard/create_action.py b/openerp/addons/base/ir/wizard/create_action.py
deleted file mode 100644
index 335f7a5ce04..00000000000
--- a/openerp/addons/base/ir/wizard/create_action.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# -*- coding: utf-8 -*-
- ##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL ().
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
-
-import wizard
-import pooler
-import time
-
-action_type = '''
-'''
-
-action_type_fields = {
- 'type': {'string':"Select Action Type",'type':'selection','required':True ,'selection':[('ir.actions.report.xml','Open Report')]},
-}
-
-report_action = '''
-'''
-
-report_action_fields = {
- 'report': {'string':"Select Report",'type':'many2one','relation':'ir.actions.report.xml', 'required':True},
-}
-
-class create_action(wizard.interface):
-
- def _create_report_action(self, cr, uid, data, context={}):
- pool = pooler.get_pool(cr.dbname)
-
- reports = pool.get('ir.actions.report.xml')
- form = data['form']
-
- rpt = reports.browse(cr, uid, form['report'])
-
- action = """action = {"type": "ir.actions.report.xml","model":"%s","report_name": "%s","ids": context["active_ids"]}""" % (rpt.model, rpt.report_name)
-
- obj = pool.get('ir.actions.server')
- obj.write(cr, uid, data['ids'], {'code':action})
-
- return {}
-
- states = {
- 'init': {
- 'actions': [],
- 'result': {'type':'form', 'arch':action_type,'fields':action_type_fields, 'state':[('step_1','Next'),('end','Close')]}
- },
- 'step_1': {
- 'actions': [],
- 'result': {'type':'form', 'arch':report_action,'fields':report_action_fields, 'state':[('create','Create'),('end','Close')]}
- },
- 'create': {
- 'actions': [_create_report_action],
- 'result': {'type':'state', 'state':'end'}
- },
- }
-create_action('server.action.create')
-
-
diff --git a/openerp/addons/base/ir/wizard/wizard_menu_view.xml b/openerp/addons/base/ir/wizard/wizard_menu_view.xml
index 4d3e7e7a26e..d99138d00e6 100644
--- a/openerp/addons/base/ir/wizard/wizard_menu_view.xml
+++ b/openerp/addons/base/ir/wizard/wizard_menu_view.xml
@@ -21,12 +21,5 @@
-
diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py
index 034829b82b5..a35e4b5d1ce 100644
--- a/openerp/addons/base/module/module.py
+++ b/openerp/addons/base/module/module.py
@@ -107,48 +107,59 @@ class module(osv.osv):
view_obj = self.pool.get('ir.ui.view')
report_obj = self.pool.get('ir.actions.report.xml')
menu_obj = self.pool.get('ir.ui.menu')
- mlist = self.browse(cr, uid, ids, context=context)
- mnames = {}
- for m in mlist:
- # skip uninstalled modules below,
- # no data to find anyway
- if m.state in ('installed', 'to upgrade', 'to remove'):
- mnames[m.name] = m.id
- res[m.id] = {
- 'menus_by_module':[],
- 'reports_by_module':[],
+
+ dmodels = []
+ if field_name is None or 'views_by_module' in field_name:
+ dmodels.append('ir.ui.view')
+ if field_name is None or 'reports_by_module' in field_name:
+ dmodels.append('ir.actions.report.xml')
+ if field_name is None or 'menus_by_module' in field_name:
+ dmodels.append('ir.ui.menu')
+ assert dmodels, "no models for %s" % field_name
+
+ for module_rec in self.browse(cr, uid, ids, context=context):
+ res[module_rec.id] = {
+ 'menus_by_module': [],
+ 'reports_by_module': [],
'views_by_module': []
}
- if not mnames:
- return res
+ # Skip uninstalled modules below, no data to find anyway.
+ if module_rec.state not in ('installed', 'to upgrade', 'to remove'):
+ continue
- view_id = model_data_obj.search(cr,uid,[('module','in', mnames.keys()),
- ('model','in',('ir.ui.view','ir.actions.report.xml','ir.ui.menu'))])
- for data_id in model_data_obj.browse(cr,uid,view_id,context):
- # We use try except, because views or menus may not exist
+ # then, search and group ir.model.data records
+ imd_models = dict( [(m,[]) for m in dmodels])
+ imd_ids = model_data_obj.search(cr,uid,[('module','=', module_rec.name),
+ ('model','in',tuple(dmodels))])
+
+ for imd_res in model_data_obj.read(cr, uid, imd_ids, ['model', 'res_id'], context=context):
+ imd_models[imd_res['model']].append(imd_res['res_id'])
+
+ # For each one of the models, get the names of these ids.
+ # We use try except, because views or menus may not exist.
try:
- key = data_id.model
- res_mod_dic = res[mnames[data_id.module]]
- if key=='ir.ui.view':
- v = view_obj.browse(cr,uid,data_id.res_id)
+ res_mod_dic = res[module_rec.id]
+ for v in view_obj.browse(cr, uid, imd_models.get('ir.ui.view', []), context=context):
aa = v.inherit_id and '* INHERIT ' or ''
res_mod_dic['views_by_module'].append(aa + v.name + '('+v.type+')')
- elif key=='ir.actions.report.xml':
- res_mod_dic['reports_by_module'].append(report_obj.browse(cr,uid,data_id.res_id).name)
- elif key=='ir.ui.menu':
- res_mod_dic['menus_by_module'].append(menu_obj.browse(cr,uid,data_id.res_id).complete_name)
+
+ for rx in report_obj.browse(cr, uid, imd_models.get('ir.actions.report.xml', []), context=context):
+ res_mod_dic['reports_by_module'].append(rx.name)
+
+ for um in menu_obj.browse(cr, uid, imd_models.get('ir.ui.menu', []), context=context):
+ res_mod_dic['menus_by_module'].append(um.complete_name)
except KeyError, e:
self.__logger.warning(
- 'Data not found for reference %s[%s:%s.%s]', data_id.model,
- data_id.res_id, data_id.model, data_id.name, exc_info=True)
- pass
+ 'Data not found for items of %s', module_rec.name)
+ except AttributeError, e:
+ self.__logger.warning(
+ 'Data not found for items of %s %s', module_rec.name, str(e))
except Exception, e:
- self.__logger.warning('Unknown error while browsing %s[%s]',
- data_id.model, data_id.res_id, exc_info=True)
- pass
+ self.__logger.warning('Unknown error while fetching data of %s',
+ module_rec.name, exc_info=True)
for key, value in res.iteritems():
- for k, v in res[key].iteritems() :
+ for k, v in res[key].iteritems():
res[key][k] = "\n".join(sorted(v))
return res
@@ -437,12 +448,11 @@ class module(osv.osv):
res.append(mod.url)
if not download:
continue
- zipfile = urllib.urlopen(mod.url).read()
+ zip_content = urllib.urlopen(mod.url).read()
fname = addons.get_module_path(str(mod.name)+'.zip', downloaded=True)
try:
- fp = file(fname, 'wb')
- fp.write(zipfile)
- fp.close()
+ with open(fname, 'wb') as fp:
+ fp.write(zip_content)
except Exception:
self.__logger.exception('Error when trying to create module '
'file %s', fname)
diff --git a/openerp/addons/base/module/wizard/base_import_language.py b/openerp/addons/base/module/wizard/base_import_language.py
index d73cd0864a6..fdb9a177d8b 100644
--- a/openerp/addons/base/module/wizard/base_import_language.py
+++ b/openerp/addons/base/module/wizard/base_import_language.py
@@ -35,9 +35,12 @@ class base_language_import(osv.osv_memory):
'name': fields.char('Language Name',size=64 , required=True),
'code': fields.char('Code (eg:en__US)',size=5 , required=True),
'data': fields.binary('File', required=True),
+ 'overwrite': fields.boolean('Overwrite Existing Terms',
+ help="If you enable this option, existing translations (including custom ones) "
+ "will be overwritten and replaced by those in this file"),
}
- def import_lang(self, cr, uid, ids, context):
+ def import_lang(self, cr, uid, ids, context=None):
"""
Import Language
@param cr: the current row, from the database cursor.
@@ -45,8 +48,11 @@ class base_language_import(osv.osv_memory):
@param ids: the ID or list of IDs
@param context: A standard dictionary
"""
-
+ if context is None:
+ context = {}
import_data = self.browse(cr, uid, ids)[0]
+ if import_data.overwrite:
+ context.update(overwrite=True)
fileobj = TemporaryFile('w+')
fileobj.write(base64.decodestring(import_data.data))
@@ -56,7 +62,7 @@ class base_language_import(osv.osv_memory):
fileformat = first_line.endswith("type,name,res_id,src,value") and 'csv' or 'po'
fileobj.seek(0)
- tools.trans_load_data(cr, fileobj, fileformat, import_data.code, lang_name=import_data.name)
+ tools.trans_load_data(cr, fileobj, fileformat, import_data.code, lang_name=import_data.name, context=context)
tools.trans_update_res_ids(cr)
fileobj.close()
return {}
diff --git a/openerp/addons/base/module/wizard/base_import_language_view.xml b/openerp/addons/base/module/wizard/base_import_language_view.xml
index d313afc4080..4a1d7e5b758 100644
--- a/openerp/addons/base/module/wizard/base_import_language_view.xml
+++ b/openerp/addons/base/module/wizard/base_import_language_view.xml
@@ -27,6 +27,7 @@
+
diff --git a/openerp/addons/base/module/wizard/base_module_import.py b/openerp/addons/base/module/wizard/base_module_import.py
index 05c3b18198d..3ef9132af0e 100644
--- a/openerp/addons/base/module/wizard/base_module_import.py
+++ b/openerp/addons/base/module/wizard/base_module_import.py
@@ -28,6 +28,8 @@ import base64
from tools.translate import _
from osv import osv, fields
+ADDONS_PATH = tools.config['addons_path'].split(",")[-1]
+
class base_module_import(osv.osv_memory):
""" Import Module """
@@ -37,7 +39,8 @@ class base_module_import(osv.osv_memory):
_columns = {
'module_file': fields.binary('Module .ZIP file', required=True),
- 'state':fields.selection([('init','init'),('done','done')], 'state', readonly=True),
+ 'state':fields.selection([('init','init'),('done','done')],
+ 'state', readonly=True),
'module_name': fields.char('Module Name', size=128),
}
@@ -48,26 +51,30 @@ class base_module_import(osv.osv_memory):
def importzip(self, cr, uid, ids, context):
(data,) = self.browse(cr, uid, ids , context=context)
module_data = data.module_file
-
- val = base64.decodestring(module_data)
+ zip_data = base64.decodestring(module_data)
fp = StringIO()
- fp.write(val)
- fdata = zipfile.ZipFile(fp, 'r')
- fname = fdata.namelist()[0]
- module_name = os.path.split(fname)[0]
-
- ad = tools.config['addons_path'].split(",")[-1]
-
- fname = os.path.join(ad, module_name+'.zip')
+ fp.write(zip_data)
try:
- fp = file(fname, 'wb')
- fp.write(val)
- fp.close()
- except IOError:
- raise osv.except_osv(_('Error !'), _('Can not create the module file: %s !') % (fname,) )
+ file_data = zipfile.ZipFile(fp, 'r')
+ except zipfile.BadZipfile:
+ raise osv.except_osv(_('Error !'), _('File is not a zip file!'))
+ init_file_name = sorted(file_data.namelist())[0]
+ module_name = os.path.split(init_file_name)[0]
- self.pool.get('ir.module.module').update_list(cr, uid, {'module_name': module_name,})
- self.write(cr, uid, ids, {'state':'done', 'module_name': module_name}, context)
+ file_path = os.path.join(ADDONS_PATH, '%s.zip' % module_name)
+ try:
+ zip_file = open(file_path, 'wb')
+ except IOError:
+ raise osv.except_osv(_('Error !'),
+ _('Can not create the module file: %s !') % \
+ (file_path,) )
+ zip_file.write(zip_data)
+ zip_file.close()
+
+ self.pool.get('ir.module.module').update_list(cr, uid,
+ {'module_name': module_name,})
+ self.write(cr, uid, ids, {'state':'done', 'module_name': module_name},
+ context)
return False
def action_module_open(self, cr, uid, ids, context):
@@ -84,4 +91,4 @@ class base_module_import(osv.osv_memory):
base_module_import()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/addons/base/module/wizard/base_module_import_view.xml b/openerp/addons/base/module/wizard/base_module_import_view.xml
index 8e43789b057..0ca3e14ea96 100644
--- a/openerp/addons/base/module/wizard/base_module_import_view.xml
+++ b/openerp/addons/base/module/wizard/base_module_import_view.xml
@@ -12,9 +12,10 @@
-
+
-
+
diff --git a/openerp/addons/base/res/__init__.py b/openerp/addons/base/res/__init__.py
index 9ce69f0c317..2b4da739f54 100644
--- a/openerp/addons/base/res/__init__.py
+++ b/openerp/addons/base/res/__init__.py
@@ -29,10 +29,10 @@ import res_bank
import res_config
import res_currency
import res_company
-import res_user
+import res_users
import res_request
-import res_lang
-import res_log
+import res_lang
+import res_log
import res_widget
import ir_property
diff --git a/openerp/addons/base/res/ir_property_view.xml b/openerp/addons/base/res/ir_property_view.xml
index af836a3c92e..67b3357a4df 100644
--- a/openerp/addons/base/res/ir_property_view.xml
+++ b/openerp/addons/base/res/ir_property_view.xml
@@ -13,6 +13,7 @@
help="Parameters that are used by all resources."
domain="[('res_id','=',False)]"/>
+
diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py
index 3ad0cfcfb55..dc07b55a78e 100644
--- a/openerp/addons/base/res/res_company.py
+++ b/openerp/addons/base/res/res_company.py
@@ -143,6 +143,9 @@ class res_company(osv.osv):
'vat': fields.related('partner_id', 'vat', string="Tax ID", type="char", size=32),
'company_registry': fields.char('Company Registry', size=64),
}
+ _sql_constraints = [
+ ('name_uniq', 'unique (name)', 'The company name must be unique !')
+ ]
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False, access_rights_uid=None):
diff --git a/openerp/addons/base/res/res_currency.py b/openerp/addons/base/res/res_currency.py
index 3b7e427a923..bb6a51a6bcb 100644
--- a/openerp/addons/base/res/res_currency.py
+++ b/openerp/addons/base/res/res_currency.py
@@ -62,15 +62,34 @@ class res_currency(osv.osv):
'active': fields.boolean('Active'),
'company_id':fields.many2one('res.company', 'Company'),
'date': fields.date('Date'),
- 'base': fields.boolean('Base')
-
+ 'base': fields.boolean('Base'),
+ 'position': fields.selection([('after','After Amount'),('before','Before Amount')], 'Symbol position', help="Determines where the currency symbol should be placed after or before the amount.")
}
_defaults = {
'active': lambda *a: 1,
- 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'res.currency', context=c)
+ 'position' : 'after',
}
+ _sql_constraints = [
+ # this constraint does not cover all cases due to SQL NULL handling for company_id,
+ # so it is complemented with a unique index (see below). The constraint and index
+ # share the same prefix so that IntegrityError triggered by the index will be caught
+ # and reported to the user with the constraint's error message.
+ ('unique_name_company_id', 'unique (name, company_id)', 'The currency code must be unique per company!'),
+ ]
_order = "name"
+ def init(self, cr):
+ # CONSTRAINT/UNIQUE INDEX on (name,company_id)
+ # /!\ The unique constraint 'unique_name_company_id' is not sufficient, because SQL92
+ # only support field names in constraint definitions, and we need a function here:
+ # we need to special-case company_id to treat all NULL company_id as equal, otherwise
+ # we would allow duplicate "global" currencies (all having company_id == NULL)
+ cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'res_currency_unique_name_company_id_idx'""")
+ if not cr.fetchone():
+ cr.execute("""CREATE UNIQUE INDEX res_currency_unique_name_company_id_idx
+ ON res_currency
+ (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)
currency_rate_obj = self.pool.get('res.currency.rate')
@@ -150,7 +169,7 @@ res_currency()
class res_currency_rate_type(osv.osv):
_name = "res.currency.rate.type"
- _description = "Used to define the type of Currency Rates"
+ _description = "Currency Rate Type"
_columns = {
'name': fields.char('Name', size=64, required=True, translate=True),
}
diff --git a/openerp/addons/base/res/res_currency_view.xml b/openerp/addons/base/res/res_currency_view.xml
index 8d747c882b1..7dab4c051f4 100644
--- a/openerp/addons/base/res/res_currency_view.xml
+++ b/openerp/addons/base/res/res_currency_view.xml
@@ -2,6 +2,18 @@
+
+ res.currency.search
+ res.currency
+ search
+
+
+
+
+
+
+
+
res.currency.treeres.currency
@@ -9,12 +21,13 @@
-
+
+
@@ -25,23 +38,30 @@
form
diff --git a/openerp/addons/base/res/res_lang.py b/openerp/addons/base/res/res_lang.py
index f6743a54062..50841241f8a 100644
--- a/openerp/addons/base/res/res_lang.py
+++ b/openerp/addons/base/res/res_lang.py
@@ -194,7 +194,7 @@ class lang(osv.osv):
trans_obj.unlink(cr, uid, trans_ids, context=context)
return super(lang, self).unlink(cr, uid, ids, context=context)
- def format(self, cr, uid, ids, percent, value, grouping=False, monetary=False):
+ def format(self, cr, uid, ids, percent, value, grouping=False, monetary=False, context=None):
""" Format() will return the language-specific output for float values"""
if percent[0] != '%':
diff --git a/openerp/addons/base/res/res_partner_demo.xml b/openerp/addons/base/res/res_partner_demo.xml
index e8d8d540422..d3c4db106f9 100644
--- a/openerp/addons/base/res/res_partner_demo.xml
+++ b/openerp/addons/base/res/res_partner_demo.xml
@@ -90,67 +90,88 @@
ASUStek
- 1
+
+ www.asustek.comAgrolait
-
+
+
+ www.agrolait.comCamptocamp1
+
+ www.camptocamp.com
- http://www.syleam.fr
+ www.syleam.frSyleam
+ Thymbra
+
+ www.thymbra.com/Axelor1
+
+ www.axelor.com/Tiny AT Work
+
+ www.tinyatwork.com/Bank Wealthy and sons
+
+ www.wealthyandsons.com/China Export
+
+ www.chinaexport.com/Distrib PC1
+
+ www.distribpc.com/Ecole de Commerce de Liege
+
+ www.eci-liege.info//Elec Import1
+
@@ -159,6 +180,7 @@
1
+
@@ -177,11 +199,11 @@
- http://balmerinc.com
+ www.balmerinc.comBalmerInc S.A.or
-
+
@@ -190,6 +212,7 @@
3020170000003
+ Leclerc
@@ -205,6 +228,7 @@
+ Magazin BML 1
@@ -219,6 +243,8 @@
Université de Liège
+
+ http://www.ulg.ac.be/
- ['|','|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id]),('company_id','=',False)]
-
+
-
- Multi_company_default company
-
-
- [('company_id','child_of',[user.company_id.id])]
-
+
+ res.widget.user rule
+
+
+ ['|', ('user_id','=',user.id),('user_id','=',False)]
+
+
+
+ res.partner company
+
+
+
+ ['|','|',('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id]),('company_id','=',False)]
+
+
+
+ Multi_company_default company
+
+
+ [('company_id','child_of',[user.company_id.id])]
+
diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv
index 8949052f89b..659938a73a3 100644
--- a/openerp/addons/base/security/ir.model.access.csv
+++ b/openerp/addons/base/security/ir.model.access.csv
@@ -48,6 +48,7 @@
"access_res_country_state_group_user","res_country_state group_user","model_res_country_state","group_partner_manager",1,1,1,1
"access_res_currency_group_all","res_currency group_all","model_res_currency",,1,0,0,0
"access_res_currency_rate_group_all","res_currency_rate group_all","model_res_currency_rate",,1,0,0,0
+"access_res_currency_rate_type_group_all","res_currency_rate_type group_all","model_res_currency_rate_type",,1,0,0,0
"access_res_currency_group_system","res_currency group_system","model_res_currency","group_system",1,1,1,1
"access_res_currency_rate_group_system","res_currency_rate group_system","model_res_currency_rate","group_system",1,1,1,1
"access_res_groups_group_erp_manager","res_groups group_erp_manager","model_res_groups","group_erp_manager",1,1,1,1
@@ -123,4 +124,6 @@
"access_res_widget_user","res.widget.user","model_res_widget",,1,0,0,0
"access_res_log_all","res.log","model_res_log",,1,1,1,1
"access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0
+"access_ir_mail_server_all","ir_mail_server","model_ir_mail_server",,1,0,0,0
"access_ir_actions_todo_category","ir_actions_todo_category","model_ir_actions_todo_category","group_system",1,1,1,1
+"access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0
diff --git a/openerp/addons/base/test/test_osv_expression.yml b/openerp/addons/base/test/test_osv_expression.yml
index 3a5e41dacc7..43fea5c16cf 100644
--- a/openerp/addons/base/test/test_osv_expression.yml
+++ b/openerp/addons/base/test/test_osv_expression.yml
@@ -177,6 +177,251 @@
res_ids = self.search(cr, uid, [('company_id.partner_id', 'not in', [])])
res_ids.sort()
assert res_ids == all_ids, "Searching against empty set failed, returns %r" % res_ids
+-
+ Test the '(not) like/in' behavior. res.partner and its parent_id column are used because
+ parent_id is a many2one, allowing to test the Null value, and there are actually some
+ null and non-null values in the demo data.
+-
+ !python {model: res.partner }: |
+ partner_ids = self.search(cr, uid, [])
+ partner_ids.sort()
+ max_partner_id = max(partner_ids)
+
+ # Grab test sample data without using a normal
+ # search domain, because we want to test these later,
+ # so we can't rely on them!
+ partners = self.browse(cr, uid, partner_ids)
+ with_parent = []
+ without_parent = []
+ with_website = []
+ for x in partners:
+ if x.parent_id:
+ with_parent.append(x.id)
+ else:
+ without_parent.append(x.id)
+ if x.website:
+ with_website.append(x.id)
+ with_parent.sort()
+ without_parent.sort()
+ with_website.sort()
+
+ # We treat null values differently than in SQL. For instance in SQL:
+ # SELECT id FROM res_partner WHERE parent_id NOT IN (0)
+ # will return only the records with non-null parent_id.
+ # SELECT id FROM res_partner WHERE parent_id IN (0)
+ # will return expectedly nothing (our ids always begin at 1).
+ # This means the union of those two results will give only some
+ # records, but not all present in database.
+ #
+ # When using domains and the ORM's search method, we think it is
+ # more intuitive that the union returns all the records, and that
+ # a domain like ('parent_id', 'not in', [0]) will return all
+ # the records. For instance, if you perform a search for the companies
+ # that don't have OpenERP has a parent company, you expect to find,
+ # among others, the companies that don't have parent company.
+ #
+ # ('parent_id', 'not in', [0]) must give the same result than
+ # ('parent_id', 'not in', []), i.e. a empty set or a set with non-
+ # existing values be treated similarly if we simply check that some
+ # existing value belongs to them.
+
+ res_0 = self.search(cr, uid, [('parent_id', 'not like', 'probably_unexisting_name')]) # get all rows, included null parent_id
+ res_0.sort()
+ res_1 = self.search(cr, uid, [('parent_id', 'not in', [max_partner_id + 1])]) # get all rows, included null parent_id
+ res_1.sort()
+ res_2 = self.search(cr, uid, [('parent_id', 'not in', False)]) # get rows with not null parent_id, deprecated syntax
+ res_2.sort()
+ res_3 = self.search(cr, uid, [('parent_id', 'not in', [])]) # get all rows, included null parent_id
+ res_3.sort()
+ res_4 = self.search(cr, uid, [('parent_id', 'not in', [False])]) # get rows with not null parent_id
+ res_4.sort()
+ assert res_0 == partner_ids
+ assert res_1 == partner_ids
+ assert res_2 == with_parent
+ assert res_3 == partner_ids
+ assert res_4 == with_parent
+ # The results of these queries, when combined with queries 0..4 must
+ # give the whole set of ids.
+ res_5 = self.search(cr, uid, [('parent_id', 'like', 'probably_unexisting_name')])
+ res_5.sort()
+ res_6 = self.search(cr, uid, [('parent_id', 'in', [max_partner_id + 1])])
+ res_6.sort()
+ res_7 = self.search(cr, uid, [('parent_id', 'in', False)])
+ res_7.sort()
+ res_8 = self.search(cr, uid, [('parent_id', 'in', [])])
+ res_8.sort()
+ res_9 = self.search(cr, uid, [('parent_id', 'in', [False])])
+ res_9.sort()
+ assert res_5 == []
+ assert res_6 == []
+ assert res_7 == without_parent
+ assert res_8 == []
+ assert res_9 == without_parent
+ # These queries must return exactly the results than the queries 0..4,
+ # i.e. not ... in ... must be the same as ... not in ... .
+ res_10 = self.search(cr, uid, ['!', ('parent_id', 'like', 'probably_unexisting_name')])
+ res_10.sort()
+ res_11 = self.search(cr, uid, ['!', ('parent_id', 'in', [max_partner_id + 1])])
+ res_11.sort()
+ res_12 = self.search(cr, uid, ['!', ('parent_id', 'in', False)])
+ res_12.sort()
+ res_13 = self.search(cr, uid, ['!', ('parent_id', 'in', [])])
+ res_13.sort()
+ res_14 = self.search(cr, uid, ['!', ('parent_id', 'in', [False])])
+ res_14.sort()
+ assert res_0 == res_10
+ assert res_1 == res_11
+ assert res_2 == res_12
+ assert res_3 == res_13
+ assert res_4 == res_14
+
+ # Testing many2one field is not enough, a regular char field is tested
+ # with in [] and must not return any result.
+ res_15 = self.search(cr, uid, [('website', 'in', [])])
+ assert res_15 == []
+ # not in [] must return everything.
+ res_16 = self.search(cr, uid, [('website', 'not in', [])])
+ res_16.sort()
+ assert res_16 == partner_ids
+
+ res_17 = self.search(cr, uid, [('website', 'not in', False)])
+ res_17.sort()
+ assert res_17 == with_website
+-
+ Property of the query (one2many not in False).
+-
+ !python {model: res.currency }: |
+ ids = self.search(cr, uid, [])
+ referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)])
+ companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', 'not in', False)]))
+ assert referenced_companies == companies
+-
+ Property of the query (one2many in False).
+-
+ !python {model: res.currency }: |
+ ids = self.search(cr, uid, [])
+ referenced_companies = set([x.company_id.id for x in self.browse(cr, uid, ids)])
+ unreferenced_companies = set(self.pool.get('res.company').search(cr, uid, [])).difference(referenced_companies)
+ companies = set(self.pool.get('res.company').search(cr, uid, [('currency_ids', 'in', False)]))
+ assert unreferenced_companies == companies
+-
+ Equivalent queries.
+-
+ !python {model: res.currency }: |
+ max_currency_id = max(self.search(cr, uid, []))
+ res_0 = self.search(cr, uid, [])
+ res_1 = self.search(cr, uid, [('name', 'not like', 'probably_unexisting_name')])
+ res_2 = self.search(cr, uid, [('id', 'not in', [max_currency_id + 1003])])
+ res_3 = self.search(cr, uid, [('id', 'not in', [])])
+ res_4 = self.search(cr, uid, [('id', 'not in', False)])
+ res_0.sort()
+ res_1.sort()
+ res_2.sort()
+ res_3.sort()
+ res_4.sort()
+ assert res_0 == res_1
+ assert res_0 == res_2
+ assert res_0 == res_3
+ assert res_0 == res_4
+-
+ Equivalent queries, integer and string.
+-
+ !python {model: res.partner }: |
+ all_ids = self.search(cr, uid, [])
+ if len(all_ids) > 1:
+ one = all_ids[0]
+ record = self.browse(cr, uid, one)
+ others = all_ids[1:]
+ res_1 = self.search(cr, uid, [('id', '=', one)])
+ # self.search(cr, uid, [('id', '!=', others)]) # not permitted
+ res_2 = self.search(cr, uid, [('id', 'not in', others)])
+ res_3 = self.search(cr, uid, ['!', ('id', '!=', one)])
+ res_4 = self.search(cr, uid, ['!', ('id', 'in', others)])
+ # res_5 = self.search(cr, uid, [('id', 'in', one)]) # TODO make it permitted, just like for child_of
+ res_6 = self.search(cr, uid, [('id', 'in', [one])])
+ res_7 = self.search(cr, uid, [('name', '=', record.name)])
+ res_8 = self.search(cr, uid, [('name', 'in', [record.name])])
+ # res_9 = self.search(cr, uid, [('name', 'in', record.name)]) # TODO
+ assert [one] == res_1
+ assert [one] == res_2
+ assert [one] == res_3
+ assert [one] == res_4
+ #assert [one] == res_5
+ assert [one] == res_6
+ assert [one] == res_7
+-
+ Need a company with a parent_id.
+-
+ !record {model: res.company, id: ymltest_company3}:
+ name: Acme 3
+-
+ Need a company with a parent_id.
+-
+ !record {model: res.company, id: ymltest_company4}:
+ name: Acme 4
+ parent_id: ymltest_company3
+-
+ Equivalent queries, one2many.
+-
+ !python {model: res.company }: |
+ # Search the company via its one2many (the one2many must point back at the company).
+ company = self.browse(cr, uid, ref('ymltest_company3'))
+ max_currency_id = max(self.pool.get('res.currency').search(cr, uid, []))
+ currency_ids1 = self.pool.get('res.currency').search(cr, uid, [('name', 'not like', 'probably_unexisting_name')])
+ currency_ids2 = self.pool.get('res.currency').search(cr, uid, [('id', 'not in', [max_currency_id + 1003])])
+ currency_ids3 = self.pool.get('res.currency').search(cr, uid, [('id', 'not in', [])])
+ assert currency_ids1 == currency_ids2 == currency_ids3, 'All 3 results should have be the same: all currencies'
+ default_company = self.browse(cr, uid, 1)
+ # one2many towards same model
+ res_1 = self.search(cr, uid, [('child_ids', 'in', [x.id for x in company.child_ids])]) # any company having a child of company3 as child
+ res_2 = self.search(cr, uid, [('child_ids', 'in', [company.child_ids[0].id])]) # any company having the first child of company3 as child
+ # one2many towards another model
+ res_3 = self.search(cr, uid, [('currency_ids', 'in', [x.id for x in default_company.currency_ids])]) # companies having a currency of main company
+ res_4 = self.search(cr, uid, [('currency_ids', 'in', [default_company.currency_ids[0].id])]) # companies having first currency of main company
+ res_5 = self.search(cr, uid, [('currency_ids', 'in', default_company.currency_ids[0].id)]) # companies having first currency of main company
+ # res_6 = self.search(cr, uid, [('currency_ids', 'in', [default_company.currency_ids[0].name])]) # TODO
+ res_7 = self.search(cr, uid, [('currency_ids', '=', default_company.currency_ids[0].name)])
+ res_8 = self.search(cr, uid, [('currency_ids', 'like', default_company.currency_ids[0].name)])
+ res_9 = self.search(cr, uid, [('currency_ids', 'like', 'probably_unexisting_name')])
+ # self.search(cr, uid, [('currency_ids', 'unexisting_op', 'probably_unexisting_name')]) # TODO expected exception
+ assert res_1 == [ref('ymltest_company3')]
+ assert res_2 == [ref('ymltest_company3')]
+ assert res_3 == [1]
+ assert res_4 == [1]
+ assert res_5 == [1]
+ assert res_7 == [1]
+ assert res_8 == [1]
+ assert res_9 == []
+
+ # get the companies referenced by some currency (this is normally the main company)
+ res_10 = self.search(cr, uid, [('currency_ids', 'not like', 'probably_unexisting_name')])
+ res_11 = self.search(cr, uid, [('currency_ids', 'not in', [max_currency_id + 1])])
+ res_12 = self.search(cr, uid, [('currency_ids', 'not in', False)])
+ res_13 = self.search(cr, uid, [('currency_ids', 'not in', [])])
+ res_10.sort()
+ res_11.sort()
+ res_12.sort()
+ res_13.sort()
+ assert res_10 == res_11
+ assert res_10 == res_12
+ assert res_10 == res_13
+
+ # child_of x returns x and its children (direct or not).
+ company = self.browse(cr, uid, ref('ymltest_company3'))
+ expected = [ref('ymltest_company3'), ref('ymltest_company4')]
+ expected.sort()
+ res_1 = self.search(cr, uid, [('id', 'child_of', [ref('ymltest_company3')])])
+ res_1.sort()
+ res_2 = self.search(cr, uid, [('id', 'child_of', ref('ymltest_company3'))])
+ res_2.sort()
+ res_3 = self.search(cr, uid, [('id', 'child_of', [company.name])])
+ res_3.sort()
+ res_4 = self.search(cr, uid, [('id', 'child_of', company.name)])
+ res_4.sort()
+ assert res_1 == expected
+ assert res_2 == expected
+ assert res_3 == expected
+ assert res_4 == expected
-
Verify that normalize_domain() works.
-
@@ -187,6 +432,72 @@
domain = [('x','in',['y','z']),('a.v','=','e'),'|','|',('a','=','b'),'!',('c','>','d'),('e','!=','f'),('g','=','h')]
norm_domain = ['&','&','&'] + domain
assert norm_domain == expression.normalize(domain), "Non-normalized domains should be properly normalized"
+-
+ Unaccent. Create a company with an accent in its name.
+-
+ !record {model: res.company, id: ymltest_unaccent_company}:
+ name: Hélène
+-
+ Test the unaccent-enabled 'ilike'.
+-
+ !python {model: res.company}: |
+ if self.pool.has_unaccent:
+ ids = self.search(cr, uid, [('name','ilike','Helene')], {})
+ assert ids == [ref('ymltest_unaccent_company')]
+ ids = self.search(cr, uid, [('name','ilike','hélène')], {})
+ assert ids == [ref('ymltest_unaccent_company')]
+ ids = self.search(cr, uid, [('name','not ilike','Helene')], {})
+ assert ref('ymltest_unaccent_company') not in ids
+ ids = self.search(cr, uid, [('name','not ilike','hélène')], {})
+ assert ref('ymltest_unaccent_company') not in ids
+-
+ Check that =like/=ilike expressions (no wildcard variants of like/ilike) are working on an untranslated field.
+-
+ !python {model: res.partner }: |
+ all_ids = self.search(cr, uid, [('name', '=like', 'A_e_or')])
+ assert len(all_ids) == 1, "Must match one partner (Axelor), got %r"%all_ids
+ all_ids = self.search(cr, uid, [('name', '=ilike', 'm_____')])
+ assert len(all_ids) == 1, "Must match *only* one partner (Maxtor), got %r"%all_ids
+-
+ Check that =like/=ilike expressions (no wildcard variants of like/ilike) are working on translated field.
+-
+ !python {model: res.country }: |
+ all_ids = self.search(cr, uid, [('name', '=like', 'Ind__')])
+ assert len(all_ids) == 1, "Must match India only, got %r"%all_ids
+ all_ids = self.search(cr, uid, [('name', '=ilike', 'z%')])
+ assert len(all_ids) == 3, "Must match only countries with names starting with Z (currently 3), got %r"%all_ids
+-
+ Use the create_date column on res.country (which doesn't declare it in _columns).
+-
+ !python {model: res.country }: |
+ ids = self.search(cr, uid, [('create_date', '<', '2001-01-01 12:00:00')])
+-
+ Verify that invalid expressions are refused, even for magic fields
+-
+ !python {model: res.country }: |
+ try:
+ self.search(cr, uid, [('does_not_exist', '=', 'foo')])
+ raise AssertionError('Invalid fields should not be accepted')
+ except ValueError:
+ pass
+
+ try:
+ self.search(cr, uid, [('create_date', '>>', 'foo')])
+ raise AssertionError('Invalid operators should not be accepted')
+ except ValueError:
+ pass
+
+ import psycopg2
+ try:
+ cr._default_log_exceptions = False
+ cr.execute('SAVEPOINT expression_failure_test')
+ self.search(cr, uid, [('create_date', '=', "1970-01-01'); --")])
+ # if the above search gives no error, the operand was not escaped!
+ cr.execute('RELEASE SAVEPOINT expression_failure_test')
+ raise AssertionError('Operands should always be SQL escaped')
+ except psycopg2.DataError:
+ # Should give: 'DataError: invalid input syntax for type timestamp' or similar
+ cr.execute('ROLLBACK TO SAVEPOINT expression_failure_test')
diff --git a/openerp/modules/db.py b/openerp/modules/db.py
index 25ce7283c97..6e6dd64b13c 100644
--- a/openerp/modules/db.py
+++ b/openerp/modules/db.py
@@ -21,6 +21,7 @@
##############################################################################
import openerp.modules
+import logging
def is_initialized(cr):
""" Check if a database has been initialized for the ORM.
@@ -40,6 +41,10 @@ def initialize(cr):
"""
f = openerp.modules.get_module_resource('base', 'base.sql')
+ if not f:
+ m = "File not found: 'base.sql' (provided by module 'base')."
+ logging.getLogger('init').critical(m)
+ raise IOError(m)
base_sql_file = openerp.tools.misc.file_open(f)
try:
cr.execute(base_sql_file.read())
@@ -118,4 +123,14 @@ def create_categories(cr, categories):
categories = categories[1:]
return p_id
+def has_unaccent(cr):
+ """ Test if the database has an unaccent function.
+
+ The unaccent is supposed to be provided by the PostgreSQL unaccent contrib
+ module but any similar function will be picked by OpenERP.
+
+ """
+ cr.execute("SELECT proname FROM pg_proc WHERE proname='unaccent'")
+ return len(cr.fetchall()) > 0
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py
index 4bc8e440b62..40986580d1b 100644
--- a/openerp/modules/loading.py
+++ b/openerp/modules/loading.py
@@ -347,7 +347,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
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):
+ 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))
cr.execute("SELECT model from ir_model")
diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py
index e88852a8c18..f35adadbf2f 100644
--- a/openerp/modules/registry.py
+++ b/openerp/modules/registry.py
@@ -22,10 +22,14 @@
""" Models registries.
"""
+import threading
+
+import logging
import openerp.sql_db
import openerp.osv.orm
-
+import openerp.modules.db
+import openerp.tools.config
class Registry(object):
""" Model registry for a particular database.
@@ -44,6 +48,14 @@ class Registry(object):
self.db_name = db_name
self.db = openerp.sql_db.db_connect(db_name)
+ cr = self.db.cursor()
+ has_unaccent = openerp.modules.db.has_unaccent(cr)
+ if openerp.tools.config['unaccent'] and not has_unaccent:
+ logger = logging.getLogger('unaccent')
+ logger.warning("The option --unaccent was given but no unaccent() function was found in database.")
+ self.has_unaccent = openerp.tools.config['unaccent'] and has_unaccent
+ cr.close()
+
def do_parent_store(self, cr):
for o in self._init_parent:
self.get(o)._parent_store_compute(cr)
@@ -93,7 +105,6 @@ class Registry(object):
for model in self.models.itervalues():
model.clear_caches()
-
class RegistryManager(object):
""" Model registries manager.
@@ -105,19 +116,20 @@ class RegistryManager(object):
# Mapping between db name and model registry.
# Accessed through the methods below.
registries = {}
+ registries_lock = threading.RLock()
@classmethod
def get(cls, db_name, force_demo=False, status=None, update_module=False,
pooljobs=True):
""" Return a registry for a given database name."""
-
- if db_name in cls.registries:
- registry = cls.registries[db_name]
- else:
- registry = cls.new(db_name, force_demo, status,
- update_module, pooljobs)
- return registry
+ with cls.registries_lock:
+ if db_name in cls.registries:
+ registry = cls.registries[db_name]
+ else:
+ registry = cls.new(db_name, force_demo, status,
+ update_module, pooljobs)
+ return registry
@classmethod
@@ -128,42 +140,43 @@ class RegistryManager(object):
The (possibly) previous registry for that database name is discarded.
"""
-
import openerp.modules
- registry = Registry(db_name)
+ with cls.registries_lock:
+ registry = Registry(db_name)
- # Initializing a registry will call general code which will in turn
- # call registries.get (this object) to obtain the registry being
- # initialized. Make it available in the registries dictionary then
- # remove it if an exception is raised.
- cls.delete(db_name)
- cls.registries[db_name] = registry
- try:
- # This should be a method on Registry
- openerp.modules.load_modules(registry.db, force_demo, status, update_module)
- except Exception:
- del cls.registries[db_name]
- raise
+ # Initializing a registry will call general code which will in turn
+ # call registries.get (this object) to obtain the registry being
+ # initialized. Make it available in the registries dictionary then
+ # remove it if an exception is raised.
+ cls.delete(db_name)
+ cls.registries[db_name] = registry
+ try:
+ # This should be a method on Registry
+ openerp.modules.load_modules(registry.db, force_demo, status, update_module)
+ except Exception:
+ del cls.registries[db_name]
+ raise
- cr = registry.db.cursor()
- try:
- registry.do_parent_store(cr)
- registry.get('ir.actions.report.xml').register_all(cr)
- cr.commit()
- finally:
- cr.close()
+ cr = registry.db.cursor()
+ try:
+ registry.do_parent_store(cr)
+ registry.get('ir.actions.report.xml').register_all(cr)
+ cr.commit()
+ finally:
+ cr.close()
- if pooljobs:
- registry.get('ir.cron').restart(registry.db.dbname)
+ if pooljobs:
+ registry.get('ir.cron').restart(registry.db.dbname)
- return registry
+ return registry
@classmethod
def delete(cls, db_name):
""" Delete the registry linked to a given database. """
- if db_name in cls.registries:
- del cls.registries[db_name]
+ with cls.registries_lock:
+ if db_name in cls.registries:
+ del cls.registries[db_name]
@classmethod
@@ -177,8 +190,9 @@ class RegistryManager(object):
This method is given to spare you a ``RegistryManager.get(db_name)``
that would loads the given database if it was not already loaded.
"""
- if db_name in cls.registries:
- cls.registries[db_name].clear_caches()
+ with cls.registries_lock:
+ if db_name in cls.registries:
+ cls.registries[db_name].clear_caches()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py
index 54726a289f2..ff2528db73d 100644
--- a/openerp/osv/expression.py
+++ b/openerp/osv/expression.py
@@ -20,17 +20,146 @@
#
##############################################################################
+""" Domain expression processing
+
+The main duty of this module is to compile a domain expression into a SQL
+query. A lot of things should be documented here, but as a first step in the
+right direction, some tests in test_osv_expression.yml might give you some
+additional information.
+
+For legacy reasons, a domain uses an inconsistent two-levels abstract syntax
+(domains are regular Python data structures). At the first level, a domain
+is an expression made of terms (sometimes called leaves) and (domain) operators
+used in prefix notation. The available operators at this level are '!', '&',
+and '|'. '!' is a unary 'not', '&' is a binary 'and', and '|' is a binary 'or'.
+For instance, here is a possible domain. ( stands for an arbitrary term,
+more on this later.)
+
+ ['&', '!', , '|', , ]
+
+It is equivalent to this pseudo code using infix notation:
+
+ (not ) and ( or )
+
+The second level of syntax deals with the term representation. A term is
+a triple of the form (left, operator, right). That is, a term uses an infix
+notation, and the available operators, and possible left and right operands
+differ with those of the previous level. Here is a possible term:
+
+ ('company_id.name', '=', 'OpenERP')
+
+The left and right operand don't have the same possible values. The left
+operand is field name (related to the model for which the domain applies).
+Actually, the field name can use the dot-notation to traverse relationships.
+The right operand is a Python value whose type should match the used operator
+and field type. In the above example, a string is used because the name field
+of a company has type string, and because we use the '=' operator. When
+appropriate, a 'in' operator can be used, and thus the right operand should be
+a list.
+
+Note: the non-uniform syntax could have been more uniform, but this would hide
+an important limitation of the domain syntax. Say that the term representation
+was ['=', 'company_id.name', 'OpenERP']. Used in a complete domain, this would
+look like:
+
+ ['!', ['=', 'company_id.name', 'OpenERP']]
+
+and you would be tempted to believe something like this would be possible:
+
+ ['!', ['=', 'company_id.name', ['&', ..., ...]]]
+
+That is, a domain could be a valid operand. But this is not the case. A domain
+is really limited to a two-level nature, and can not takes a recursive form: a
+domain is not a valid second-level operand.
+
+Unaccent - Accent-insensitive search
+
+OpenERP will use the SQL function 'unaccent' when available for the 'ilike' and
+'not ilike' operators, and enabled in the configuration.
+Normally the 'unaccent' function is obtained from the PostgreSQL 'unaccent'
+contrib module[0].
+
+
+..todo: The following explanation should be moved in some external installation
+ guide
+
+The steps to install the module might differ on specific PostgreSQL versions.
+We give here some instruction for PostgreSQL 9.x on a Ubuntu system.
+
+Ubuntu doesn't come yet with PostgreSQL 9.x, so an alternative package source
+is used. We use Martin Pitt's PPA available at ppa:pitti/postgresql[1]. See
+[2] for instructions. Basically:
+
+ > sudo add-apt-repository ppa:pitti/postgresql
+ > sudo apt-get update
+
+Once the package list is up-to-date, you have to install PostgreSQL 9.0 and
+its contrib modules.
+
+ > sudo apt-get install postgresql-9.0 postgresql-contrib-9.0
+
+When you want to enable unaccent on some database:
+
+ > psql9 -f /usr/share/postgresql/9.0/contrib/unaccent.sql
+
+Here 'psql9' is an alias for the newly installed PostgreSQL 9.0 tool, together
+with the correct port if necessary (for instance if PostgreSQL 8.4 is running
+on 5432). (Other aliases can be used for createdb and dropdb.)
+
+ > alias psql9='/usr/lib/postgresql/9.0/bin/psql -p 5433'
+
+You can check unaccent is working:
+
+ > psql9 -c"select unaccent('hélène')"
+
+Finally, to instruct OpenERP to really use the unaccent function, you have to
+start the server specifying the --unaccent flag.
+
+[0] http://developer.postgresql.org/pgdocs/postgres/unaccent.html
+[1] https://launchpad.net/~pitti/+archive/postgresql
+[2] https://launchpad.net/+help/soyuz/ppa-sources-list.html
+
+"""
+
+import logging
+
from openerp.tools import flatten, reverse_enumerate
import fields
+import openerp.modules
+from openerp.osv.orm import MAGIC_COLUMNS
#.apidoc title: Domain Expressions
+# Domain operators.
NOT_OPERATOR = '!'
OR_OPERATOR = '|'
AND_OPERATOR = '&'
+DOMAIN_OPERATORS = (NOT_OPERATOR, OR_OPERATOR, AND_OPERATOR)
-TRUE_DOMAIN = [(1,'=',1)]
-FALSE_DOMAIN = [(0,'=',1)]
+# List of available term operators. It is also possible to use the '<>'
+# operator, which is strictly the same as '!='; the later should be prefered
+# for consistency. This list doesn't contain '<>' as it is simpified to '!='
+# by the normalize_operator() function (so later part of the code deals with
+# only one representation).
+# An internal (i.e. not available to the user) 'inselect' operator is also
+# used. In this case its right operand has the form (subselect, params).
+TERM_OPERATORS = ('=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike',
+ 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in',
+ 'child_of')
+
+# A subset of the above operators, with a 'negative' semantic. When the
+# expressions 'in NEGATIVE_TERM_OPERATORS' or 'not in NEGATIVE_TERM_OPERATORS' are used in the code
+# below, this doesn't necessarily mean that any of those NEGATIVE_TERM_OPERATORS is
+# legal in the processed term.
+NEGATIVE_TERM_OPERATORS = ('!=', 'not like', 'not ilike', 'not in')
+
+TRUE_LEAF = (1, '=', 1)
+FALSE_LEAF = (0, '=', 1)
+
+TRUE_DOMAIN = [TRUE_LEAF]
+FALSE_DOMAIN = [FALSE_LEAF]
+
+_logger = logging.getLogger('expression')
def normalize(domain):
"""Returns a normalized version of ``domain_expr``, where all implicit '&' operators
@@ -45,10 +174,10 @@ def normalize(domain):
op_arity = {NOT_OPERATOR: 1, AND_OPERATOR: 2, OR_OPERATOR: 2}
for token in domain:
if expected == 0: # more than expected, like in [A, B]
- result[0:0] = ['&'] # put an extra '&' in front
+ result[0:0] = [AND_OPERATOR] # put an extra '&' in front
expected = 1
result.append(token)
- if isinstance(token, (list,tuple)): # domain term
+ if isinstance(token, (list, tuple)): # domain term
expected -= 1
else:
expected += op_arity.get(token, 0) - 1
@@ -57,7 +186,8 @@ def normalize(domain):
def combine(operator, unit, zero, domains):
"""Returns a new domain expression where all domain components from ``domains``
- have been added together using the binary operator ``operator``.
+ have been added together using the binary operator ``operator``. The given
+ domains must be normalized.
:param unit: the identity element of the domains "set" with regard to the operation
performed by ``operator``, i.e the domain component ``i`` which, when
@@ -69,6 +199,7 @@ def combine(operator, unit, zero, domains):
combined with any domain ``x`` via ``operator``, yields ``z``.
E.g. [(1,'=',1)] is the typical zero for OR_OPERATOR: as soon as
you see it in a domain component the resulting domain is the zero.
+ :param domains: a list of normalized domains.
"""
result = []
count = 0
@@ -84,13 +215,130 @@ def combine(operator, unit, zero, domains):
return result
def AND(domains):
- """ AND([D1,D2,...]) returns a domain representing D1 and D2 and ... """
+ """AND([D1,D2,...]) returns a domain representing D1 and D2 and ... """
return combine(AND_OPERATOR, TRUE_DOMAIN, FALSE_DOMAIN, domains)
def OR(domains):
- """ OR([D1,D2,...]) returns a domain representing D1 or D2 or ... """
+ """OR([D1,D2,...]) returns a domain representing D1 or D2 or ... """
return combine(OR_OPERATOR, FALSE_DOMAIN, TRUE_DOMAIN, domains)
+def is_operator(element):
+ """Test whether an object is a valid domain operator. """
+ return isinstance(element, basestring) and element in DOMAIN_OPERATORS
+
+# TODO change the share wizard to use this function.
+def is_leaf(element, internal=False):
+ """ Test whether an object is a valid domain term.
+
+ :param internal: allow or not the 'inselect' internal operator in the term.
+ This normally should be always left to False.
+ """
+ INTERNAL_OPS = TERM_OPERATORS + ('inselect',)
+ return (isinstance(element, tuple) or isinstance(element, list)) \
+ and len(element) == 3 \
+ and (((not internal) and element[1] in TERM_OPERATORS + ('<>',)) \
+ or (internal and element[1] in INTERNAL_OPS + ('<>',)))
+
+def normalize_leaf(left, operator, right):
+ """ Change a term's operator to some canonical form, simplifying later
+ processing.
+ """
+ original = operator
+ operator = operator.lower()
+ if operator == '<>':
+ operator = '!='
+ if isinstance(right, bool) and operator in ('in', 'not in'):
+ _logger.warning("The domain term '%s' should use the '=' or '!=' operator." % ((left, original, right),))
+ operator = '=' if operator == 'in' else '!='
+ if isinstance(right, (list, tuple)) and operator in ('=', '!='):
+ _logger.warning("The domain term '%s' should use the 'in' or 'not in' operator." % ((left, original, right),))
+ operator = 'in' if operator == '=' else 'not in'
+ return left, operator, right
+
+def distribute_not(domain):
+ """ Distribute any '!' domain operators found inside a normalized domain.
+
+ Because we don't use SQL semantic for processing a 'left not in right'
+ query (i.e. our 'not in' is not simply translated to a SQL 'not in'),
+ it means that a '! left in right' can not be simply processed
+ by __leaf_to_sql by first emitting code for 'left in right' then wrapping
+ the result with 'not (...)', as it would result in a 'not in' at the SQL
+ level.
+
+ This function is thus responsible for pushing any '!' domain operators
+ inside the terms themselves. For example::
+
+ ['!','&',('user_id','=',4),('partner_id','in',[1,2])]
+ will be turned into:
+ ['|',('user_id','!=',4),('partner_id','not in',[1,2])]
+
+ """
+ def negate(leaf):
+ """Negates and returns a single domain leaf term,
+ using the opposite operator if possible"""
+ left, operator, right = leaf
+ mapping = {
+ '<': '>=',
+ '>': '<=',
+ '<=': '>',
+ '>=': '<',
+ '=': '!=',
+ '!=': '=',
+ }
+ if operator in ('in', 'like', 'ilike'):
+ operator = 'not ' + operator
+ return [(left, operator, right)]
+ if operator in ('not in', 'not like', 'not ilike'):
+ operator = operator[4:]
+ return [(left, operator, right)]
+ if operator in mapping:
+ operator = mapping[operator]
+ return [(left, operator, right)]
+ return [NOT_OPERATOR, (left, operator, right)]
+ def distribute_negate(domain):
+ """Negate the domain ``subtree`` rooted at domain[0],
+ leaving the rest of the domain intact, and return
+ (negated_subtree, untouched_domain_rest)
+ """
+ if is_leaf(domain[0]):
+ return negate(domain[0]), domain[1:]
+ if domain[0] == AND_OPERATOR:
+ done1, todo1 = distribute_negate(domain[1:])
+ done2, todo2 = distribute_negate(todo1)
+ return [OR_OPERATOR] + done1 + done2, todo2
+ if domain[0] == OR_OPERATOR:
+ done1, todo1 = distribute_negate(domain[1:])
+ done2, todo2 = distribute_negate(todo1)
+ return [AND_OPERATOR] + done1 + done2, todo2
+ if not domain:
+ return []
+ if domain[0] != NOT_OPERATOR:
+ return [domain[0]] + distribute_not(domain[1:])
+ if domain[0] == NOT_OPERATOR:
+ done, todo = distribute_negate(domain[1:])
+ return done + distribute_not(todo)
+
+def select_from_where(cr, select_field, from_table, where_field, where_ids, where_operator):
+ # todo: merge into parent query as sub-query
+ res = []
+ if where_ids:
+ if where_operator in ['<','>','>=','<=']:
+ cr.execute('SELECT "%s" FROM "%s" WHERE "%s" %s %%s' % \
+ (select_field, from_table, where_field, where_operator),
+ (where_ids[0],)) # TODO shouldn't this be min/max(where_ids) ?
+ res = [r[0] for r in cr.fetchall()]
+ else: # TODO where_operator is supposed to be 'in'? It is called with child_of...
+ for i in range(0, len(where_ids), cr.IN_MAX):
+ subids = where_ids[i:i+cr.IN_MAX]
+ cr.execute('SELECT "%s" FROM "%s" WHERE "%s" IN %%s' % \
+ (select_field, from_table, where_field), (tuple(subids),))
+ res.extend([r[0] for r in cr.fetchall()])
+ return res
+
+def select_distinct_from_where_not_null(cr, select_field, from_table):
+ cr.execute('SELECT distinct("%s") FROM "%s" where "%s" is not null' % \
+ (select_field, from_table, select_field))
+ return [r[0] for r in cr.fetchall()]
class expression(object):
"""
@@ -100,148 +348,124 @@ class expression(object):
For more info: http://christophe-simonis-at-tiny.blogspot.com/2008/08/new-new-domain-notation.html
"""
- @classmethod
- def _is_operator(cls, element):
- return isinstance(element, (str, unicode)) and element in [AND_OPERATOR, OR_OPERATOR, NOT_OPERATOR]
-
- @classmethod
- def _is_leaf(cls, element, internal=False):
- OPS = ('=', '!=', '<>', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of')
- INTERNAL_OPS = OPS + ('inselect',)
- return (isinstance(element, tuple) or isinstance(element, list)) \
- and len(element) == 3 \
- and (((not internal) and element[1] in OPS) \
- or (internal and element[1] in INTERNAL_OPS))
-
- def __execute_recursive_in(self, cr, s, f, w, ids, op, type):
- # todo: merge into parent query as sub-query
- res = []
- if ids:
- if op in ['<','>','>=','<=']:
- cr.execute('SELECT "%s"' \
- ' FROM "%s"' \
- ' WHERE "%s" %s %%s' % (s, f, w, op), (ids[0],))
- res.extend([r[0] for r in cr.fetchall()])
- else:
- for i in range(0, len(ids), cr.IN_MAX):
- subids = ids[i:i+cr.IN_MAX]
- cr.execute('SELECT "%s"' \
- ' FROM "%s"' \
- ' WHERE "%s" IN %%s' % (s, f, w),(tuple(subids),))
- res.extend([r[0] for r in cr.fetchall()])
- else:
- cr.execute('SELECT distinct("%s")' \
- ' FROM "%s" where "%s" is not null' % (s, f, s)),
- res.extend([r[0] for r in cr.fetchall()])
- return res
-
- def __init__(self, exp):
- # check if the expression is valid
- if not reduce(lambda acc, val: acc and (self._is_operator(val) or self._is_leaf(val)), exp, True):
- raise ValueError('Bad domain expression: %r' % (exp,))
- self.__exp = exp
+ def __init__(self, cr, uid, exp, table, context):
+ self.has_unaccent = openerp.modules.registry.RegistryManager.get(cr.dbname).has_unaccent
self.__field_tables = {} # used to store the table to use for the sql generation. key = index of the leaf
self.__all_tables = set()
self.__joins = []
self.__main_table = None # 'root' table. set by parse()
- self.__DUMMY_LEAF = (1, '=', 1) # a dummy leaf that must not be parsed or sql generated
+ # assign self.__exp with the normalized, parsed domain.
+ self.parse(cr, uid, distribute_not(normalize(exp)), table, context)
+ # TODO used only for osv_memory
@property
def exp(self):
return self.__exp[:]
- def parse(self, cr, uid, table, context):
- """ transform the leafs of the expression """
- if not self.__exp:
- return self
+ def parse(self, cr, uid, exp, table, context):
+ """ transform the leaves of the expression """
+ self.__exp = exp
+ self.__main_table = table
+ self.__all_tables.add(table)
- def _rec_get(ids, table, parent=None, left='id', prefix=''):
- if table._parent_store and (not table.pool._init):
-# TODO: Improve where joins are implemented for many with '.', replace by:
-# doms += ['&',(prefix+'.parent_left','<',o.parent_right),(prefix+'.parent_left','>=',o.parent_left)]
+ def child_of_domain(left, ids, left_model, parent=None, prefix=''):
+ """Returns a domain implementing the child_of operator for [(left,child_of,ids)],
+ either as a range using the parent_left/right tree lookup fields (when available),
+ or as an expanded [(left,in,child_ids)]"""
+ if left_model._parent_store and (not left_model.pool._init):
+ # TODO: Improve where joins are implemented for many with '.', replace by:
+ # doms += ['&',(prefix+'.parent_left','<',o.parent_right),(prefix+'.parent_left','>=',o.parent_left)]
doms = []
- for o in table.browse(cr, uid, ids, context=context):
+ for o in left_model.browse(cr, uid, ids, context=context):
if doms:
doms.insert(0, OR_OPERATOR)
doms += [AND_OPERATOR, ('parent_left', '<', o.parent_right), ('parent_left', '>=', o.parent_left)]
if prefix:
- return [(left, 'in', table.search(cr, uid, doms, context=context))]
+ return [(left, 'in', left_model.search(cr, uid, doms, context=context))]
return doms
else:
- def rg(ids, table, parent):
+ def recursive_children(ids, model, parent_field):
if not ids:
return []
- ids2 = table.search(cr, uid, [(parent, 'in', ids)], context=context)
- return ids + rg(ids2, table, parent)
- return [(left, 'in', rg(ids, table, parent or table._parent_name))]
+ ids2 = model.search(cr, uid, [(parent_field, 'in', ids)], context=context)
+ return ids + recursive_children(ids2, model, parent_field)
+ return [(left, 'in', recursive_children(ids, left_model, parent or left_model._parent_name))]
- def child_of_right_to_ids(value):
- """ Normalize a single id, or a string, or a list of ids to a list of ids.
-
- This function is always used with _rec_get() above, so it should be
- called directly from _rec_get instead of repeatedly before _rec_get.
-
- """
+ def to_ids(value, field_obj):
+ """Normalize a single id or name, or a list of those, into a list of ids"""
+ names = []
if isinstance(value, basestring):
- return [x[0] for x in field_obj.name_search(cr, uid, value, [], 'ilike', context=context, limit=None)]
+ names = [value]
+ if value and isinstance(value, (tuple, list)) and isinstance(value[0], basestring):
+ names = value
+ if names:
+ return flatten([[x[0] for x in field_obj.name_search(cr, uid, n, [], 'ilike', context=context, limit=None)] \
+ for n in names])
elif isinstance(value, (int, long)):
return [value]
- else:
- return list(value)
-
- self.__main_table = table
- self.__all_tables.add(table)
+ return list(value)
i = -1
while i + 1 1:
+ if len(field_path) > 1:
if field._type == 'many2one':
- right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context)
- if right == []:
- self.__exp[i] = ( 'id', '=', 0 )
- else:
- self.__exp[i] = (fargs[0], 'in', right)
+ right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context)
+ self.__exp[i] = (field_path[0], 'in', right)
# Making search easier when there is a left operand as field.o2m or field.m2m
- if field._type in ['many2many','one2many']:
- right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context)
- right1 = table.search(cr, uid, [(fargs[0],'in', right)], context=context)
- if right1 == []:
- self.__exp[i] = ( 'id', '=', 0 )
- else:
- self.__exp[i] = ('id', 'in', right1)
+ if field._type in ['many2many', 'one2many']:
+ right = field_obj.search(cr, uid, [(field_path[1], operator, right)], context=context)
+ right1 = table.search(cr, uid, [(field_path[0], 'in', right)], context=context)
+ self.__exp[i] = ('id', 'in', right1)
- if not isinstance(field,fields.property):
+ if not isinstance(field, fields.property):
continue
if field._properties and not field.store:
@@ -249,16 +473,16 @@ class expression(object):
if not field._fnct_search:
# the function field doesn't provide a search function and doesn't store
# values in the database, so we must ignore it : we generate a dummy leaf
- self.__exp[i] = self.__DUMMY_LEAF
+ self.__exp[i] = TRUE_LEAF
else:
subexp = field.search(cr, uid, table, left, [self.__exp[i]], context=context)
if not subexp:
- self.__exp[i] = self.__DUMMY_LEAF
+ self.__exp[i] = TRUE_LEAF
else:
# we assume that the expression is valid
# we create a dummy leaf for forcing the parsing of the resulting expression
self.__exp[i] = AND_OPERATOR
- self.__exp.insert(i + 1, self.__DUMMY_LEAF)
+ self.__exp.insert(i + 1, TRUE_LEAF)
for j, se in enumerate(subexp):
self.__exp.insert(i + 2 + j, se)
# else, the value of the field is store in the database, so we search on it
@@ -266,11 +490,11 @@ class expression(object):
elif field._type == 'one2many':
# Applying recursivity on field(one2many)
if operator == 'child_of':
- ids2 = child_of_right_to_ids(right)
+ ids2 = to_ids(right, field_obj)
if field._obj != working_table._name:
- dom = _rec_get(ids2, field_obj, left=left, prefix=field._obj)
+ dom = child_of_domain(left, ids2, field_obj, prefix=field._obj)
else:
- dom = _rec_get(ids2, working_table, parent=left)
+ dom = child_of_domain('id', ids2, working_table, parent=left)
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
else:
@@ -282,7 +506,7 @@ class expression(object):
if ids2:
operator = 'in'
else:
- if not isinstance(right,list):
+ if not isinstance(right, list):
ids2 = [right]
else:
ids2 = right
@@ -290,22 +514,16 @@ class expression(object):
if operator in ['like','ilike','in','=']:
#no result found with given search criteria
call_null = False
- self.__exp[i] = ('id','=',0)
- else:
- call_null = True
- operator = 'in' # operator changed because ids are directly related to main object
+ self.__exp[i] = FALSE_LEAF
else:
- call_null = False
- o2m_op = 'in'
- if operator in ['not like','not ilike','not in','<>','!=']:
- o2m_op = 'not in'
- self.__exp[i] = ('id', o2m_op, self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', ids2, operator, field._type))
+ ids2 = select_from_where(cr, field._fields_id, field_obj._table, 'id', ids2, operator)
+ if ids2:
+ call_null = False
+ self.__exp[i] = ('id', 'in', ids2)
if call_null:
- o2m_op = 'not in'
- if operator in ['not like','not ilike','not in','<>','!=']:
- o2m_op = 'in'
- self.__exp[i] = ('id', o2m_op, self.__execute_recursive_in(cr, field._fields_id, field_obj._table, 'id', [], operator, field._type) or [0])
+ o2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'
+ self.__exp[i] = ('id', o2m_op, select_distinct_from_where_not_null(cr, field._fields_id, field_obj._table))
elif field._type == 'many2many':
#FIXME
@@ -313,10 +531,10 @@ class expression(object):
def _rec_convert(ids):
if field_obj == table:
return ids
- return self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, ids, operator, field._type)
+ return select_from_where(cr, field._id1, field._rel, field._id2, ids, operator)
- ids2 = child_of_right_to_ids(right)
- dom = _rec_get(ids2, field_obj)
+ ids2 = to_ids(right, field_obj)
+ dom = child_of_domain('id', ids2, field_obj)
ids2 = field_obj.search(cr, uid, dom, context=context)
self.__exp[i] = ('id', 'in', _rec_convert(ids2))
else:
@@ -335,34 +553,28 @@ class expression(object):
if operator in ['like','ilike','in','=']:
#no result found with given search criteria
call_null_m2m = False
- self.__exp[i] = ('id','=',0)
+ self.__exp[i] = FALSE_LEAF
else:
- call_null_m2m = True
operator = 'in' # operator changed because ids are directly related to main object
else:
call_null_m2m = False
- m2m_op = 'in'
- if operator in ['not like','not ilike','not in','<>','!=']:
- m2m_op = 'not in'
+ m2m_op = 'not in' if operator in NEGATIVE_TERM_OPERATORS else 'in'
+ self.__exp[i] = ('id', m2m_op, select_from_where(cr, field._id1, field._rel, field._id2, res_ids, operator) or [0])
- self.__exp[i] = ('id', m2m_op, self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, res_ids, operator, field._type) or [0])
if call_null_m2m:
- m2m_op = 'not in'
- if operator in ['not like','not ilike','not in','<>','!=']:
- m2m_op = 'in'
- self.__exp[i] = ('id', m2m_op, self.__execute_recursive_in(cr, field._id1, field._rel, field._id2, [], operator, field._type) or [0])
+ m2m_op = 'in' if operator in NEGATIVE_TERM_OPERATORS else 'not in'
+ self.__exp[i] = ('id', m2m_op, select_distinct_from_where_not_null(cr, field._id1, field._rel))
elif field._type == 'many2one':
if operator == 'child_of':
- ids2 = child_of_right_to_ids(right)
- self.__operator = 'in'
+ ids2 = to_ids(right, field_obj)
if field._obj != working_table._name:
- dom = _rec_get(ids2, field_obj, left=left, prefix=field._obj)
+ dom = child_of_domain(left, ids2, field_obj, prefix=field._obj)
else:
- dom = _rec_get(ids2, working_table, parent=left)
+ dom = child_of_domain('id', ids2, working_table, parent=left)
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
else:
- def _get_expression(field_obj,cr, uid, left, right, operator, context=None):
+ def _get_expression(field_obj, cr, uid, left, right, operator, context=None):
if context is None:
context = {}
c = context.copy()
@@ -370,46 +582,35 @@ class expression(object):
#Special treatment to ill-formed domains
operator = ( operator in ['<','>','<=','>='] ) and 'in' or operator
- dict_op = {'not in':'!=','in':'=','=':'in','!=':'not in','<>':'not in'}
- if isinstance(right,tuple):
+ dict_op = {'not in':'!=','in':'=','=':'in','!=':'not in'}
+ if isinstance(right, tuple):
right = list(right)
- if (not isinstance(right,list)) and operator in ['not in','in']:
+ if (not isinstance(right, list)) and operator in ['not in','in']:
operator = dict_op[operator]
- elif isinstance(right,list) and operator in ['<>','!=','=']: #for domain (FIELD,'=',['value1','value2'])
+ elif isinstance(right, list) and operator in ['!=','=']: #for domain (FIELD,'=',['value1','value2'])
operator = dict_op[operator]
- res_ids = field_obj.name_search(cr, uid, right, [], operator, limit=None, context=c)
- if not res_ids:
- return ('id','=',0)
- else:
- right = map(lambda x: x[0], res_ids)
- return (left, 'in', right)
+ res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, limit=None, context=c)]
+ if operator in NEGATIVE_TERM_OPERATORS:
+ res_ids.append(False) # TODO this should not be appended if False was in 'right'
+ return (left, 'in', res_ids)
m2o_str = False
if right:
if isinstance(right, basestring): # and not isinstance(field, fields.related):
m2o_str = True
- elif isinstance(right,(list,tuple)):
+ elif isinstance(right, (list, tuple)):
m2o_str = True
for ele in right:
if not isinstance(ele, basestring):
m2o_str = False
break
+ if m2o_str:
+ self.__exp[i] = _get_expression(field_obj, cr, uid, left, right, operator, context=context)
elif right == []:
- m2o_str = False
- if operator in ('not in', '!=', '<>'):
- # (many2one not in []) should return all records
- self.__exp[i] = self.__DUMMY_LEAF
- else:
- self.__exp[i] = ('id','=',0)
- else:
- new_op = '='
- if operator in ['not like','not ilike','not in','<>','!=']:
- new_op = '!='
- #Is it ok to put 'left' and not 'id' ?
- self.__exp[i] = (left,new_op,False)
+ pass # Handled by __leaf_to_sql().
+ else: # right is False
+ pass # Handled by __leaf_to_sql().
- if m2o_str:
- self.__exp[i] = _get_expression(field_obj,cr, uid, left, right, operator, context=context)
else:
# other field type
# add the time part to datetime field when it's not there:
@@ -425,127 +626,160 @@ class expression(object):
self.__exp[i] = tuple(self.__exp[i])
if field.translate:
- if operator in ('like', 'ilike', 'not like', 'not ilike'):
+ need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike')
+ sql_operator = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
+ if need_wildcard:
right = '%%%s%%' % right
- operator = operator == '=like' and 'like' or operator
-
- query1 = '( SELECT res_id' \
+ subselect = '( SELECT res_id' \
' FROM ir_translation' \
' WHERE name = %s' \
' AND lang = %s' \
' AND type = %s'
instr = ' %s'
#Covering in,not in operators with operands (%s,%s) ,etc.
- if operator in ['in','not in']:
+ if sql_operator in ['in','not in']:
instr = ','.join(['%s'] * len(right))
- query1 += ' AND value ' + operator + ' ' +" (" + instr + ")" \
+ subselect += ' AND value ' + sql_operator + ' ' +" (" + instr + ")" \
') UNION (' \
' SELECT id' \
' FROM "' + working_table._table + '"' \
- ' WHERE "' + left + '" ' + operator + ' ' +" (" + instr + "))"
+ ' WHERE "' + left + '" ' + sql_operator + ' ' +" (" + instr + "))"
else:
- query1 += ' AND value ' + operator + instr + \
+ subselect += ' AND value ' + sql_operator + instr + \
') UNION (' \
' SELECT id' \
' FROM "' + working_table._table + '"' \
- ' WHERE "' + left + '" ' + operator + instr + ")"
+ ' WHERE "' + left + '" ' + sql_operator + instr + ")"
- query2 = [working_table._name + ',' + left,
+ params = [working_table._name + ',' + left,
context.get('lang', False) or 'en_US',
'model',
right,
right,
]
- self.__exp[i] = ('id', 'inselect', (query1, query2))
- return self
+ self.__exp[i] = ('id', 'inselect', (subselect, params))
def __leaf_to_sql(self, leaf, table):
- if leaf == self.__DUMMY_LEAF:
- return ('(1=1)', [])
left, operator, right = leaf
- if operator == 'inselect':
- query = '(%s.%s in (%s))' % (table._table, left, right[0])
- params = right[1]
- elif operator in ['in', 'not in']:
- params = right and right[:] or []
- len_before = len(params)
- for i in range(len_before)[::-1]:
- if params[i] == False:
- del params[i]
+ # final sanity checks - should never fail
+ assert operator in (TERM_OPERATORS + ('inselect',)), \
+ "Invalid operator %r in domain term %r" % (operator, leaf)
+ assert leaf in (TRUE_LEAF, FALSE_LEAF) or left in table._all_columns \
+ or left in MAGIC_COLUMNS, "Invalid field %r in domain term %r" % (left, leaf)
- len_after = len(params)
- check_nulls = len_after != len_before
- query = '(1=0)'
-
- if len_after:
- if left == 'id':
- instr = ','.join(['%s'] * len_after)
- else:
- instr = ','.join([table._columns[left]._symbol_set[0]] * len_after)
- query = '(%s.%s %s (%s))' % (table._table, left, operator, instr)
- else:
- # the case for [field, 'in', []] or [left, 'not in', []]
- if operator == 'in':
- query = '(%s.%s IS NULL)' % (table._table, left)
- else:
- query = '(%s.%s IS NOT NULL)' % (table._table, left)
- if check_nulls:
- query = '(%s OR %s.%s IS NULL)' % (query, table._table, left)
- else:
+ if leaf == TRUE_LEAF:
+ query = 'TRUE'
params = []
- if right == False and (leaf[0] in table._columns) and table._columns[leaf[0]]._type=="boolean" and (operator == '='):
- query = '(%s.%s IS NULL or %s.%s = false )' % (table._table, left,table._table, left)
- elif (((right == False) and (type(right)==bool)) or (right is None)) and (operator == '='):
- query = '%s.%s IS NULL ' % (table._table, left)
- elif right == False and (leaf[0] in table._columns) and table._columns[leaf[0]]._type=="boolean" and (operator in ['<>', '!=']):
- query = '(%s.%s IS NOT NULL and %s.%s != false)' % (table._table, left,table._table, left)
- elif (((right == False) and (type(right)==bool)) or right is None) and (operator in ['<>', '!=']):
- query = '%s.%s IS NOT NULL' % (table._table, left)
- elif (operator == '=?'):
- op = '='
- if (right is False or right is None):
- return ( 'TRUE',[])
- if left in table._columns:
- format = table._columns[left]._symbol_set[0]
- query = '(%s.%s %s %s)' % (table._table, left, op, format)
- params = table._columns[left]._symbol_set[1](right)
- else:
- query = "(%s.%s %s '%%s')" % (table._table, left, op)
- params = right
+ elif leaf == FALSE_LEAF:
+ query = 'FALSE'
+ params = []
- else:
- if left == 'id':
- query = '%s.id %s %%s' % (table._table, operator)
- params = right
- else:
- like = operator in ('like', 'ilike', 'not like', 'not ilike')
+ elif operator == 'inselect':
+ query = '(%s."%s" in (%s))' % (table._table, left, right[0])
+ params = right[1]
- op = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
- if left in table._columns:
- format = like and '%s' or table._columns[left]._symbol_set[0]
- query = '(%s.%s %s %s)' % (table._table, left, op, format)
+ elif operator in ['in', 'not in']:
+ # Two cases: right is a boolean or a list. The boolean case is an
+ # abuse and handled for backward compatibility.
+ if isinstance(right, bool):
+ _logger.warning("The domain term '%s' should use the '=' or '!=' operator." % (leaf,))
+ if operator == 'in':
+ r = 'NOT NULL' if right else 'NULL'
+ else:
+ r = 'NULL' if right else 'NOT NULL'
+ query = '(%s."%s" IS %s)' % (table._table, left, r)
+ params = []
+ elif isinstance(right, (list, tuple)):
+ params = right[:]
+ check_nulls = False
+ for i in range(len(params))[::-1]:
+ if params[i] == False:
+ check_nulls = True
+ del params[i]
+
+ if params:
+ if left == 'id':
+ instr = ','.join(['%s'] * len(params))
else:
- query = "(%s.%s %s '%s')" % (table._table, left, op, right)
+ instr = ','.join([table._columns[left]._symbol_set[0]] * len(params))
+ query = '(%s."%s" %s (%s))' % (table._table, left, operator, instr)
+ else:
+ # The case for (left, 'in', []) or (left, 'not in', []).
+ query = 'FALSE' if operator == 'in' else 'TRUE'
- add_null = False
- if like:
- if isinstance(right, str):
- str_utf8 = right
- elif isinstance(right, unicode):
- str_utf8 = right.encode('utf-8')
- else:
- str_utf8 = str(right)
- params = '%%%s%%' % str_utf8
- add_null = not str_utf8
- elif left in table._columns:
- params = table._columns[left]._symbol_set[1](right)
+ if check_nulls and operator == 'in':
+ query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
+ elif not check_nulls and operator == 'not in':
+ query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
+ elif check_nulls and operator == 'not in':
+ query = '(%s AND %s."%s" IS NOT NULL)' % (query, table._table, left) # needed only for TRUE.
+ else: # Must not happen
+ raise ValueError("Invalid domain term %r" % (leaf,))
- if add_null:
- query = '(%s OR %s IS NULL)' % (query, left)
+ elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '='):
+ query = '(%s."%s" IS NULL or %s."%s" = false )' % (table._table, left, table._table, left)
+ params = []
+
+ elif (right is False or right is None) and (operator == '='):
+ query = '%s."%s" IS NULL ' % (table._table, left)
+ params = []
+
+ elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '!='):
+ query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table._table, left, table._table, left)
+ params = []
+
+ elif (right is False or right is None) and (operator == '!='):
+ query = '%s."%s" IS NOT NULL' % (table._table, left)
+ params = []
+
+ elif (operator == '=?'):
+ if (right is False or right is None):
+ # '=?' is a short-circuit that makes the term TRUE if right is None or False
+ query = 'TRUE'
+ params = []
+ else:
+ # '=?' behaves like '=' in other cases
+ query, params = self.__leaf_to_sql((left, '=', right), table)
+
+ elif left == 'id':
+ query = '%s.id %s %%s' % (table._table, operator)
+ params = right
+
+ else:
+ need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike')
+ sql_operator = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
+
+ if left in table._columns:
+ format = need_wildcard and '%s' or table._columns[left]._symbol_set[0]
+ if self.has_unaccent and sql_operator in ('ilike', 'not ilike'):
+ query = '(unaccent(%s."%s") %s unaccent(%s))' % (table._table, left, sql_operator, format)
+ else:
+ query = '(%s."%s" %s %s)' % (table._table, left, sql_operator, format)
+ elif left in MAGIC_COLUMNS:
+ query = "(%s.\"%s\" %s %%s)" % (table._table, left, sql_operator)
+ params = right
+ else: # Must not happen
+ raise ValueError("Invalid field %r in domain term %r" % (left, leaf))
+
+ add_null = False
+ if need_wildcard:
+ if isinstance(right, str):
+ str_utf8 = right
+ elif isinstance(right, unicode):
+ str_utf8 = right.encode('utf-8')
+ else:
+ str_utf8 = str(right)
+ params = '%%%s%%' % str_utf8
+ add_null = not str_utf8
+ elif left in table._columns:
+ params = table._columns[left]._symbol_set[1](right)
+
+ if add_null:
+ query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
if isinstance(params, basestring):
params = [params]
@@ -555,25 +789,26 @@ class expression(object):
def to_sql(self):
stack = []
params = []
+ # Process the domain from right to left, using a stack, to generate a SQL expression.
for i, e in reverse_enumerate(self.__exp):
- if self._is_leaf(e, internal=True):
+ if is_leaf(e, internal=True):
table = self.__field_tables.get(i, self.__main_table)
q, p = self.__leaf_to_sql(e, table)
params.insert(0, p)
stack.append(q)
+ elif e == NOT_OPERATOR:
+ stack.append('(NOT (%s))' % (stack.pop(),))
else:
- if e == NOT_OPERATOR:
- stack.append('(NOT (%s))' % (stack.pop(),))
- else:
- ops = {AND_OPERATOR: ' AND ', OR_OPERATOR: ' OR '}
- q1 = stack.pop()
- q2 = stack.pop()
- stack.append('(%s %s %s)' % (q1, ops[e], q2,))
+ ops = {AND_OPERATOR: ' AND ', OR_OPERATOR: ' OR '}
+ q1 = stack.pop()
+ q2 = stack.pop()
+ stack.append('(%s %s %s)' % (q1, ops[e], q2,))
- query = ' AND '.join(reversed(stack))
+ assert len(stack) == 1
+ query = stack[0]
joins = ' AND '.join(self.__joins)
if joins:
- query = '(%s) AND (%s)' % (joins, query)
+ query = '(%s) AND %s' % (joins, query)
return (query, flatten(params))
def get_tables(self):
diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py
index 7a8f460f5cb..ccc1d740403 100644
--- a/openerp/osv/fields.py
+++ b/openerp/osv/fields.py
@@ -55,7 +55,7 @@ def _symbol_set(symb):
class _column(object):
""" Base of all fields, a database column
-
+
An instance of this object is a *description* of a database column. It will
not hold any data, but only provide the methods to manipulate data of an
ORM record or even prepare/update the database to hold such a field of data.
@@ -675,7 +675,7 @@ class many2many(_column):
if not cr.fetchone():
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%s,%s)', (id, act[1]))
elif act[0] == 5:
- cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%s', (id,))
+ cr.execute('delete from '+self._rel+' where ' + self._id1 + ' = %s', (id,))
elif act[0] == 6:
d1, d2,tables = obj.pool.get('ir.rule').domain_get(cr, user, obj._name, context=context)
@@ -1295,7 +1295,7 @@ class property(function):
def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None):
prop = obj.pool.get('ir.property')
- # get the default values (for res_id = False) for the property fields
+ # get the default values (for res_id = False) for the property fields
default_val = self._get_defaults(obj, cr, uid, prop_names, context)
# build the dictionary that will be returned
@@ -1417,12 +1417,16 @@ class column_info(object):
:attr parent_column: the name of the column containing the m2o
relationship to the parent model that contains
this column, None for local columns.
+ :attr original_parent: if the column is inherited, name of the original
+ parent model that contains it i.e in case of multilevel
+ inheritence, None for local columns.
"""
- def __init__(self, name, column, parent_model=None, parent_column=None):
+ def __init__(self, name, column, parent_model=None, parent_column=None, original_parent=None):
self.name = name
self.column = column
self.parent_model = parent_model
self.parent_column = parent_column
+ self.original_parent = original_parent
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py
index b87672c012d..37dd1010d2f 100644
--- a/openerp/osv/orm.py
+++ b/openerp/osv/orm.py
@@ -38,7 +38,7 @@
- classicals (varchar, integer, boolean, ...)
- relations (one2many, many2one, many2many)
- functions
-
+
"""
import calendar
@@ -165,7 +165,7 @@ def modifiers_tests():
test_modifiers({}, '{}')
test_modifiers({"invisible": True}, '{"invisible": true}')
test_modifiers({"invisible": False}, '{}')
-
+
def check_object_name(name):
""" Check if the given name is a valid openerp object name.
@@ -212,6 +212,19 @@ def last_day_of_current_month():
def intersect(la, lb):
return filter(lambda x: x in lb, la)
+def fix_import_export_id_paths(fieldname):
+ """
+ Fixes the id fields in import and exports, and splits field paths
+ on '/'.
+
+ :param str fieldname: name of the field to import/export
+ :return: split field name
+ :rtype: list of str
+ """
+ fixed_db_id = re.sub(r'([^/])\.id', r'\1/.id', fieldname)
+ fixed_external_id = re.sub(r'([^/]):id', r'\1/id', fixed_db_id)
+ return fixed_external_id.split('/')
+
class except_orm(Exception):
def __init__(self, name, value):
self.name = name
@@ -252,7 +265,7 @@ class browse_null(object):
#
class browse_record_list(list):
""" Collection of browse objects
-
+
Such an instance will be returned when doing a ``browse([ids..])``
and will be iterable, yielding browse() objects
"""
@@ -267,9 +280,9 @@ class browse_record_list(list):
class browse_record(object):
""" An object that behaves like a row of an object's table.
It has attributes after the columns of the corresponding object.
-
+
Examples::
-
+
uobj = pool.get('res.users')
user_rec = uobj.browse(cr, uid, 104)
name = user_rec.name
@@ -326,9 +339,12 @@ class browse_record(object):
col = self._table._inherit_fields[name][2]
elif hasattr(self._table, str(name)):
attr = getattr(self._table, name)
-
if isinstance(attr, (types.MethodType, types.LambdaType, types.FunctionType)):
- return lambda *args, **argv: attr(self._cr, self._uid, [self._id], *args, **argv)
+ def function_proxy(*args, **kwargs):
+ if 'context' not in kwargs and self._context:
+ kwargs.update(context=self._context)
+ return attr(self._cr, self._uid, [self._id], *args, **kwargs)
+ return function_proxy
else:
return attr
else:
@@ -475,6 +491,16 @@ class browse_record(object):
__repr__ = __str__
+ def refresh(self):
+ """Force refreshing this browse_record's data and all the data of the
+ records that belong to the same cache, by emptying the cache completely,
+ preserving only the record identifiers (for prefetching optimizations).
+ """
+ for model, model_cache in self._cache.iteritems():
+ # only preserve the ids of the records that were in the cache
+ cached_ids = dict([(i, {'id': i}) for i in model_cache.keys()])
+ self._cache[model].clear()
+ self._cache[model].update(cached_ids)
def get_pg_type(f):
"""
@@ -587,22 +613,32 @@ class orm_template(object):
_order = 'id'
_sequence = None
_description = None
+
+ # structure:
+ # { 'parent_model': 'm2o_field', ... }
_inherits = {}
- # Mapping from inherits'd field name to triple (m, r, f)
- # where m is the model from which it is inherits'd,
- # r is the (local) field towards m,
- # and f is the _column object itself.
+
+ # Mapping from inherits'd field name to triple (m, r, f, n) where m is the
+ # model from which it is inherits'd, r is the (local) field towards m, f
+ # is the _column object itself, and n is the original (i.e. top-most)
+ # parent model.
+ # Example:
+ # { 'field_name': ('parent_model', 'm2o_field_to_reach_parent',
+ # field_column_obj, origina_parent_model), ... }
_inherit_fields = {}
+
# Mapping field name/column_info object
# This is similar to _inherit_fields but:
# 1. includes self fields,
# 2. uses column_info instead of a triple.
_all_columns = {}
+
_table = None
_invalids = set()
_log_create = False
CONCURRENCY_CHECK_FIELD = '__last_update'
+
def log(self, cr, uid, id, message, secondary=False, context=None):
if context and context.get('disable_log'):
return True
@@ -770,7 +806,7 @@ class orm_template(object):
'You may need to add a dependency on the parent class\' module.' % (name, parent_name))
nattr = {}
for s in attributes:
- new = copy.copy(getattr(pool.get(parent_name), s))
+ new = copy.copy(getattr(pool.get(parent_name), s, {}))
if s == '_columns':
# Don't _inherit custom fields.
for c in new.keys():
@@ -872,7 +908,7 @@ class orm_template(object):
elif field_type == 'integer':
return 0
elif field_type == 'boolean':
- return False
+ return 'False'
return ''
def selection_field(in_field):
@@ -984,11 +1020,7 @@ class orm_template(object):
cols = self._columns.copy()
for f in self._inherit_fields:
cols.update({f: self._inherit_fields[f][2]})
- def fsplit(fieldname):
- fixed_db_id = re.sub(r'([^/])\.id', r'\1/.id', fieldname)
- fixed_external_id = re.sub(r'([^/]):id', r'\1/id', fixed_db_id)
- return fixed_external_id.split('/')
- fields_to_export = map(fsplit, fields_to_export)
+ fields_to_export = map(fix_import_export_id_paths, fields_to_export)
datas = []
for row in self.browse(cr, uid, ids, context):
datas += self.__export_row(cr, uid, row, fields_to_export, context)
@@ -1024,10 +1056,7 @@ class orm_template(object):
"""
if not context:
context = {}
- def _replace_field(x):
- x = re.sub('([a-z0-9A-Z_])\\.id$', '\\1/.id', x)
- return x.replace(':id','/id').split('/')
- fields = map(_replace_field, fields)
+ fields = map(fix_import_export_id_paths, fields)
logger = netsvc.Logger()
ir_model_data_obj = self.pool.get('ir.model.data')
@@ -1089,7 +1118,7 @@ class orm_template(object):
if line[i] and skip:
return False
continue
-
+
#set the mode for m2o, o2m, m2m : xml_id/id/name
if len(field) == len(prefix)+1:
mode = False
@@ -1102,7 +1131,7 @@ class orm_template(object):
for db_id in line.split(config.get('csv_internal_sep')):
res.append(_get_id(relation, db_id, current_module, mode))
return [(6,0,res)]
-
+
# ID of the record using a XML ID
if field[len(prefix)]=='id':
try:
@@ -1126,9 +1155,9 @@ class orm_template(object):
relation_obj = self.pool.get(relation)
newfd = relation_obj.fields_get( cr, uid, context=context )
pos = position
-
+
res = many_ids(line[i], relation, current_module, mode)
-
+
first = 0
while pos < len(datas):
res2 = process_liness(self, datas, prefix + [field[len(prefix)]], current_module, relation_obj._name, newfd, pos, first)
@@ -1138,15 +1167,15 @@ class orm_template(object):
nbrmax = max(nbrmax, pos)
warning += w2
first += 1
-
+
if data_res_id2:
res.append((4, data_res_id2))
-
+
if (not newrow) or not reduce(lambda x, y: x or y, newrow.values(), 0):
break
res.append( (data_res_id2 and 1 or 0, data_res_id2 or 0, newrow) )
-
+
elif fields_def[field[len(prefix)]]['type']=='many2one':
relation = fields_def[field[len(prefix)]]['relation']
@@ -1175,7 +1204,7 @@ class orm_template(object):
else:
res = line[i]
-
+
row[field[len(prefix)]] = res or False
result = (row, nbrmax, warning, data_res_id, xml_id)
@@ -1189,7 +1218,7 @@ class orm_template(object):
position = 0
while position', 'in', 'not in', '<=', '>=', '<>']:
@@ -2488,8 +2536,28 @@ class orm_memory(orm_template):
# nothing to check in memory...
pass
- def exists(self, cr, uid, id, context=None):
- return id in self.datas
+ def exists(self, cr, uid, ids, context=None):
+ if isinstance(ids, (long,int)):
+ ids = [ids]
+ return [id for id in ids if id in self.datas]
+
+ def check_access_rule(self, cr, uid, ids, operation, context=None):
+ # ir.rules do not currently apply for orm.memory instances,
+ # only the implicit visibility=owner one.
+ for id in ids:
+ self._check_access(uid, id, operation)
+
+# Definition of log access columns, automatically added to models if
+# self._log_access is True
+LOG_ACCESS_COLUMNS = {
+ 'create_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
+ 'create_date': 'TIMESTAMP',
+ 'write_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
+ 'write_date': 'TIMESTAMP'
+}
+# special columns automatically created by the ORM
+MAGIC_COLUMNS = ['id'] + LOG_ACCESS_COLUMNS.keys() + \
+ ['internal.create_uid', 'internal.date_access'] # for osv_memory only
class orm(orm_template):
_sql_constraints = []
@@ -2497,6 +2565,7 @@ class orm(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']
__logger = logging.getLogger('orm')
__schema = logging.getLogger('orm.schema')
+
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False):
"""
Get the list of records in list view grouped by the given ``groupby`` fields
@@ -2617,20 +2686,22 @@ class orm(orm_template):
del d['id']
return data
- def _inherits_join_add(self, parent_model_name, query):
+ def _inherits_join_add(self, current_table, parent_model_name, query):
"""
Add missing table SELECT and JOIN clause to ``query`` for reaching the parent table (no duplicates)
-
+ :param current_table: current model object
:param parent_model_name: name of the parent model for which the clauses should be added
:param query: query object on which the JOIN should be added
"""
- inherits_field = self._inherits[parent_model_name]
+ inherits_field = current_table._inherits[parent_model_name]
parent_model = self.pool.get(parent_model_name)
parent_table_name = parent_model._table
quoted_parent_table_name = '"%s"' % parent_table_name
if quoted_parent_table_name not in query.tables:
query.tables.append(quoted_parent_table_name)
- query.where_clause.append('("%s".%s = %s.id)' % (self._table, inherits_field, parent_table_name))
+ query.where_clause.append('(%s.%s = %s.id)' % (current_table._table, inherits_field, parent_table_name))
+
+
def _inherits_join_calc(self, field, query):
"""
@@ -2645,7 +2716,7 @@ class orm(orm_template):
while field in current_table._inherit_fields and not field in current_table._columns:
parent_model_name = current_table._inherit_fields[field][0]
parent_table = self.pool.get(parent_model_name)
- self._inherits_join_add(parent_model_name, query)
+ self._inherits_join_add(current_table, parent_model_name, query)
current_table = parent_table
return '"%s".%s' % (current_table._table, field)
@@ -2707,7 +2778,7 @@ class orm(orm_template):
pass
if not val_id:
raise except_orm(_('ValidateError'),
- _('Invalid value for reference field "%s" (last part must be a non-zero integer): "%s"') % (field, value))
+ _('Invalid value for reference field "%s.%s" (last part must be a non-zero integer): "%s"') % (self._table, field, value))
val = val_model
else:
val = value
@@ -2717,13 +2788,13 @@ class orm(orm_template):
elif val in dict(self._columns[field].selection(self, cr, uid, context=context)):
return
raise except_orm(_('ValidateError'),
- _('The value "%s" for the field "%s" is not in the selection') % (value, field))
+ _('The value "%s" for the field "%s.%s" is not in the selection') % (value, self._table, field))
def _check_removed_columns(self, cr, log=False):
# iterate on the database columns to drop the NOT NULL constraints
# of fields which were required but have been removed (or will be added by another module)
columns = [c for c in self._columns if not (isinstance(self._columns[c], fields.function) and not self._columns[c].store)]
- columns += ('id', 'write_uid', 'write_date', 'create_uid', 'create_date') # openerp access columns
+ columns += MAGIC_COLUMNS
cr.execute("SELECT a.attname, a.attnotnull"
" FROM pg_class c, pg_attribute a"
" WHERE c.relname=%s"
@@ -2790,7 +2861,7 @@ class orm(orm_template):
column_data = self._select_column_data(cr)
for k, f in self._columns.iteritems():
- if k in ('id', 'write_uid', 'write_date', 'create_uid', 'create_date'):
+ if k in MAGIC_COLUMNS:
continue
# Don't update custom (also called manual) fields
if f.manual and not update_custom_fields:
@@ -2883,7 +2954,7 @@ class orm(orm_template):
cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k))
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (self._table, k, newname))
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
- cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
+ cr.execute("COMMENT ON COLUMN %s.\"%s\" IS %%s" % (self._table, k), (f.string,))
self.__schema.debug("Table '%s': column '%s' has changed type (DB=%s, def=%s), data moved to column %s !",
self._table, k, f_pg_type, f._type, newname)
@@ -2970,7 +3041,7 @@ class orm(orm_template):
if not isinstance(f, fields.function) or f.store:
# add the missing field
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
- cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
+ cr.execute("COMMENT ON COLUMN %s.\"%s\" IS %%s" % (self._table, k), (f.string,))
self.__schema.debug("Table '%s': added column '%s' with definition=%s",
self._table, k, get_pg_type(f)[1])
@@ -3053,7 +3124,7 @@ class orm(orm_template):
def _create_table(self, cr):
cr.execute('CREATE TABLE "%s" (id SERIAL NOT NULL, PRIMARY KEY(id)) WITHOUT OIDS' % (self._table,))
- cr.execute("COMMENT ON TABLE \"%s\" IS '%s'" % (self._table, self._description.replace("'", "''")))
+ cr.execute(("COMMENT ON TABLE \"%s\" IS %%s" % self._table), (self._description,))
self.__schema.debug("Table '%s': created", self._table)
@@ -3092,23 +3163,17 @@ class orm(orm_template):
def _add_log_columns(self, cr):
- logs = {
- 'create_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
- 'create_date': 'TIMESTAMP',
- 'write_uid': 'INTEGER REFERENCES res_users ON DELETE SET NULL',
- 'write_date': 'TIMESTAMP'
- }
- for k in logs:
+ for field, field_def in LOG_ACCESS_COLUMNS.iteritems():
cr.execute("""
SELECT c.relname
FROM pg_class c, pg_attribute a
WHERE c.relname=%s AND a.attname=%s AND c.oid=a.attrelid
- """, (self._table, k))
+ """, (self._table, field))
if not cr.rowcount:
- cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, logs[k]))
+ cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, field, field_def))
cr.commit()
self.__schema.debug("Table '%s': added column '%s' with definition=%s",
- self._table, k, logs[k])
+ self._table, field, field_def)
def _select_column_data(self, cr):
@@ -3263,7 +3328,7 @@ class orm(orm_template):
if f == order:
ok = False
if ok:
- self.pool._store_function[object].append( (self._name, store_field, fnct, fields2, order, length))
+ self.pool._store_function[object].append((self._name, store_field, fnct, tuple(fields2) if fields2 else None, order, length))
self.pool._store_function[object].sort(lambda x, y: cmp(x[4], y[4]))
for (key, _, msg) in self._sql_constraints:
@@ -3336,9 +3401,9 @@ class orm(orm_template):
for table in self._inherits:
other = self.pool.get(table)
for col in other._columns.keys():
- res[col] = (table, self._inherits[table], other._columns[col])
+ res[col] = (table, self._inherits[table], other._columns[col], table)
for col in other._inherit_fields.keys():
- res[col] = (table, self._inherits[table], other._inherit_fields[col][2])
+ res[col] = (table, self._inherits[table], other._inherit_fields[col][2], other._inherit_fields[col][3])
self._inherit_fields = res
self._all_columns = self._get_column_infos()
self._inherits_reload_src()
@@ -3349,8 +3414,8 @@ class orm(orm_template):
inherited field via _inherits) to a ``column_info`` struct
giving detailed columns """
result = {}
- for k, (parent, m2o, col) in self._inherit_fields.iteritems():
- result[k] = fields.column_info(k, col, parent, m2o)
+ for k, (parent, m2o, col, original_parent) in self._inherit_fields.iteritems():
+ result[k] = fields.column_info(k, col, parent, m2o, original_parent)
for k, col in self._columns.iteritems():
result[k] = fields.column_info(k, col)
return result
@@ -3454,7 +3519,7 @@ class orm(orm_template):
res = []
if len(fields_pre):
def convert_field(f):
- f_qual = "%s.%s" % (self._table, f) # need fully-qualified references in case len(tables) > 1
+ f_qual = '%s."%s"' % (self._table, f) # need fully-qualified references in case len(tables) > 1
if f in ('create_date', 'write_date'):
return "date_trunc('second', %s) as %s" % (f_qual, f)
if f == self.CONCURRENCY_CHECK_FIELD:
@@ -4059,7 +4124,7 @@ class orm(orm_template):
upd_todo = []
for v in vals.keys():
if v in self._inherit_fields:
- (table, col, col_detail) = self._inherit_fields[v]
+ (table, col, col_detail, original_parent) = self._inherit_fields[v]
tocreate[table][v] = vals[v]
del vals[v]
else:
@@ -4206,44 +4271,52 @@ class orm(orm_template):
:return: [(priority, model_name, [record_ids,], [function_fields,])]
"""
- # FIXME: rewrite, cleanup, use real variable names
- # e.g.: http://pastie.org/1222060
- result = {}
- fncts = self.pool._store_function.get(self._name, [])
- for fnct in range(len(fncts)):
- if fncts[fnct][3]:
- ok = False
- if not fields:
- ok = True
- for f in (fields or []):
- if f in fncts[fnct][3]:
- ok = True
- break
- if not ok:
- continue
+ if fields is None: fields = []
+ stored_functions = self.pool._store_function.get(self._name, [])
- result.setdefault(fncts[fnct][0], {})
+ # use indexed names for the details of the stored_functions:
+ model_name_, func_field_to_compute_, id_mapping_fnct_, trigger_fields_, priority_ = range(5)
+ # only keep functions that should be triggered for the ``fields``
+ # being written to.
+ to_compute = [f for f in stored_functions \
+ if ((not f[trigger_fields_]) or set(fields).intersection(f[trigger_fields_]))]
+
+ mapping = {}
+ for function in to_compute:
# use admin user for accessing objects having rules defined on store fields
- ids2 = fncts[fnct][2](self, cr, ROOT_USER_ID, ids, context)
- for id in filter(None, ids2):
- result[fncts[fnct][0]].setdefault(id, [])
- result[fncts[fnct][0]][id].append(fnct)
- dict = {}
- for object in result:
- k2 = {}
- for id, fnct in result[object].items():
- k2.setdefault(tuple(fnct), [])
- k2[tuple(fnct)].append(id)
- for fnct, id in k2.items():
- dict.setdefault(fncts[fnct[0]][4], [])
- dict[fncts[fnct[0]][4]].append((fncts[fnct[0]][4], object, id, map(lambda x: fncts[x][1], fnct)))
- result2 = []
- tmp = dict.keys()
- tmp.sort()
- for k in tmp:
- result2 += dict[k]
- return result2
+ target_ids = [id for id in function[id_mapping_fnct_](self, cr, ROOT_USER_ID, ids, context) if id]
+
+ # the compound key must consider the priority and model name
+ key = (function[priority_], function[model_name_])
+ for target_id in target_ids:
+ mapping.setdefault(key, {}).setdefault(target_id,set()).add(tuple(function))
+
+ # Here mapping looks like:
+ # { (10, 'model_a') : { target_id1: [ (function_1_tuple, function_2_tuple) ], ... }
+ # (20, 'model_a') : { target_id2: [ (function_3_tuple, function_4_tuple) ], ... }
+ # (99, 'model_a') : { target_id1: [ (function_5_tuple, function_6_tuple) ], ... }
+ # }
+
+ # Now we need to generate the batch function calls list
+ # call_map =
+ # { (10, 'model_a') : [(10, 'model_a', [record_ids,], [function_fields,])] }
+ call_map = {}
+ for ((priority,model), id_map) in mapping.iteritems():
+ functions_ids_maps = {}
+ # function_ids_maps =
+ # { (function_1_tuple, function_2_tuple) : [target_id1, target_id2, ..] }
+ for id, functions in id_map.iteritems():
+ functions_ids_maps.setdefault(tuple(functions), []).append(id)
+ for functions, ids in functions_ids_maps.iteritems():
+ call_map.setdefault((priority,model),[]).append((priority, model, ids,
+ [f[func_field_to_compute_] for f in functions]))
+ ordered_keys = call_map.keys()
+ ordered_keys.sort()
+ result = []
+ if ordered_keys:
+ result = reduce(operator.add, (call_map[k] for k in ordered_keys))
+ return result
def _store_set_values(self, cr, uid, ids, fields, context):
"""Calls the fields.function's "implementation function" for all ``fields``, on records with ``ids`` (taking care of
@@ -4355,8 +4428,7 @@ class orm(orm_template):
if domain:
import expression
- e = expression.expression(domain)
- e.parse(cr, user, self, context)
+ e = expression.expression(cr, user, domain, self, context)
tables = e.get_tables()
where_clause, where_params = e.to_sql()
where_clause = where_clause and [where_clause] or []
@@ -4381,7 +4453,7 @@ class orm(orm_template):
if parent_model and child_object:
# as inherited rules are being applied, we need to add the missing JOIN
# to reach the parent table (if it was not JOINed yet in the query)
- child_object._inherits_join_add(parent_model, query)
+ child_object._inherits_join_add(child_object, parent_model, query)
query.where_clause += added_clause
query.where_clause_params += added_params
for table in added_tables:
@@ -4470,7 +4542,7 @@ class orm(orm_template):
else:
continue # ignore non-readable or "non-joinable" fields
elif order_field in self._inherit_fields:
- parent_obj = self.pool.get(self._inherit_fields[order_field][0])
+ parent_obj = self.pool.get(self._inherit_fields[order_field][3])
order_column = parent_obj._columns[order_field]
if order_column._classic_read:
inner_clause = self._inherits_join_calc(order_field, query)
@@ -4577,7 +4649,7 @@ class orm(orm_template):
for f in fields:
ftype = fields[f]['type']
- if self._log_access and f in ('create_date', 'create_uid', 'write_date', 'write_uid'):
+ if self._log_access and f in LOG_ACCESS_COLUMNS:
del data[f]
if f in default:
@@ -4614,9 +4686,13 @@ class orm(orm_template):
# force a clean recompute!
for parent_column in ['parent_left', 'parent_right']:
data.pop(parent_column, None)
-
- for v in self._inherits:
- del data[self._inherits[v]]
+ # Remove _inherits field's from data recursively, missing parents will
+ # be created by create() (so that copy() copy everything).
+ def remove_ids(inherits_dict):
+ for parent_table in inherits_dict:
+ del data[inherits_dict[parent_table]]
+ remove_ids(self.pool.get(parent_table)._inherits)
+ remove_ids(self._inherits)
return data
def copy_translations(self, cr, uid, old_id, new_id, context=None):
@@ -4690,9 +4766,9 @@ class orm(orm_template):
def exists(self, cr, uid, ids, context=None):
if type(ids) in (int, long):
ids = [ids]
- query = 'SELECT count(1) FROM "%s"' % (self._table)
+ query = 'SELECT id FROM "%s"' % (self._table)
cr.execute(query + "WHERE ID IN %s", (tuple(ids),))
- return cr.fetchone()[0] == len(ids)
+ return [x[0] for x in cr.fetchall()]
def check_recursion(self, cr, uid, ids, context=None, parent=None):
warnings.warn("You are using deprecated %s.check_recursion(). Please use the '_check_recursion()' instead!" % \
diff --git a/openerp/report/interface.py b/openerp/report/interface.py
index 110110fb1a9..9a97c445671 100644
--- a/openerp/report/interface.py
+++ b/openerp/report/interface.py
@@ -231,6 +231,7 @@ class report_rml(report_int):
def _get_path(self):
ret = []
ret.append(self.tmpl.replace(os.path.sep, '/').rsplit('/',1)[0]) # Same dir as the report rml
+ ret.append('addons')
ret.append(tools.config['root_path'])
return ret
diff --git a/openerp/report/preprocess.py b/openerp/report/preprocess.py
index c84ce66b472..b339e078d81 100644
--- a/openerp/report/preprocess.py
+++ b/openerp/report/preprocess.py
@@ -65,7 +65,10 @@ class report(object):
if type =='html2html':
match = html_parents
if txt.group(3):
- match = [txt.group(3)]
+ group_3 = txt.group(3)
+ if group_3.startswith("'") or group_3.startswith('"'):
+ group_3 = group_3[1:-1]
+ match = [group_3]
n = node
while n.tag not in match:
n = n.getparent()
diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py
index a770a19ec27..0067bf300f2 100644
--- a/openerp/report/render/rml2pdf/trml2pdf.py
+++ b/openerp/report/render/rml2pdf/trml2pdf.py
@@ -447,14 +447,14 @@ class _rml_canvas(object):
self._logger.debug("Image %s used", node.get('name'))
s = StringIO(image_data)
else:
+ newtext = node.text
if self.localcontext:
- res = utils._regex.findall(node.text)
+ res = utils._regex.findall(newtext)
for key in res:
- newtext = eval(key, {}, self.localcontext)
- node.text = newtext or ''
+ newtext = eval(key, {}, self.localcontext) or ''
image_data = None
- if node.text:
- image_data = base64.decodestring(node.text)
+ if newtext:
+ image_data = base64.decodestring(newtext)
if image_data:
s = StringIO(image_data)
else:
diff --git a/openerp/report/report_sxw.py b/openerp/report/report_sxw.py
index 210a54760c4..98de86b01a8 100644
--- a/openerp/report/report_sxw.py
+++ b/openerp/report/report_sxw.py
@@ -68,6 +68,9 @@ rml2sxw = {
'para': 'p',
}
+def get_date_length(date_format=DT_FORMAT):
+ return len((datetime.now()).strftime(date_format))
+
class _format(object):
def set_value(self, cr, uid, name, object, field, lang_obj):
self.object = object
@@ -78,7 +81,7 @@ class _format(object):
class _float_format(float, _format):
def __init__(self,value):
super(_float_format, self).__init__()
- self.val = value
+ self.val = value or 0.0
def __str__(self):
digits = 2
@@ -86,17 +89,17 @@ class _float_format(float, _format):
digits = self._field.digits[1]
if hasattr(self, 'lang_obj'):
return self.lang_obj.format('%.' + str(digits) + 'f', self.name, True)
- return self.val
+ return str(self.val)
class _int_format(int, _format):
def __init__(self,value):
super(_int_format, self).__init__()
- self.val = value and str(value) or str(0)
+ self.val = value or 0
def __str__(self):
if hasattr(self,'lang_obj'):
return self.lang_obj.format('%.d', self.name, True)
- return self.val
+ return str(self.val)
class _date_format(str, _format):
def __init__(self,value):
@@ -106,7 +109,7 @@ class _date_format(str, _format):
def __str__(self):
if self.val:
if getattr(self,'name', None):
- date = datetime.strptime(self.name, DT_FORMAT)
+ date = datetime.strptime(self.name[:get_date_length()], DT_FORMAT)
return date.strftime(str(self.lang_obj.date_format))
return self.val
@@ -264,7 +267,7 @@ class rml_parse(object):
d = obj._field.digits[1] or DEFAULT_DIGITS
return d
- def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False):
+ def formatLang(self, value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False, currency_obj=False):
"""
Assuming 'Account' decimal.precision=3:
formatLang(value) -> digits=2 (default)
@@ -296,13 +299,19 @@ class rml_parse(object):
date_format = date_format + " " + self.lang_dict['time_format']
parse_format = DHM_FORMAT
if not isinstance(value, time.struct_time):
- return time.strftime(date_format, time.strptime(value, parse_format))
+ return time.strftime(date_format, time.strptime(value[:get_date_length(parse_format)], parse_format))
else:
date = datetime(*value.timetuple()[:6])
return date.strftime(date_format)
- return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
+ res = self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary)
+ if currency_obj:
+ if currency_obj.position == 'after':
+ res='%s %s'%(res,currency_obj.symbol)
+ elif currency_obj and currency_obj.position == 'before':
+ res='%s %s'%(currency_obj.symbol, res)
+ return res
def repeatIn(self, lst, name,nodes_parent=False):
ret_lst = []
diff --git a/openerp/sql_db.py b/openerp/sql_db.py
index 79606b9101c..8038c39486d 100644
--- a/openerp/sql_db.py
+++ b/openerp/sql_db.py
@@ -183,6 +183,8 @@ class Cursor(object):
self.__caller = False
self.__closer = False
+ self._default_log_exceptions = True
+
def __del__(self):
if not self.__closed:
# Oops. 'self' has not been closed explicitly.
@@ -199,7 +201,7 @@ class Cursor(object):
self._close(True)
@check
- def execute(self, query, params=None, log_exceptions=True):
+ def execute(self, query, params=None, log_exceptions=None):
if '%d' in query or '%f' in query:
self.__logger.warn(query)
self.__logger.warn("SQL queries cannot contain %d or %f anymore. "
@@ -212,11 +214,11 @@ class Cursor(object):
params = params or None
res = self._obj.execute(query, params)
except psycopg2.ProgrammingError, pe:
- if log_exceptions:
+ if self._default_log_exceptions or log_exceptions:
self.__logger.error("Programming error: %s, in query %s", pe, query)
raise
except Exception:
- if log_exceptions:
+ if self._default_log_exceptions or log_exceptions:
self.__logger.exception("bad query: %s", self._obj.query or query)
raise
diff --git a/openerp/tools/config.py b/openerp/tools/config.py
index f5a45dd67a0..69155f99966 100644
--- a/openerp/tools/config.py
+++ b/openerp/tools/config.py
@@ -254,6 +254,8 @@ class configmanager(object):
"osv_memory tables. This is a decimal value expressed in hours, "
"and the default is 1 hour.",
type="float")
+ group.add_option("--unaccent", dest="unaccent", my_default=False, action="store_true",
+ help="Use the unaccent function provided by the database when available.")
parser.add_option_group(group)
# Copy all optparse options (i.e. MyOption) into self.options.
@@ -356,7 +358,7 @@ class configmanager(object):
'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog',
'list_db', 'xmlrpcs',
'test_file', 'test_disable', 'test_commit', 'test_report_directory',
- 'osv_memory_count_limit', 'osv_memory_age_limit',
+ 'osv_memory_count_limit', 'osv_memory_age_limit', 'unaccent',
]
for arg in keys:
diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py
index b1d23e74630..dbccbe5b217 100644
--- a/openerp/tools/misc.py
+++ b/openerp/tools/misc.py
@@ -45,6 +45,7 @@ from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.Header import Header
from email.Utils import formatdate, COMMASPACE
+from email import Utils
from email import Encoders
from itertools import islice, izip
from lxml import etree
@@ -59,6 +60,7 @@ except ImportError:
html2text = None
import openerp.loglevels as loglevels
+import openerp.pooler as pooler
from config import config
from cache import *
@@ -280,15 +282,7 @@ email_re = re.compile(r"""
""", re.VERBOSE)
res_re = re.compile(r"\[([0-9]+)\]", re.UNICODE)
command_re = re.compile("^Set-([a-z]+) *: *(.+)$", re.I + re.UNICODE)
-reference_re = re.compile("<.*-openobject-(\\d+)@(.*)>", re.UNICODE)
-
-priorities = {
- '1': '1 (Highest)',
- '2': '2 (High)',
- '3': '3 (Normal)',
- '4': '4 (Low)',
- '5': '5 (Lowest)',
- }
+reference_re = re.compile("<.*-open(?:object|erp)-(\\d+).*@(.*)>", re.UNICODE)
def html2plaintext(html, body_id=None, encoding='utf-8'):
""" From an HTML text, convert the HTML to plain text.
@@ -354,150 +348,51 @@ def html2plaintext(html, body_id=None, encoding='utf-8'):
return html
-def generate_tracking_message_id(openobject_id):
+def generate_tracking_message_id(res_id):
"""Returns a string that can be used in the Message-ID RFC822 header field
Used to track the replies related to a given object thanks to the "In-Reply-To"
or "References" fields that Mail User Agents will set.
"""
- return "<%s-openobject-%s@%s>" % (time.time(), openobject_id, socket.gethostname())
-
-def _email_send(smtp_from, smtp_to_list, message, openobject_id=None, ssl=False, debug=False):
- """ Low-level method to send directly a Message through the configured smtp server.
-
- :param smtp_from: RFC-822 envelope FROM (not displayed to recipient)
- :param smtp_to_list: RFC-822 envelope RCPT_TOs (not displayed to recipient)
- :param message: an email.message.Message to send
- :param debug: True if messages should be output to stderr before being sent,
- and smtplib.SMTP put into debug mode.
- :return: True if the mail was delivered successfully to the smtp,
- else False (+ exception logged)
- """
- class WriteToLogger(object):
- def __init__(self):
- self.logger = loglevels.Logger()
-
- def write(self, s):
- self.logger.notifyChannel('email_send', loglevels.LOG_DEBUG, s)
-
- if openobject_id:
- message['Message-Id'] = generate_tracking_message_id(openobject_id)
-
- try:
- smtp_server = config['smtp_server']
-
- if smtp_server.startswith('maildir:/'):
- from mailbox import Maildir
- maildir_path = smtp_server[8:]
- mdir = Maildir(maildir_path,factory=None, create = True)
- mdir.add(message.as_string(True))
- return True
-
- oldstderr = smtplib.stderr
- if not ssl: ssl = config.get('smtp_ssl', False)
- s = smtplib.SMTP()
- try:
- # in case of debug, the messages are printed to stderr.
- if debug:
- smtplib.stderr = WriteToLogger()
-
- s.set_debuglevel(int(bool(debug))) # 0 or 1
- s.connect(smtp_server, config['smtp_port'])
- if ssl:
- s.ehlo()
- s.starttls()
- s.ehlo()
-
- if config['smtp_user'] or config['smtp_password']:
- s.login(config['smtp_user'], config['smtp_password'])
-
- s.sendmail(smtp_from, smtp_to_list, message.as_string())
- finally:
- try:
- s.quit()
- if debug:
- smtplib.stderr = oldstderr
- except Exception:
- # ignored, just a consequence of the previous exception
- pass
-
- except Exception:
- _logger.error('could not deliver email', exc_info=True)
- return False
-
- return True
-
+ return "<%s-openerp-%s@%s>" % (time.time(), res_id, socket.gethostname())
def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=None, reply_to=False,
- attach=None, openobject_id=False, ssl=False, debug=False, subtype='plain', x_headers=None, priority='3'):
+ attachments=None, message_id=None, references=None, openobject_id=False, debug=False, subtype='plain', headers=None,
+ smtp_server=None, smtp_port=None, ssl=False, smtp_user=None, smtp_password=None, cr=None, uid=None):
+ """Low-level function for sending an email (deprecated).
- """Send an email.
-
- @param email_from A string used to fill the `From` header, if falsy,
- config['email_from'] is used instead. Also used for
- the `Reply-To` header if `reply_to` is not provided
-
- @param email_to a sequence of addresses to send the mail to.
+ :deprecate: since OpenERP 6.1, please use ir.mail_server.send_email() instead.
+ :param email_from: A string used to fill the `From` header, if falsy,
+ config['email_from'] is used instead. Also used for
+ the `Reply-To` header if `reply_to` is not provided
+ :param email_to: a sequence of addresses to send the mail to.
"""
- if x_headers is None:
- x_headers = {}
-
+ # If not cr, get cr from current thread database
+ if not cr:
+ db_name = getattr(threading.currentThread(), 'dbname', None)
+ if db_name:
+ cr = pooler.get_db_only(db_name).cursor()
+ else:
+ raise Exception("No database cursor found, please pass one explicitly")
- if not (email_from or config['email_from']):
- raise ValueError("Sending an email requires either providing a sender "
- "address or having configured one")
+ # Send Email
+ try:
+ mail_server_pool = pooler.get_pool(cr.dbname).get('ir.mail_server')
+ res = False
+ # Pack Message into MIME Object
+ email_msg = mail_server_pool.build_email(email_from, email_to, subject, body, email_cc, email_bcc, reply_to,
+ attachments, message_id, references, openobject_id, subtype, headers=headers)
- if not email_from: email_from = config.get('email_from', False)
- email_from = ustr(email_from).encode('utf-8')
-
- if not email_cc: email_cc = []
- if not email_bcc: email_bcc = []
- if not body: body = u''
-
- email_body = ustr(body).encode('utf-8')
- email_text = MIMEText(email_body or '',_subtype=subtype,_charset='utf-8')
-
- msg = MIMEMultipart()
-
- msg['Subject'] = Header(ustr(subject), 'utf-8')
- msg['From'] = email_from
- del msg['Reply-To']
- if reply_to:
- msg['Reply-To'] = reply_to
- else:
- msg['Reply-To'] = msg['From']
- msg['To'] = COMMASPACE.join(email_to)
- if email_cc:
- msg['Cc'] = COMMASPACE.join(email_cc)
- if email_bcc:
- msg['Bcc'] = COMMASPACE.join(email_bcc)
- msg['Date'] = formatdate(localtime=True)
-
- msg['X-Priority'] = priorities.get(priority, '3 (Normal)')
-
- # Add dynamic X Header
- for key, value in x_headers.iteritems():
- msg['%s' % key] = str(value)
-
- if html2text and subtype == 'html':
- text = html2text(email_body.decode('utf-8')).encode('utf-8')
- alternative_part = MIMEMultipart(_subtype="alternative")
- alternative_part.attach(MIMEText(text, _charset='utf-8', _subtype='plain'))
- alternative_part.attach(email_text)
- msg.attach(alternative_part)
- else:
- msg.attach(email_text)
-
- if attach:
- for (fname,fcontent) in attach:
- part = MIMEBase('application', "octet-stream")
- part.set_payload( fcontent )
- Encoders.encode_base64(part)
- part.add_header('Content-Disposition', 'attachment; filename="%s"' % (fname,))
- msg.attach(part)
-
- return _email_send(email_from, flatten([email_to, email_cc, email_bcc]), msg, openobject_id=openobject_id, ssl=ssl, debug=debug)
+ res = mail_server_pool.send_email(cr, uid or 1, email_msg, mail_server_id=None,
+ smtp_server=smtp_server, smtp_port=smtp_port, smtp_user=smtp_user, smtp_password=smtp_password,
+ smtp_encryption=('ssl' if ssl else None), debug=debug)
+ except Exception:
+ _log.exception("tools.email_send failed to deliver email")
+ return False
+ finally:
+ cr.close()
+ return res
#----------------------------------------------------------
# SMS
@@ -1089,10 +984,7 @@ def detect_server_timezone():
return 'UTC'
def get_server_timezone():
- # timezone detection is safe in multithread, so lazy init is ok here
- if (not config['timezone']):
- config['timezone'] = detect_server_timezone()
- return config['timezone']
+ return "UTC"
DEFAULT_SERVER_DATE_FORMAT = "%Y-%m-%d"
diff --git a/openerp/workflow/wkf_service.py b/openerp/workflow/wkf_service.py
index c74a0ad25c1..a8d829aa546 100644
--- a/openerp/workflow/wkf_service.py
+++ b/openerp/workflow/wkf_service.py
@@ -27,6 +27,16 @@ import openerp.netsvc as netsvc
import openerp.pooler as pooler
class workflow_service(netsvc.Service):
+ """
+ Sometimes you might want to fire a signal or re-evaluate the current state
+ of a workflow using the service's API. You can access the workflow services
+ using:
+
+ >>> import netsvc
+ >>> wf_service = netsvc.LocalService("workflow")
+
+ """
+
def __init__(self, name='workflow'):
netsvc.Service.__init__(self, name)
self.wkf_on_create_cache={}
@@ -35,12 +45,31 @@ class workflow_service(netsvc.Service):
self.wkf_on_create_cache[cr.dbname]={}
def trg_write(self, uid, res_type, res_id, cr):
+ """
+ Reevaluates the specified workflow instance. Thus if any condition for
+ a transition have been changed in the backend, then running ``trg_write``
+ will move the workflow over that transition.
+
+ :param res_type: the model name
+ :param res_id: the model instance id the workflow belongs to
+ :param cr: a database cursor
+ """
ident = (uid,res_type,res_id)
cr.execute('select id from wkf_instance where res_id=%s and res_type=%s and state=%s', (res_id or None,res_type or None, 'active'))
for (id,) in cr.fetchall():
instance.update(cr, id, ident)
def trg_trigger(self, uid, res_type, res_id, cr):
+ """
+ Activate a trigger.
+
+ If a workflow instance is waiting for a trigger from another model, then this
+ trigger can be activated if its conditions are met.
+
+ :param res_type: the model name
+ :param res_id: the model instance id the workflow belongs to
+ :param cr: a database cursor
+ """
cr.execute('select instance_id from wkf_triggers where res_id=%s and model=%s', (res_id,res_type))
res = cr.fetchall()
for (instance_id,) in res:
@@ -49,10 +78,24 @@ class workflow_service(netsvc.Service):
instance.update(cr, instance_id, ident)
def trg_delete(self, uid, res_type, res_id, cr):
+ """
+ Delete a workflow instance
+
+ :param res_type: the model name
+ :param res_id: the model instance id the workflow belongs to
+ :param cr: a database cursor
+ """
ident = (uid,res_type,res_id)
instance.delete(cr, ident)
def trg_create(self, uid, res_type, res_id, cr):
+ """
+ Create a new workflow instance
+
+ :param res_type: the model name
+ :param res_id: the model instance id to own the created worfklow instance
+ :param cr: a database cursor
+ """
ident = (uid,res_type,res_id)
self.wkf_on_create_cache.setdefault(cr.dbname, {})
if res_type in self.wkf_on_create_cache[cr.dbname]:
@@ -65,6 +108,14 @@ class workflow_service(netsvc.Service):
instance.create(cr, ident, wkf_id)
def trg_validate(self, uid, res_type, res_id, signal, cr):
+ """
+ Fire a signal on a given workflow instance
+
+ :param res_type: the model name
+ :param res_id: the model instance id the workflow belongs to
+ :signal: the signal name to be fired
+ :param cr: a database cursor
+ """
result = False
ident = (uid,res_type,res_id)
# ids of all active workflow instances for a corresponding resource (id, model_nam)
@@ -74,10 +125,19 @@ class workflow_service(netsvc.Service):
result = result or res2
return result
- # make all workitems which are waiting for a (subflow) workflow instance
- # for the old resource point to the (first active) workflow instance for
- # the new resource
def trg_redirect(self, uid, res_type, res_id, new_rid, cr):
+ """
+ Re-bind a workflow instance to another instance of the same model.
+
+ Make all workitems which are waiting for a (subflow) workflow instance
+ for the old resource point to the (first active) workflow instance for
+ the new resource.
+
+ :param res_type: the model name
+ :param res_id: the model instance id the workflow belongs to
+ :param new_rid: the model instance id to own the worfklow instance
+ :param cr: a database cursor
+ """
# get ids of wkf instances for the old resource (res_id)
#CHECKME: shouldn't we get only active instances?
cr.execute('select id, wkf_id from wkf_instance where res_id=%s and res_type=%s', (res_id, res_type))
diff --git a/setup.nsi b/setup.nsi
index f9c962ae383..0ea37b0f9e6 100644
--- a/setup.nsi
+++ b/setup.nsi
@@ -210,6 +210,7 @@ Section OpenERP_Server SectionOpenERP_Server
WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_user" $TextPostgreSQLUsername
WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_password" $TextPostgreSQLPassword
WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_port" $TextPostgreSQLPort
+ WriteIniStr "$INSTDIR\openerp-server.conf" "options" "pg_path" "$INSTDIR\PostgreSQL\bin"
nsExec::Exec '"$INSTDIR\openerp-server.exe" --stop-after-init --logfile "$INSTDIR\openerp-server.log" -s'
nsExec::Exec '"$INSTDIR\service\OpenERPServerService.exe" -auto -install'
diff --git a/setup.py b/setup.py
index e36662b16cc..58424dbad12 100755
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ if os.name == 'nt':
"pydot", "asyncore","asynchat", "reportlab", "vobject",
"HTMLParser", "select", "mako", "poplib",
"imaplib", "smtplib", "email", "yaml", "DAV",
- "uuid", "commands", "openerp",
+ "uuid", "commands", "openerp", "simplejson", "vatnumber"
],
"excludes" : ["Tkconstants","Tkinter","tcl"],
}
@@ -165,6 +165,7 @@ setup(name = name,
'pywebdav',
'feedparser',
'simplejson >= 2.0',
+ 'vatnumber', # required by base_vat module
],
extras_require = {
'SSL' : ['pyopenssl'],