[IMP] Improved code. added group on UOM field improved tooltip and changes in groups
[odoo/odoo.git] / addons / sale / res_config.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 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
22 from osv import fields, osv
23 import pooler
24 from tools.translate import _
25
26 MODULE_LIST = [
27                'analytic_user_function', 'analytic_journal_billing_rate', 'import_sugarcrm',
28                'import_google', 'crm_caldav', 'wiki_sale_faq', 'base_contact','sale_layout','warning',
29                'google_map', 'fetchmail_crm', 'plugin_thunderbird', 'plugin_outlook','account_analytic_analysis',
30                'project_timesheet', 'account_analytic_analysis', 'project_mrp', 'delivery',
31                'sale_margin', 'sale_journal'
32 ]
33
34 class sale_configuration(osv.osv_memory):
35     _inherit = 'res.config'
36
37     _columns = {
38         'sale_orders': fields.boolean('Based on Sales Orders',),
39         'deli_orders': fields.boolean('Based on Delivery Orders'),
40         'task_work': fields.boolean('Based on Tasks\' Work',
41                                     help="""
42                                     This allows to you transfer the entries under tasks defined for Project Management to
43                                     the Timesheet line entries for particular date and particular user  with the effect of creating, editing and deleting either ways.
44                                     Automatically creates project tasks from procurement lines.
45                                     It installs the project_timesheet and project_mrp module.
46                                     """),
47         'timesheet': fields.boolean('Based on Timesheet',
48                                     help = """For modifying account analytic view to show important data to project manager of services companies,
49                                     You can also view the report of account analytic summary user-wise as well as month wise
50                                     ,It installs the account_analytic_analysis module."""),
51         'order_policy': fields.selection([
52             ('manual', 'Invoice Based on Sales Orders'),
53             ('picking', 'Invoice Based on Deliveries'),
54         ], 'Main Method Based On', required=True, help="You can generate invoices based on sales orders or based on shippings."),
55         'module_delivery': fields.boolean('Do you charge the delivery?',
56                                    help ="""
57                                    Allows you to add delivery methods in sale orders and picking,
58                                    You can define your own carrier and delivery grids for prices.
59                                    It installs the delivery module.
60                                    """),
61         'time_unit': fields.many2one('product.uom','Working Time Unit'),
62         'picking_policy' : fields.boolean("Deliver all products at once?", help = "You can set picking policy from sale order that will allow you to deliver all products at one."),
63         'group_sale_delivery_address':fields.boolean("Multiple Address",help="This allows you to set different delivery address and picking address.It assigns Multiple Address group to employee."),
64         'group_sale_disc_per_sale_order_line':fields.boolean("Discounts per sale order lines ",help="This allows you to apply discounts per sale order lines. It assigns Discounts per sale order lines group to employee."),
65         'module_sale_layout':fields.boolean("Notes & subtotals per line",help="Allows to format sale order lines using notes, separators, titles and subtotals. It installs the sale_layout module."),
66         'module_warning': fields.boolean("Alerts by products or customers",
67                                   help="""To trigger warnings in OpenERP objects.
68                                   Warning messages can be displayed for objects like sale order, purchase order, picking and invoice. The message is triggered by the form's onchange event.
69                                   It installs the warning module."""),
70         'module_sale_margin': fields.boolean("Display Margin For Users",
71                         help="""This adds the 'Margin' on sales order,
72                         This gives the profitability by calculating the difference between the Unit Price and Cost Price.
73                         .It installs the sale_margin module."""),
74         'module_sale_journal': fields.boolean("Invoice journal?",
75                         help="""This allows you to categorise your sales and deliveries (picking lists) between different journals.
76                         It installs the sale_journal module."""),
77         'module_analytic_user_function' : fields.boolean("User function by contracts",
78                                     help="""This allows you to define what is the default function of a specific user on a given account
79                                     This is mostly used when a user encodes his timesheet: the values are retrieved and the fields are auto-filled. But the possibility to change these values is still available.
80                                     It Installs analytic_user_function module."""),
81         'module_analytic_journal_billing_rate' : fields.boolean("Billing rates by contracts",
82                                     help=""" This allows you to define what is the default invoicing rate for a specific journal on a given account.
83                                     It installs analytic_journal_billing_rate module.
84                                     """),
85         'module_account_analytic_analysis': fields.boolean('Contracts',
86                                     help = """
87                                     For modifying account analytic view to show important data to project manager of services companies,
88                                     You can also view the report of account analytic summary user-wise as well as month wise.
89                                     It installs the account_analytic_analysis module."""),
90     }
91
92     def get_default_applied_groups(self, cr, uid, ids, context=None):
93         applied_groups = {}
94         user_obj = self.pool.get('res.users')
95         dataobj = self.pool.get('ir.model.data')
96
97         groups = []
98         user_group_ids = user_obj.browse(cr, uid, uid, context=context).groups_id
99
100         for group_id in user_group_ids:
101             groups.append(group_id.id)
102
103         for id in groups:
104             key_id = dataobj.search(cr, uid,[('res_id','=',id),('model','=','res.groups')],context=context)
105             key = dataobj.browse(cr, uid, key_id[0], context=context).name
106             applied_groups[key] = True
107
108         return applied_groups
109
110     def get_default_installed_modules(self, cr, uid, ids, context=None):
111         module_obj = self.pool.get('ir.module.module')
112         data_obj = self.pool.get('ir.model.data')
113         module_ids = module_obj.search(cr, uid,
114                            [('name','in',MODULE_LIST),
115                             ('state','in',['to install', 'installed', 'to upgrade'])],
116                            context=context)
117         installed_modules = dict([(mod.name,True) for mod in module_obj.browse(cr, uid, module_ids, context=context)])
118         if installed_modules.get('project_mrp') and installed_modules.get('project_timesheet'):
119             installed_modules['task_work'] = True
120             prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id
121             uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id
122             defaults.update({'time_unit': uom_id})
123         if installed_modules.get('account_analytic_analysis'):
124             installed_modules['timesheet'] = True
125             prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id
126             uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id
127             defaults.update({'time_unit': uom_id})
128         return installed_modules
129
130     def get_default_sale_configs(self, cr, uid, ids, context=None):
131         ir_values_obj = self.pool.get('ir.values')
132         data_obj = self.pool.get('ir.model.data')
133         menu_obj = self.pool.get('ir.ui.menu')
134         result = {}
135         invoicing_groups_id = [gid.id for gid in data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').groups_id]
136         picking_groups_id = [gid.id for gid in data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').groups_id]
137         group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id
138         for menu in ir_values_obj.get(cr, uid, 'default', False, ['ir.ui.menu']):
139             if menu[1] == 'groups_id' and group_id in menu[2][0]:
140                 if group_id in invoicing_groups_id:
141                     result['sale_orders'] = True
142                 if group_id in picking_groups_id:
143                     result['deli_orders'] = True
144         for res in ir_values_obj.get(cr, uid, 'default', False, ['sale.order']):
145             result[res[1]] = res[2]
146         return result
147     
148     def get_default_groups(self, cr, uid, ids, context=None):
149         ir_values_obj = self.pool.get('ir.values')
150         result = {}
151         for res in ir_values_obj.get(cr, uid, 'default', False, ['res.users']):
152             result[res[1]] = res[2]
153         return result
154     
155     def default_get(self, cr, uid, fields_list, context=None):
156         result = super(sale_configuration, self).default_get(
157             cr, uid, fields_list, context=context)
158         for method in dir(self):
159             if method.startswith('get_default_'):
160                 result.update(getattr(self, method)(cr, uid, [], context))
161         return result
162     
163     _defaults = {
164         'order_policy': 'manual',
165         'time_unit': lambda self, cr, uid, c: self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c) and self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=c)[0] or False,
166     }
167
168     def create(self, cr, uid, vals, context=None):
169         ids = super(sale_configuration, self).create(cr, uid, vals, context=context)
170         self.execute(cr, uid, [ids], vals, context=context)
171         return ids
172
173     def write(self, cr, uid, ids, vals, context=None):
174         self.execute(cr, uid, ids, vals, context=context)
175         return super(sale_configuration, self).write(cr, uid, ids, vals, context=context)
176
177     def execute(self, cr, uid, ids, vals, context=None):
178         #TODO: TO BE IMPLEMENTED
179         for method in dir(self):
180             if method.startswith('set_'):
181                 vals['modules'] = MODULE_LIST
182                 getattr(self, method)(cr, uid, ids, vals, context)
183         return True
184
185     def set_modules(self, cr, uid, ids, vals, context=None):
186         module_obj = self.pool.get('ir.module.module')
187         MODULE_LIST = vals.get('modules')
188         if vals.get('task_work'):
189             vals.update({'project_timesheet': True,'project_mrp': True})
190         if vals.get('timesheet'):
191             vals.update({'account_analytic_analysis': True})
192         for k, v in vals.items():
193             if k in MODULE_LIST:
194                 installed = self.get_default_installed_modules(cr, uid, [k], context)
195                 if v == True and not installed.get(k):
196                     module_id = module_obj.search(cr, uid, [('name','=',k)])
197                     module_obj.button_immediate_install(cr, uid, module_id, context)
198                 elif v == False and installed.get(k):
199                     module_id = module_obj.search(cr, uid, [('name','=',k)])
200                     module_obj.button_uninstall(self, cr, uid, module_id, context=None)
201                     module_obj.button_upgrade(self, cr, uid, module_id, context=None)
202
203     def set_sale_defaults(self, cr, uid, ids, vals, context=None):
204         ir_values_obj = self.pool.get('ir.values')
205         data_obj = self.pool.get('ir.model.data')
206         menu_obj = self.pool.get('ir.ui.menu')
207         res = {}
208         wizard = self.browse(cr, uid, ids)[0]
209         group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id
210
211         if wizard.sale_orders:
212             menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').id
213             menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]})
214             ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['ir.ui.menu'], [(4,group_id)])
215
216         if wizard.deli_orders:
217             menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').id
218             menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]})
219             ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['ir.ui.menu'], [(4,group_id)])
220             
221         if wizard.picking_policy:
222             ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], 'one')
223
224         if wizard.time_unit:
225             prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id
226             product_obj = self.pool.get('product.product')
227             product_obj.write(cr, uid, prod_id, {'uom_id': wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id})
228
229         ir_values_obj.set(cr, uid, 'default', False, 'order_policy', ['sale.order'], wizard.order_policy)
230         if wizard.task_work and wizard.time_unit:
231             company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
232             self.pool.get('res.company').write(cr, uid, [company_id], {
233                 'project_time_mode_id': wizard.time_unit.id
234             }, context=context)
235             
236         return res
237
238     def set_groups(self, cr, uid, ids, vals, context=None):
239         data_obj = self.pool.get('ir.model.data')
240         users_obj = self.pool.get('res.users')
241         groups_obj = self.pool.get('res.groups')
242         ir_values_obj = self.pool.get('ir.values')
243         dummy,user_group_id = data_obj.get_object_reference(cr, uid, 'base', 'group_user')
244         for group in vals.keys():
245             if group.startswith('group_'):
246                 dummy,group_id = data_obj.get_object_reference(cr, uid, 'base', group)
247                 if vals[group]:
248                     groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(4,group_id)]})
249                     users_obj.write(cr, uid, [uid], {'groups_id': [(4,group_id)]})
250                     ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(4,group_id)])
251                 else:
252                     groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(3,group_id)]})
253                     users_obj.write(cr, uid, [uid], {'groups_id': [(3,group_id)]})
254                     ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(3,group_id)])
255
256     def onchange_tax_policy(self, cr, uid, ids, tax_policy, tax_value, context=None):
257         res = {'value': {}}
258         if isinstance(tax_value, (int)):
259             self.set_default_taxes(cr, uid, ids, {'tax_value': [tax_value]}, context=context)
260         self.set_tax_policy(cr, uid, ids, {'tax_policy': tax_policy}, context=context)
261         return res
262     
263     def set_default_taxes(self, cr, uid, ids, vals, context=None):
264         ir_values_obj = self.pool.get('ir.values')
265         taxes = self._check_default_tax(cr, uid, context=context)
266         if isinstance(vals.get('tax_value'), list):
267             taxes = vals.get('tax_value')
268         if taxes:
269             ir_values_obj.set(cr, uid, 'default', False, 'tax_id', ['sale.order'], taxes[0])
270             ir_values_obj.set(cr, uid, 'default', False, 'tax_id', ['sale.order.line'], taxes)
271             ir_values_obj.set(cr, uid, 'default', False, 'taxes_id', ['product.product'], taxes)
272
273 sale_configuration()
274
275 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: