[IMP] improved code for set tax policy
[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 class sale_configuration(osv.osv_memory):
27     _inherit = 'res.config.settings'
28
29     _columns = {
30         'sale_orders': fields.boolean('Based on Sales Orders', 
31                                       help="To allow your salesman to make invoices for sale order lines using 'Lines to Invoice' menu."),
32         'deli_orders': fields.boolean('Based on Delivery Orders',
33                                       help="To allow your salesman to make invoices for Delivery Orders using 'Deliveries to Invoice' menu."),
34         'task_work': fields.boolean('Based on Tasks\' Work',
35                                     help="""Lets you transfer the entries under tasks defined for Project Management to
36                                     the Timesheet line entries for particular date and particular user  with the effect of creating, editing and deleting either ways 
37                                     and to automatically creates project tasks from procurement lines.
38                                     It installs the project_timesheet and project_mrp modules."""),
39         'module_account_analytic_analysis': fields.boolean('Based on Timesheet',
40                                     help = """For modifying account analytic view to show important data to project manager of services companies.
41                                     You can also view the report of account analytic summary user-wise as well as month wise.
42                                     It installs the account_analytic_analysis module."""),
43         'default_order_policy': fields.selection([
44                                 ('manual', 'Invoice Based on Sales Orders'),
45                                 ('picking', 'Invoice Based on Deliveries'),
46                             ], 'Main Method Based On', required=True, default_model='sale.order', 
47                             help="You can generate invoices based on sales orders or based on shippings."),
48         'module_delivery': fields.boolean('Do you charge the delivery?',
49                                    help ="""
50                                    Allows you to add delivery methods in sale orders and delivery orders.
51                                    You can define your own carrier and delivery grids for prices.
52                                    It installs the delivery module.
53                                    """),
54         'time_unit': fields.many2one('product.uom','Working Time Unit'),
55         'default_picking_policy' : fields.boolean("Deliver all products at once?", default_model='sale.order', 
56                                                   help = "You can set picking policy on sale order that will allow you to deliver all products at once."),
57         'group_sale_delivery_address':fields.boolean("Multiple Address", group='base.group_user', implied_group='base.group_sale_delivery_address',
58                                                      help="Allows you to set different delivery address and invoice address. It assigns Multiple Address group to all employees."),
59         'group_sale_disc_per_sale_order_line':fields.boolean("Discounts per sale order lines ", group='base.group_user', implied_group='base.group_sale_disc_per_sale_order_line',
60                                                              help="This allows you to apply discounts per sale order lines, it assigns Discounts per sale order lines group to all employees."),
61         '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."),
62         'module_warning': fields.boolean("Alerts by products or customers",
63                                   help="""To raise user specific warning messages on different products used in Sales Orders, Purchase Orders, Invoices and Deliveries. 
64                                   It installs the warning module."""),
65         'module_sale_margin': fields.boolean("Display Margin For Users",
66                         help="""This adds the 'Margin' on sales order.
67                         This gives the profitability by calculating the difference between the Unit Price and Cost Price.
68                         It installs the sale_margin module."""),
69         'module_sale_journal': fields.boolean("Invoice Journal",
70                         help="""Allows you to categorize your sales and deliveries (picking lists) between different journals.
71                         It installs the sale_journal module."""),
72         'module_analytic_user_function' : fields.boolean("User function by contracts",
73                                     help="""Allows you to define what is the default function of a specific user on a given account.
74                                     This is mostly used when a user encodes his timesheet. The values are retrieved and the fields are auto-filled. 
75                                     But the possibility to change these values is still available.
76                                     It installs analytic_user_function module."""),
77         'module_analytic_journal_billing_rate' : fields.boolean("Billing rates by contracts",
78                                     help="""Allows you to define what is the default invoicing rate for a specific journal on a given account.
79                                     It installs analytic_journal_billing_rate module.
80                                     """),
81         'tax_policy': fields.selection([
82                 ('no_tax', 'No Tax'),
83                 ('global_on_order', 'Global On Order'),
84                 ('on_order_line', 'On Order Lines'),
85             ], 'Taxes', required=True, 
86             help="""
87                 If you want to apply global tax on sale order then select 'Global On Order' it will add 'Global On Order' group to employees.
88                 If you want to apply different taxes for sale order lines then select 'On Order Lines' it will add 'On Order Lines' group to employees.
89             """),
90         'group_sale_taxes_global_on_order':fields.boolean("Global on order", group='base.group_user', implied_group='base.group_sale_taxes_global_on_order'),
91         'group_sale_taxes_on_order_line':fields.boolean("On order line", group='base.group_user', implied_group='base.group_sale_taxes_on_order_line'),
92     }
93
94     def default_get(self, cr, uid, fields, context=None):
95         data_obj = self.pool.get('ir.model.data')
96         res = super(sale_configuration, self).default_get(cr, uid, fields, context)
97         if res.get('module_project_mrp') and res.get('module_project_timesheet'):
98             res.update({'task_work': True})
99         if res.get('module_account_analytic_analysis'):
100             prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id
101             uom_id = self.pool.get('product.product').browse(cr, uid, prod_id).uom_id.id
102             res.update({'time_unit': uom_id})
103         if res.get('group_sale_taxes_global_on_order'):
104             res.update({'tax_policy': 'global_on_order'})
105         elif res.get('group_sale_taxes_on_order_line'):
106             res.update({'tax_policy': 'on_order_line'})
107         else:
108             res.update({'tax_policy': 'no_tax'})
109         return res
110
111     def get_default_sale_configs(self, cr, uid, ids, context=None):
112         ir_values_obj = self.pool.get('ir.values')
113         data_obj = self.pool.get('ir.model.data')
114         menu_obj = self.pool.get('ir.ui.menu')
115         result = {}
116         invoicing_groups_id = [gid.id for gid in data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').groups_id]
117         picking_groups_id = [gid.id for gid in data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').groups_id]
118         group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id
119         for menu in ir_values_obj.get(cr, uid, 'default', False, ['ir.ui.menu']):
120             if menu[1] == 'groups_id' and group_id in menu[2][0]:
121                 if group_id in invoicing_groups_id:
122                     result['sale_orders'] = True
123                 if group_id in picking_groups_id:
124                     result['deli_orders'] = True
125         for res in ir_values_obj.get(cr, uid, 'default', False, ['sale.order']):
126             result[res[1]] = res[2]
127         return result
128
129     _defaults = {
130         'default_order_policy': 'manual',
131         '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,
132         'tax_policy': 'global_on_order',
133     }
134     
135     def _check_default_tax(self, cr, uid, context=None):
136         ir_values_obj = self.pool.get('ir.values')
137         for tax in ir_values_obj.get(cr, uid, 'default', False, ['product.product']):
138             if tax[1] == 'taxes_id':
139                 return tax[2]
140         return False
141
142     def set_sale_defaults(self, cr, uid, ids, context=None):
143         ir_values_obj = self.pool.get('ir.values')
144         data_obj = self.pool.get('ir.model.data')
145         menu_obj = self.pool.get('ir.ui.menu')
146         res = {}
147         wizard = self.browse(cr, uid, ids)[0]
148         group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_salesman').id
149
150         if wizard.sale_orders:
151             menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_invoicing_sales_order_lines').id
152             menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]})
153             ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['ir.ui.menu'], [(4,group_id)])
154
155         if wizard.deli_orders:
156             menu_id = data_obj.get_object(cr, uid, 'sale', 'menu_action_picking_list_to_invoice').id
157             menu_obj.write(cr, uid, menu_id, {'groups_id':[(4,group_id)]})
158             ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['ir.ui.menu'], [(4,group_id)])
159             
160         if wizard.default_picking_policy:
161             ir_values_obj.set(cr, uid, 'default', False, 'picking_policy', ['sale.order'], 'one')
162
163         if wizard.time_unit:
164             prod_id = data_obj.get_object(cr, uid, 'product', 'product_consultant').id
165             product_obj = self.pool.get('product.product')
166             product_obj.write(cr, uid, prod_id, {'uom_id': wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id})
167
168         ir_values_obj.set(cr, uid, 'default', False, 'order_policy', ['sale.order'], wizard.default_order_policy)
169         if wizard.task_work and wizard.time_unit:
170             company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
171             self.pool.get('res.company').write(cr, uid, [company_id], {
172                 'project_time_mode_id': wizard.time_unit.id
173             }, context=context)
174             
175         return res
176
177     def onchange_tax_policy(self, cr, uid, ids, tax_policy, context=None):
178         res = {'value': {}}
179         if ids:
180             self.set_tax_policy(cr, uid, ids, context=context)
181         if tax_policy == 'global_on_order':
182             res['value'].update({'group_sale_taxes_global_on_order': True})
183             res['value'].update({'group_sale_taxes_on_order_line': False})
184
185         elif tax_policy == 'on_order_line':
186             res['value'].update({'group_sale_taxes_on_order_line': True})
187             res['value'].update({'group_sale_taxes_global_on_order': False})
188         else:
189             res['value'].update({'group_sale_taxes_on_order_line': False, 'group_sale_taxes_global_on_order': False})
190         return res
191
192     def set_default_taxes(self, cr, uid, ids, context=None):
193         ir_values_obj = self.pool.get('ir.values')
194         taxes = self._check_default_tax(cr, uid, context=context)
195         if taxes:
196             ir_values_obj.set(cr, uid, 'default', False, 'tax_id', ['sale.order'], taxes[0])
197             ir_values_obj.set(cr, uid, 'default', False, 'tax_id', ['sale.order.line'], taxes)
198             ir_values_obj.set(cr, uid, 'default', False, 'taxes_id', ['product.product'], taxes)
199     
200     #TODO: TO BE REMOVED
201 #    def set_tax_policy(self, cr, uid, ids, context=None):
202 #        data_obj = self.pool.get('ir.model.data')
203 #        users_obj = self.pool.get('res.users')
204 #        groups_obj = self.pool.get('res.groups')
205 #        ir_values_obj = self.pool.get('ir.values')
206 #        dummy,user_group_id = data_obj.get_object_reference(cr, uid, 'base', 'group_user')
207 #        tax_policy = self.browse(cr, uid, ids[0], context=context).tax_policy
208 #        order_group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_taxes_global_on_order').id
209 #        order_line_group_id = data_obj.get_object(cr, uid, 'base', 'group_sale_taxes_on_order_line').id
210 #        group_id = False
211 #        remove_group_id = False
212 #
213 #        if tax_policy == 'global_on_order':
214 #            group_id = order_group_id
215 #            remove_group_id = order_line_group_id
216 #        elif tax_policy == 'on_order_line':
217 #            group_id = order_line_group_id
218 #            remove_group_id = order_group_id
219 #
220 #        if group_id:
221 #            groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(4,group_id)]})
222 #            users_obj.write(cr, uid, [uid], {'groups_id': [(4,group_id)]})
223 #            ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(4,group_id)])
224 #            groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(3,remove_group_id)]})
225 #            users_obj.write(cr, uid, [uid], {'groups_id': [(3,remove_group_id)]})
226 #            ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(3,remove_group_id)])
227 #        else:
228 #            groups = [order_group_id, order_line_group_id]
229 #            for group_id in groups:
230 #                groups_obj.write(cr, uid, [user_group_id], {'implied_ids': [(3,group_id)]})
231 #                users_obj.write(cr, uid, [uid], {'groups_id': [(3,group_id)]})
232 #                ir_values_obj.set(cr, uid, 'default', False, 'groups_id', ['res.users'], [(3,group_id)])
233
234 sale_configuration()
235
236 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: