[TRY] defer
[odoo/odoo.git] / addons / sale_crm / sale_crm.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 import calendar
23 from datetime import date
24 from dateutil import relativedelta
25
26 from openerp import tools
27 from openerp.osv import osv, fields
28
29 class res_users(osv.Model):
30     _inherit = 'res.users'
31     _columns = {
32         'default_section_id': fields.many2one('crm.case.section', 'Default Sales Team'),
33     }
34
35     def __init__(self, pool, cr):
36         init_res = super(res_users, self).__init__(pool, cr)
37         # duplicate list to avoid modifying the original reference
38         self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
39         self.SELF_WRITEABLE_FIELDS.extend(['default_section_id'])
40         return init_res
41
42 class sale_order(osv.osv):
43     _inherit = 'sale.order'
44     _columns = {
45         'section_id': fields.many2one('crm.case.section', 'Sales Team'),
46         'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Tags', \
47             domain="['|', ('section_id', '=', section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}")
48     }
49
50     def _get_default_section_id(self, cr, uid, context=None):
51         """ Gives default section by checking if present in the context """
52         section_id = self.pool.get('crm.lead')._resolve_section_id_from_context(cr, uid, context=context) or False
53         if not section_id:
54             section_id = self.pool.get('res.users').browse(cr, uid, uid, context).default_section_id.id or False
55         return section_id
56
57     _defaults = {
58         'section_id': lambda s, cr, uid, c: s._get_default_section_id(cr, uid, c),
59     }
60
61     def _prepare_invoice(self, cr, uid, order, lines, context=None):
62         invoice_vals = super(sale_order, self)._prepare_invoice(cr, uid, order, lines, context=context)
63         if order.section_id and order.section_id.id:
64             invoice_vals['section_id'] = order.section_id.id
65         return invoice_vals
66
67
68 class crm_case_section(osv.osv):
69     _inherit = 'crm.case.section'
70
71     def _get_sale_orders_data(self, cr, uid, ids, field_name, arg, context=None):
72         obj = self.pool.get('sale.order')
73         res = dict.fromkeys(ids, False)
74         month_begin = date.today().replace(day=1)
75         date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
76         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
77         for id in ids:
78             res[id] = dict()
79             created_domain = [('section_id', '=', id), ('state', '=', ['draft']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
80             res[id]['monthly_quoted'] = self.__get_bar_values(cr, uid, obj, created_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context)
81             validated_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'sent', 'cancel']), ('date_order', '>=', date_begin), ('date_order', '<=', date_end)]
82             res[id]['monthly_confirmed'] = self.__get_bar_values(cr, uid, obj, validated_domain, ['amount_total', 'date_order'], 'amount_total', 'date_order', context=context)
83         return res
84
85     def _get_invoices_data(self, cr, uid, ids, field_name, arg, context=None):
86         obj = self.pool.get('account.invoice.report')
87         res = dict.fromkeys(ids, False)
88         month_begin = date.today().replace(day=1)
89         date_begin = (month_begin - relativedelta.relativedelta(months=self._period_number - 1)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
90         date_end = month_begin.replace(day=calendar.monthrange(month_begin.year, month_begin.month)[1]).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
91         for id in ids:
92             created_domain = [('section_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)]
93             res[id] = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context)
94         return res
95
96     _columns = {
97         'invoiced_forecast': fields.integer(string='Invoice Forecast',
98             help="Forecast of the invoice revenue for the current month. This is the amount the sales \n"
99                     "team should invoice this month. It is used to compute the progression ratio \n"
100                     " of the current and forecast revenue on the kanban view."),
101         'invoiced_target': fields.integer(string='Invoice Target',
102             help="Target of invoice revenue for the current month. This is the amount the sales \n"
103                     "team estimates to be able to invoice this month."),
104         'monthly_quoted': fields.function(_get_sale_orders_data,
105             type='string', readonly=True, multi='_get_sale_orders_data',
106             string='Rate of created quotation per duration'),
107         'monthly_confirmed': fields.function(_get_sale_orders_data,
108             type='string', readonly=True, multi='_get_sale_orders_data',
109             string='Rate of validate sales orders per duration'),
110         'monthly_invoiced': fields.function(_get_invoices_data,
111             type='string', readonly=True,
112             string='Rate of sent invoices per duration'),
113     }
114
115     def action_forecast(self, cr, uid, id, value, context=None):
116         return self.write(cr, uid, [id], {'invoiced_forecast': round(float(value))}, context=context)
117
118 class sale_crm_lead(osv.Model):
119     _inherit = 'crm.lead'
120
121     def on_change_user(self, cr, uid, ids, user_id, context=None):
122         """ Override of on change user_id on lead/opportunity; when having sale
123             the new logic is :
124             - use user.default_section_id
125             - or fallback on previous behavior """
126         if user_id:
127             user = self.pool.get('res.users').browse(cr, uid, user_id, context=context)
128             if user.default_section_id and user.default_section_id.id:
129                 return {'value': {'section_id': user.default_section_id.id}}
130         return super(sale_crm_lead, self).on_change_user(cr, uid, ids, user_id, context=context)
131
132
133 class account_invoice(osv.osv):
134     _inherit = 'account.invoice'
135     _columns = {
136         'section_id': fields.many2one('crm.case.section', 'Sales Team'),
137     }
138     _defaults = {
139         'section_id': lambda self, cr, uid, c=None: self.pool.get('res.users').browse(cr, uid, uid, c).default_section_id.id or False,
140     }
141
142 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: