[MERGE]: Merged lp:~openerp-dev/openobject-addons/trunk-configuration_wizard_improvem...
[odoo/odoo.git] / addons / sale / res_config.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Business Applications
5 #    Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
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 = 'sale.config.settings'
28
29     _columns = {
30         'group_invoice_so_lines': fields.boolean('Based on Sale Orders',
31             implied_group='sale.group_invoice_so_lines',
32             help="To allow your salesman to make invoices for sale order lines using the menu 'Lines to Invoice'."),
33         'group_invoice_deli_orders': fields.boolean('Based on Delivery Orders',
34             implied_group='sale.group_invoice_deli_orders',
35             help="To allow your salesman to make invoices for Delivery Orders using the menu 'Deliveries to Invoice'."),
36         'task_work': fields.boolean('Based on Task Activities',
37             help="""Lets you transfer the entries under tasks defined for Project Management to
38                 the Timesheet line entries for particular date and particular user  with the effect of creating, editing and deleting either ways
39                 and to automatically creates project tasks from procurement lines.
40                 This installs the modules project_timesheet and project_mrp."""),
41         'timesheet': fields.boolean('Based on Timesheet',
42             help = """For modifying account analytic view to show important data to project manager of services companies.
43                 You can also view the report of account analytic summary user-wise as well as month wise.
44                 This installs the module account_analytic_analysis."""),
45         'module_account_analytic_analysis': fields.boolean('Manage Customer Contracts',
46             help = """Allows to define your customer contracts conditions: invoicing
47             method (fixed price, on timesheet, advance invoice), the exact pricing 
48             (650€/day for a developer), the duration (one year support contract). 
49             You will be able to follow the progress of the contract and invoice automatically. 
50             It installs the account_analytic_analysis module."""),
51         'default_order_policy': fields.selection(
52             [('manual', 'Invoice Based on Sales Orders'), ('picking', 'Invoice Based on Deliveries')],
53             'Default Method', default_model='sale.order',
54             help="You can generate invoices based on sales orders or based on shippings."),
55         'module_delivery': fields.boolean('Allow Charging Shipping Costs',
56             help ="""Allows you to add delivery methods in sale orders and delivery orders.
57                 You can define your own carrier and delivery grids for prices.
58                 This installs the module delivery."""),
59         'time_unit': fields.many2one('product.uom', 'Working Time Unit'),
60         'default_picking_policy' : fields.boolean("Configurable Shipping Policy",
61             help = "You will be able to configure, per sale order, if you deliver all  products at once or if you deliver each product when it is available.  This may have an impact on the shipping price."),
62         'group_sale_pricelist':fields.boolean("Pricelist per Customer",
63             implied_group='product.group_sale_pricelist',
64             help="""Allows to manage different prices based on rules per category of customers. 
65                 Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
66         'group_uom':fields.boolean("Allow Different Units of Measure",
67             implied_group='product.group_uom',
68             help="""Allows you to select and maintain different units of measure for products."""),
69         'group_sale_delivery_address': fields.boolean("Allow Different Addresses for Delivery and Invoice",
70             implied_group='sale.group_delivery_invoice_address',
71             help="Allows you to specify different delivery and invoice addresses on a sale order."),
72         'group_discount_per_so_line': fields.boolean("Discount per Line",
73             implied_group='sale.group_discount_per_so_line',
74             help="Allows you to apply some discount per sale order line."),
75         'group_multiple_shops': fields.boolean("Manage Multiple Shops",
76             implied_group='stock.group_locations',
77             help="This allows to configure and use multiple shops."),                
78         'module_sale_layout': fields.boolean("Notes & Subtotals per Line",
79             help="""Allows to format sale order lines using notes, separators, titles and subtotals.
80                 This installs the module sale_layout."""),
81         'module_warning': fields.boolean("Alerts by Products or Customers",
82             help="""Allow to configure warnings on products and trigger them when a user wants to sale a given product or a given customer. 
83             Example: Product: this product is deprecated, do not purchase more than 5.
84             Supplier: don't forget to ask for an express delivery."""),
85         'module_sale_margin': fields.boolean("Display Margins on Sale Orders",
86             help="""This adds the 'Margin' on sales order.
87                 This gives the profitability by calculating the difference between the Unit Price and Cost Price.
88                 This installs the module sale_margin."""),
89         'module_sale_journal': fields.boolean("Allow Batch Invoicing through Journals",
90             help="""Allows you to categorize your sales and deliveries (picking lists) between different journals,
91                 and perform batch operations on journals.
92                 This installs the module sale_journal."""),
93         'module_analytic_user_function': fields.boolean("Assign User Roles per Contract",
94             help="""Allows you to define what is the default function of a specific user on a given account.
95                 This is mostly used when a user encodes his timesheet. The values are retrieved and the fields are auto-filled.
96                 But the possibility to change these values is still available.
97                 This installs the module analytic_user_function."""),
98         'module_analytic_journal_billing_rate': fields.boolean("Billing Rates by Contract",
99             help="""Allows you to define the default invoicing rate for a specific journal on a given account.
100                 This installs the module analytic_journal_billing_rate."""),
101         'module_project_timesheet': fields.boolean("Project Timesheet"),
102         'module_project_mrp': fields.boolean("Project MRP"),
103         'module_project': fields.boolean("Project"),
104         'decimal_precision': fields.integer('Decimal Precision on Price',help="As an example, a decimal precision of 2 will allow prices  like: 9.99 EUR, whereas a decimal precision of 4 will allow prices like:  0.0231 EUR per unit."),
105     }
106     def _check_decimal(self, cr, uid, ids, context=None):
107         for decimal in self.browse(cr, uid, ids, context=context):
108             if decimal.decimal_precision > 20:
109                 return False
110         return True
111     
112     _constraints = [
113         (_check_decimal, 'Digits must be between 0 to 20 ', ['decimal_precision']),
114     ]
115     
116     def default_get(self, cr, uid, fields, context=None):
117         ir_model_data = self.pool.get('ir.model.data')
118         res = super(sale_configuration, self).default_get(cr, uid, fields, context)
119         # task_work, time_unit depend on other fields
120         res['task_work'] = res.get('module_project_mrp') and res.get('module_project_timesheet')
121         if res.get('module_project'):
122             user = self.pool.get('res.users').browse(cr, uid, uid, context)
123             res['time_unit'] = user.company_id.project_time_mode_id.id
124         else:
125             product = ir_model_data.get_object(cr, uid, 'product', 'product_consultant')
126             res['time_unit'] = product.uom_id.id
127         return res
128
129     def get_default_sale_config(self, cr, uid, ids, context=None):
130         ir_values = self.pool.get('ir.values')
131         default_picking_policy = ir_values.get_default(cr, uid, 'sale.order', 'picking_policy')
132         return {
133             'default_picking_policy': default_picking_policy == 'one',
134         }
135
136     def _get_default_time_unit(self, cr, uid, context=None):
137         ids = self.pool.get('product.uom').search(cr, uid, [('name', '=', _('Hour'))], context=context)
138         return ids and ids[0] or False
139
140     _defaults = {
141         'default_order_policy': 'manual',
142         'time_unit': _get_default_time_unit,
143     }
144
145     def get_default_dp(self, cr, uid, fields, context=None):
146         dp = self.pool.get('ir.model.data').get_object(cr, uid, 'product','decimal_sale')
147         return {'decimal_precision': dp.digits}
148
149     def set_default_dp(self, cr, uid, ids, context=None):
150         config = self.browse(cr, uid, ids[0], context)
151         dp = self.pool.get('ir.model.data').get_object(cr, uid, 'product','decimal_sale')
152         dp.write({'digits': config.decimal_precision})
153
154     def set_sale_defaults(self, cr, uid, ids, context=None):
155         ir_values = self.pool.get('ir.values')
156         ir_model_data = self.pool.get('ir.model.data')
157         wizard = self.browse(cr, uid, ids)[0]
158
159         default_picking_policy = 'one' if wizard.default_picking_policy else 'direct'
160         ir_values.set_default(cr, uid, 'sale.order', 'picking_policy', default_picking_policy)
161
162         if wizard.time_unit:
163             product = ir_model_data.get_object(cr, uid, 'product', 'product_consultant')
164             product.write({'uom_id': wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id})
165
166         if wizard.module_project and wizard.time_unit:
167             user = self.pool.get('res.users').browse(cr, uid, uid, context)
168             user.company_id.write({'project_time_mode_id': wizard.time_unit.id})
169
170         return {}
171
172     def onchange_invoice_methods(self, cr, uid, ids, group_invoice_so_lines, group_invoice_deli_orders, context=None):
173         if not group_invoice_deli_orders:
174             return {'value': {'default_order_policy': 'manual'}}
175         if not group_invoice_so_lines:
176             return {'value': {'default_order_policy': 'picking'}}
177         return {}
178
179     def onchange_task_work(self, cr, uid, ids, task_work, context=None):
180         return {'value': {
181             'module_project_timesheet': task_work,
182             'module_project_mrp': task_work,
183         }}
184
185     def onchange_timesheet(self, cr, uid, ids, timesheet, context=None):
186         return {'value': {
187             'timesheet': timesheet,
188             'module_account_analytic_analysis': timesheet,
189         }}
190
191
192
193 class account_config_settings(osv.osv_memory):
194     _inherit = 'account.config.settings'
195     _columns = {
196         'module_sale_analytic_plans': fields.boolean('Several Analytic Accounts on Sales',
197             help="""This allows install module sale_analytic_plans."""),                 
198         'group_analytic_account_for_sales': fields.boolean('Analytic Accounting for Sales',
199             implied_group='sale.group_analytic_accounting',
200             help="Allows you to specify an analytic account on sale orders."),
201     }
202
203 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: