5e0b5c7f13bc80574864eb2d95a09af199779823
[odoo/odoo.git] / addons / base_setup / base_setup.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21 import pytz
22
23 import pooler
24 import tools
25 from osv import fields, osv
26 from tools.translate import _
27 from lxml import etree
28 from osv import fields, osv
29
30
31 #Application and feature chooser, this could be done by introspecting ir.modules
32
33 class base_setup_installer(osv.osv_memory):
34     _name = 'base.setup.installer'
35     _inherit = 'res.config.installer'
36
37     _install_if = {
38         ('sale','crm'): ['sale_crm'],
39         ('sale','project'): ['project_mrp'],
40     }
41     _columns = {
42         # Generic modules
43         'crm':fields.boolean('Customer Relationship Management',
44             help="Helps you track and manage relations with customers such as"
45                  " leads, requests or issues. Can automatically send "
46                  "reminders, escalate requests or trigger business-specific "
47                  "actions based on standard events."),
48         'sale':fields.boolean('Sales Management',
49             help="Helps you handle your quotations, sale orders and invoicing"
50                  "."),
51         'project':fields.boolean('Project Management',
52             help="Helps you manage your projects and tasks by tracking them, "
53                  "generating plannings, etc..."),
54         'knowledge':fields.boolean('Knowledge Management',
55             help="Lets you install addons geared towards sharing knowledge "
56                  "with and between your employees."),
57         'stock':fields.boolean('Warehouse Management',
58             help="Helps you manage your inventory and main stock operations: delivery orders, receptions, etc."),
59         'mrp':fields.boolean('Manufacturing',
60             help="Helps you manage your manufacturing processes and generate "
61                  "reports on those processes."),
62         'account_voucher':fields.boolean('Invoicing & Payments',
63             help="Allows you to create your invoices and track the payments. It is an easier version of the accounting module for managers who are not accountants."),
64         'account_accountant':fields.boolean('Accounting & Finance',
65             help="Helps you handle your accounting needs, if you are not an accountant, we suggest you to install only the Invoicing "),
66         'purchase':fields.boolean('Purchase Management',
67             help="Helps you manage your purchase-related processes such as "
68                  "requests for quotations, supplier invoices, etc..."),
69         'hr':fields.boolean('Human Resources',
70             help="Helps you manage your human resources by encoding your employees structure, generating work sheets, tracking attendance and more."),
71         'point_of_sale':fields.boolean('Point of Sales',
72             help="Helps you get the most out of your points of sales with "
73                  "fast sale encoding, simplified payment mode encoding, "
74                  "automatic picking lists generation and more."),
75         'marketing':fields.boolean('Marketing',
76             help="Helps you manage your marketing campaigns step by step."),
77         'profile_tools':fields.boolean('Extra Tools',
78             help="Lets you install various interesting but non-essential tools "
79                 "like Survey, Lunch and Ideas box."),
80         'report_designer':fields.boolean('Advanced Reporting',
81             help="Lets you install various tools to simplify and enhance "
82                  "OpenERP's report creation."),
83         # Vertical modules
84         'product_expiry':fields.boolean('Food Industry',
85             help="Installs a preselected set of OpenERP applications "
86                 "which will help you manage your industry."),
87         'association':fields.boolean('Associations',
88             help="Installs a preselected set of OpenERP "
89                  "applications which will help you manage your association "
90                  "more efficiently."),
91         'auction':fields.boolean('Auction Houses',
92             help="Installs a preselected set of OpenERP "
93                  "applications selected to help you manage your auctions "
94                  "as well as the business processes around them."),
95         'account_analytic_plans': fields.boolean('Multiple Analytic Plans',
96             help="Allows invoice lines to impact multiple analytic accounts "
97                  "simultaneously."),
98         'account_payment': fields.boolean('Suppliers Payment Management',
99             help="Streamlines invoice payment and creates hooks to plug "
100                  "automated payment systems in."),
101         'account_followup': fields.boolean('Followups Management',
102             help="Helps you generate reminder letters for unpaid invoices, "
103                  "including multiple levels of reminding and customized "
104                  "per-partner policies."),
105         'account_anglo_saxon': fields.boolean('Anglo-Saxon Accounting',
106             help="This module will support the Anglo-Saxons accounting methodology by "
107                 "changing the accounting logic with stock transactions."),
108         'account_asset': fields.boolean('Assets Management',
109             help="Helps you to manage your assets and their depreciation entries."),
110         # Manufacturing Resource Planning
111         'stock_location': fields.boolean('Advanced Routes',
112             help="Manages product routes and paths within and between "
113                  "locations (e.g. warehouses)."),
114         'mrp_jit': fields.boolean('Just In Time Scheduling',
115             help="Enables Just In Time computation of procurement orders."
116                  "\n\nWhile it's more resource intensive than the default "
117                  "setup, the JIT computer avoids having to wait for the "
118                  "procurement scheduler to run or having to run the "
119                  "procurement scheduler manually."),
120         'mrp_operations': fields.boolean('Manufacturing Operations',
121             help="Enhances production orders with readiness states as well "
122                  "as the start date and end date of execution of the order."),
123         'mrp_subproduct': fields.boolean('MRP Subproducts',
124             help="Enables multiple product output from a single production "
125                  "order: without this, a production order can have only one "
126                  "output product."),
127         'mrp_repair': fields.boolean('Repairs',
128             help="Enables warranty and repair management (and their impact "
129                  "on stocks and invoicing)."),
130         # Knowledge Management
131         'document_ftp':fields.boolean('Shared Repositories (FTP)',
132             help="Provides an FTP access to your OpenERP's "
133                 "Document Management System. It lets you access attachments "
134                 "and virtual documents through a standard FTP client."),
135         'document_webdav':fields.boolean('Shared Repositories (WebDAV)',
136             help="Provides a WebDAV access to your OpenERP's Document "
137                  "Management System. Lets you access attachments and "
138                  "virtual documents through your standard file browser."),
139         'wiki':fields.boolean('Collaborative Content (Wiki)',
140             help="Lets you create wiki pages and page groups in order "
141                  "to keep track of business knowledge and share it with "
142                  "and  between your employees."),
143         # Content templates
144         'wiki_faq':fields.boolean('Template: Internal FAQ',
145             help="Creates a skeleton internal FAQ pre-filled with "
146                  "documentation about OpenERP's Document Management "
147                  "System."),
148         'wiki_quality_manual':fields.boolean('Template: Quality Manual',
149             help="Creates an example skeleton for a standard quality manual."),
150         # Reporting
151         'base_report_designer':fields.boolean('OpenOffice Report Designer',help="Adds wizards to Import/Export .SXW report which "
152                                 "you can modify in OpenOffice.Once you have modified it you can "
153                                 "upload the report using the same wizard."),
154         'base_report_creator':fields.boolean('Query Builder',help="Allows you to create any statistic "
155                                 "reports  on several objects. It's a SQL query builder and browser for end users."),
156         'lunch':fields.boolean('Lunch',help='A simple module to help you to manage Lunch orders.'),
157         'subscription':fields.boolean('Recurring Documents',help='Helps to generate automatically recurring documents.'),
158         'survey':fields.boolean('Survey',help='Allows you to organize surveys.'),
159         'idea':fields.boolean('Ideas Box',help='Promote ideas of the employees, votes and discussion on best ideas.'),
160         'share':fields.boolean('Web Share',help='Allows you to give restricted access to your OpenERP documents to external users, ' \
161             'such as customers, suppliers, or accountants. You can share any OpenERP Menu such as your project tasks, support requests, invoices, etc.'),
162         'pad': fields.boolean('Collaborative Note Pads',
163             help="This module creates a tighter integration between a Pad "
164                  "instance of your choosing and your OpenERP Web Client by "
165                  "letting you easily link pads to OpenERP objects via "
166                  "OpenERP attachments."),
167         'email_template':fields.boolean('Automated E-Mails',
168             help="Helps you to design templates of emails and integrate them in your different processes."),
169         'marketing_campaign':fields.boolean('Marketing Campaigns',
170             help="Helps you to manage marketing campaigns and automate actions and communication steps."),
171         'crm_profiling':fields.boolean('Profiling Tools',
172             help="Helps you to perform segmentation of partners and design segmentation questionnaires"),
173         # Human Resources Management
174         'hr_holidays': fields.boolean('Leaves Management',
175             help="Tracks employee leaves, allocation requests and planning."),
176         'hr_expense': fields.boolean('Expenses',
177             help="Tracks and manages employee expenses, and can "
178                  "automatically re-invoice clients if the expenses are "
179                  "project-related."),
180         'hr_recruitment': fields.boolean('Recruitment Process',
181             help="Helps you manage and streamline your recruitment process."),
182         'hr_timesheet_sheet':fields.boolean('Timesheets',
183             help="Tracks and helps employees encode and validate timesheets "
184                  "and attendances."),
185         'hr_contract': fields.boolean("Employee's Contracts",
186             help="Extends employee profiles to help manage their contracts."),
187         'hr_evaluation': fields.boolean('Periodic Evaluations',
188             help="Lets you create and manage the periodic evaluation and "
189                  "performance review of employees."),
190         'hr_attendance': fields.boolean('Attendances',
191             help="Simplifies the management of employee's attendances."),
192         'hr_payroll': fields.boolean('Payroll',
193             help="Generic Payroll system."),
194         'hr_payroll_account': fields.boolean('Payroll Accounting',
195             help="Generic Payroll system Integrated with Accountings."),
196         # Project Management
197         'project_long_term': fields.boolean(
198         'Long Term Planning',
199             help="Enables long-term projects tracking, including "
200                  "multiple-phase projects and resource allocation handling."),
201         'hr_timesheet_sheet': fields.boolean('Timesheets',
202             help="Tracks and helps employees encode and validate timesheets "
203                  "and attendances."),
204         'project_timesheet': fields.boolean('Bill Time on Tasks',
205             help="Helps generate invoices based on time spent on tasks, if activated on the project."),
206         'account_budget': fields.boolean('Budgets',
207             help="Helps accountants manage analytic and crossover budgets."),
208         'project_issue': fields.boolean('Issues Tracker',
209             help="Automatically synchronizes project tasks and crm cases."),
210         # Methodologies
211         'project_scrum': fields.boolean('Methodology: SCRUM',
212             help="Implements and tracks the concepts and task types defined "
213                  "in the SCRUM methodology."),
214         'project_gtd': fields.boolean('Methodology: Getting Things Done',
215             help="GTD is a methodology to efficiently organise yourself and your tasks. This module fully integrates GTD principle with OpenERP's project management."),
216         'purchase_requisition':fields.boolean('Purchase Requisition',help="Manages your Purchase Requisition and allows you to easily keep track and manage all your purchase orders."),
217         'purchase_analytic_plans': fields.boolean('Purchase Analytic Plans',help="Manages analytic distribution and purchase orders."),
218         'delivery': fields.boolean('Delivery Costs', 
219             help="Allows you to compute delivery costs on your quotations."),
220         'sale_journal': fields.boolean('Invoicing journals',
221             help="Allows you to group and invoice your delivery orders according to different invoicing types: daily, weekly, etc."),
222         'sale_layout': fields.boolean('Sales Orders Print Layout',
223             help="Provides some features to improve the layout of the Sales Order reports."),
224         'sale_margin': fields.boolean('Margins in Sales Orders',
225             help="Gives the margin of profitability by calculating "
226                  "the difference between Unit Price and Cost Price."),
227         'sale_order_dates': fields.boolean('Full Dates on Sales Orders',
228             help="Adds commitment, requested and effective dates on Sales Orders."),
229         'hr_expense':fields.boolean('Resources Management: Expenses Tracking',  help="Tracks and manages employee expenses, and can "
230                  "automatically re-invoice clients if the expenses are "
231                  "project-related."),
232         'event_project':fields.boolean('Event Management: Events', help="Helps you to manage and organize your events."),
233         'project_gtd':fields.boolean('Getting Things Done',
234             help="GTD is a methodology to efficiently organise yourself and your tasks. This module fully integrates GTD principle with OpenERP's project management."),
235         'wiki': fields.boolean('Wiki', help="Lets you create wiki pages and page groups in order "
236                  "to keep track of business knowledge and share it with "
237                  "and  between your employees."),
238         'name': fields.char('Name', size=64),
239         'crm_helpdesk': fields.boolean('Helpdesk', help="Manages a Helpdesk service."),
240         'crm_fundraising': fields.boolean('Fundraising', help="This may help associations in their fundraising process and tracking."),
241         'crm_claim': fields.boolean('Claims', help="Manages the suppliers and customers claims, including your corrective or preventive actions."),
242         'import_sugarcrm': fields.boolean('Import Data from SugarCRM', help="Help you to import and update data from SugarCRM to OpenERP"),
243         'crm_caldav': fields.boolean('Calendar Synchronizing', help="Helps you to synchronize the meetings with other calendar clients and mobiles."),
244         'sale_crm': fields.boolean('Opportunity to Quotation', help="Create a Quotation from an Opportunity."),
245         'fetchmail': fields.boolean('Fetch Emails', help="Allows you to receive E-Mails from POP/IMAP server."),
246         'thunderbird': fields.boolean('Thunderbird Plug-In', help="Allows you to link your e-mail to OpenERP's documents. You can attach it to any existing one in OpenERP or create a new one."),
247         'outlook': fields.boolean('MS-Outlook Plug-In', help="Allows you to link your e-mail to OpenERP's documents. You can attach it to any existing one in OpenERP or create a new one."),
248         'wiki_sale_faq': fields.boolean('Sale FAQ', help="Helps you manage wiki pages for Frequently Asked Questions on Sales Application."),
249         'import_google': fields.boolean('Google Import', help="Imports contacts and events from your google account."),
250     }
251
252     _defaults = {
253         'mrp_jit': lambda self,cr,uid,*a: self.pool.get('res.users').browse(cr, uid, uid).view == 'simple',
254         'document_ftp':True,
255         'marketing_campaign': lambda *a: 1,
256     }
257
258     def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
259         res = super(base_setup_installer, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
260         doc = etree.XML(res['arch'])
261         for module in ['project_gtd','hr_expense']:
262             count = 0
263             for node in doc.xpath("//field[@name='%s']" % (module)):
264                 count = count + 1
265                 if count > 1:
266                     node.set('invisible', '1')
267         res['arch'] = etree.tostring(doc)
268         #Checking sale module is installed or not
269         cr.execute("SELECT * from ir_module_module where state='installed' and name = 'sale'")
270         count = cr.fetchall()
271         if count:
272             doc = etree.XML(res['arch'])
273             nodes = doc.xpath("//field[@name='sale_crm']")
274             for node in nodes:
275                 node.set('invisible', '0')
276                 node.set('modifiers', '{}')
277             res['arch'] = etree.tostring(doc)
278         return res
279
280     def _if_knowledge(self, cr, uid, ids, context=None):
281         if self.pool.get('res.users').browse(cr, uid, uid, context=context)\
282                .view == 'simple':
283             return ['document_ftp']
284         return None
285
286     def _if_misc_tools(self, cr, uid, ids, context=None):
287         return ['profile_tools']
288
289     def onchange_moduleselection(self, cr, uid, ids, *args, **kargs):
290         value = {}
291         # Calculate progress
292         closed, total = self.get_current_progress(cr, uid)
293         progress = round(100. * closed / (total + len(filter(None, args))))
294         value.update({'progress':progress})
295         if progress < 10.:
296             progress = 10.
297         
298         return {'value':value}
299
300
301     def execute(self, cr, uid, ids, context=None):
302         module_pool = self.pool.get('ir.module.module')
303         modules_selected = []
304         datas = self.read(cr, uid, ids, context=context)[0]
305         for mod in datas.keys():
306             if mod in ('id', 'progress'):
307                 continue
308             if datas[mod] == 1:
309                 modules_selected.append(mod)
310
311         module_ids = module_pool.search(cr, uid, [('name', 'in', modules_selected)], context=context)
312         need_install = False
313         for module in module_pool.browse(cr, uid, module_ids, context=context):
314             if module.state == 'uninstalled':
315                 module_pool.state_update(cr, uid, [module.id], 'to install', ['uninstalled'], context)
316                 need_install = True
317                 cr.commit()
318             elif module.state == 'installed':
319                 cr.execute("update ir_actions_todo set state='open' \
320                                     from ir_model_data as data where data.res_id = ir_actions_todo.id \
321                                     and ir_actions_todo.type='special'\
322                                     and data.model = 'ir.actions.todo' and data.module=%s", (module.name, ))
323         if need_install:
324             self.pool = pooler.restart_pool(cr.dbname, update_module=True)[1]
325         return
326
327
328
329 #Migrate data from another application Conf wiz
330
331 class migrade_application_installer_modules(osv.osv_memory):
332     _name = 'migrade.application.installer.modules'
333     _inherit = 'res.config.installer'
334     _columns = {
335         'import_saleforce': fields.boolean('Import Saleforce',
336             help="For Import Saleforce"),
337         'import_sugarcrm': fields.boolean('Import Sugarcrm',
338             help="For Import Sugarcrm"),
339         'sync_google_contact': fields.boolean('Sync Google Contact',
340             help="For Sync Google Contact"),
341         'quickbooks_ippids': fields.boolean('Quickbooks Ippids',
342             help="For Quickbooks Ippids"),
343     }
344
345 class product_installer(osv.osv_memory):
346     _name = 'product.installer'
347     _inherit = 'res.config'
348     _columns = {
349         'customers': fields.selection([('create','Create'), ('import','Import')], 'Customers', size=32, required=True, help="Import or create customers"),
350
351     }
352     _defaults = {
353         'customers': 'create',
354     }
355
356     def execute(self, cr, uid, ids, context=None):
357         if context is None:
358              context = {}
359         data_obj = self.pool.get('ir.model.data')
360         val = self.browse(cr, uid, ids, context=context)[0]
361         if val.customers == 'create':
362             id2 = data_obj._get_id(cr, uid, 'base', 'view_partner_form')
363             if id2:
364                 id2 = data_obj.browse(cr, uid, id2, context=context).res_id
365             return {
366                     'view_type': 'form',
367                     'view_mode': 'form',
368                     'res_model': 'res.partner',
369                     'views': [(id2, 'form')],
370                     'type': 'ir.actions.act_window',
371                     'target': 'current',
372                     'nodestroy':False,
373                 }
374         if val.customers == 'import':
375             return {'type': 'ir.actions.act_window'}
376
377 # Define users preferences for new users (ir.values)
378
379 def _lang_get(self, cr, uid, context=None):
380     obj = self.pool.get('res.lang')
381     ids = obj.search(cr, uid, [('translatable','=',True)])
382     res = obj.read(cr, uid, ids, ['code', 'name'], context=context)
383     res = [(r['code'], r['name']) for r in res]
384     return res
385
386 def _tz_get(self,cr,uid, context=None):
387     return [(x, x) for x in pytz.all_timezones]
388
389 class user_preferences_config(osv.osv_memory):
390     _name = 'user.preferences.config'
391     _inherit = 'res.config'
392     _columns = {
393         'context_tz': fields.selection(_tz_get,  'Timezone', size=64,
394             help="Set default for new user's timezone, used to perform timezone conversions "
395                  "between the server and the client."),
396         'context_lang': fields.selection(_lang_get, 'Language', required=True,
397             help="Sets default language for the all user interface, when UI "
398                 "translations are available. If you want to Add new Language, you can add it from 'Load an Official Translation' wizard  from 'Administration' menu."),
399         'view': fields.selection([('simple','Simplified'),
400                                   ('extended','Extended')],
401                                  'Interface', required=True, help= "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." ),
402         'menu_tips': fields.boolean('Display Tips', help="Check out this box if you want to always display tips on each menu action"),
403                                  
404     }
405     _defaults={
406                'view' : lambda self,cr,uid,*args: self.pool.get('res.users').browse(cr, uid, uid).view or 'simple',
407                'context_lang' : 'en_US',
408                'menu_tips' : True
409     }
410     
411     def default_get(self, cr, uid, fields, context=None):
412         if context is None:
413             context = {}
414         res = super(user_preferences_config, self).default_get(cr, uid, fields, context=context)
415         res_default = self.pool.get('ir.values').get(cr, uid, 'default', False, ['res.users'])
416         for id, field, value in res_default:
417             res.update({field: value})
418         return res
419
420     def execute(self, cr, uid, ids, context=None):
421         user_obj = self.pool.get('res.users')
422         user_ids = user_obj.search(cr, uid, [], context=context)
423         for o in self.browse(cr, uid, ids, context=context):
424             user_obj.write(cr , uid, user_ids ,{'context_tz' : o.context_tz, 'context_lang' : o.context_lang, 'view' : o.view, 'menu_tips' : o.menu_tips}, context=context)
425             ir_values_obj = self.pool.get('ir.values')
426             ir_values_obj.set(cr, uid, 'default', False, 'context_tz', ['res.users'], o.context_tz)
427             ir_values_obj.set(cr, uid, 'default', False, 'context_lang', ['res.users'], o.context_lang)
428             ir_values_obj.set(cr, uid, 'default', False, 'view', ['res.users'], o.view)
429             ir_values_obj.set(cr, uid, 'default', False, 'menu_tips', ['res.users'], o.menu_tips)
430         return {}
431
432 # Specify Your Terminology
433
434 class specify_partner_terminology(osv.osv_memory):
435     _name = 'base.setup.terminology'
436     _inherit = 'res.config'
437     _columns = {
438         'partner': fields.selection([('Customer','Customer'),
439                                   ('Client','Client'),
440                                   ('Member','Member'),
441                                   ('Patient','Patient'),
442                                   ('Partner','Partner'),
443                                   ('Donor','Donor'),
444                                   ('Guest','Guest'),
445                                   ('Tenant','Tenant')
446                                   ],
447                                  'Choose how to call a Customer', required=True ),
448     }
449     _defaults={
450                'partner' :'Partner',
451     }
452
453     def make_translations(self, cr, uid, ids, name, type, src, value, res_id=0, context=None):
454         trans_obj = self.pool.get('ir.translation')
455         user_obj = self.pool.get('res.users')
456         context_lang = user_obj.browse(cr, uid, uid, context=context).context_lang
457         existing_trans_ids = trans_obj.search(cr, uid, [('name','=',name), ('lang','=',context_lang), ('type','=',type), ('src','=',src), ('res_id','=',res_id)])
458         if existing_trans_ids:
459             trans_obj.write(cr, uid, existing_trans_ids, {'value': value}, context=context)
460         else:
461             create_id = trans_obj.create(cr, uid, {'name': name,'lang': context_lang, 'type': type, 'src': src, 'value': value , 'res_id': res_id}, context=context)
462         return {}
463
464     def execute(self, cr, uid, ids, context=None):
465         def _case_insensitive_replace(ref_string, src, value):
466             import re
467             pattern = re.compile(src, re.IGNORECASE)
468             return pattern.sub(_(value), _(ref_string))
469         trans_obj = self.pool.get('ir.translation')
470         fields_obj = self.pool.get('ir.model.fields')
471         menu_obj = self.pool.get('ir.ui.menu')
472         act_window_obj = self.pool.get('ir.actions.act_window')
473         for o in self.browse(cr, uid, ids, context=context):
474             #translate label of field
475             field_ids = fields_obj.search(cr, uid, [('field_description','ilike','Customer')])
476             for f_id in fields_obj.browse(cr ,uid, field_ids, context=context):
477                 field_ref = f_id.model_id.model + ',' + f_id.name
478                 self.make_translations(cr, uid, ids, field_ref, 'field', f_id.field_description, _case_insensitive_replace(f_id.field_description,'Customer',o.partner), context=context)
479             #translate help tooltip of field
480             for obj in self.pool.obj_pool.values():
481                 for field_name, field_rec in obj._columns.items():
482                     if field_rec.help.lower().count('customer'):
483                         field_ref = obj._name + ',' + field_name
484                         self.make_translations(cr, uid, ids, field_ref, 'help', field_rec.help, _case_insensitive_replace(field_rec.help,'Customer',o.partner), context=context)
485             #translate menuitems
486             menu_ids = menu_obj.search(cr,uid, [('name','ilike','Customer')])
487             for m_id in menu_obj.browse(cr, uid, menu_ids, context=context):
488                 menu_name = m_id.name
489                 menu_ref = 'ir.ui.menu' + ',' + 'name'
490                 self.make_translations(cr, uid, ids, menu_ref, 'model', menu_name, _case_insensitive_replace(menu_name,'Customer',o.partner), res_id=m_id.id, context=context)
491             #translate act window name
492             act_window_ids = act_window_obj.search(cr, uid, [('name','ilike','Customer')])
493             for act_id in act_window_obj.browse(cr ,uid, act_window_ids, context=context):
494                 act_ref = 'ir.actions.act_window' + ',' + 'name'
495                 self.make_translations(cr, uid, ids, act_ref, 'model', act_id.name, _case_insensitive_replace(act_id.name,'Customer',o.partner), res_id=act_id.id, context=context)
496             #translate act window tooltips
497             act_window_ids = act_window_obj.search(cr, uid, [('help','ilike','Customer')])
498             for act_id in act_window_obj.browse(cr ,uid, act_window_ids, context=context):
499                 act_ref = 'ir.actions.act_window' + ',' + 'help'
500                 self.make_translations(cr, uid, ids, act_ref, 'model', act_id.help, _case_insensitive_replace(act_id.help,'Customer',o.partner), res_id=act_id.id, context=context)
501         return {}
502
503 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: