[FIX] Fixed date_start and date_stop in period creation. Using the fields.date.contex...
[odoo/odoo.git] / addons / crm_claim / crm_claim.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 from crm import crm
24 import time
25 from crm import wizard
26 import binascii
27 import tools
28 from tools.translate import _
29
30 wizard.mail_compose_message.SUPPORTED_MODELS.append('crm.claim')
31 CRM_CLAIM_PENDING_STATES = (
32     crm.AVAILABLE_STATES[2][0], # Cancelled
33     crm.AVAILABLE_STATES[3][0], # Done
34     crm.AVAILABLE_STATES[4][0], # Pending
35 )
36
37
38 class crm_claim(crm.crm_case, osv.osv):
39     """
40     Crm claim
41     """
42     _name = "crm.claim"
43     _description = "Claim"
44     _order = "priority,date desc"
45     _inherit = ['mail.thread']
46     _columns = {
47         'id': fields.integer('ID', readonly=True),
48         'name': fields.char('Claim Subject', size=128, required=True),
49         'active': fields.boolean('Active'),
50         'action_next': fields.char('Next Action', size=200),
51         'date_action_next': fields.datetime('Next Action Date'),
52         'description': fields.text('Description'),
53         'resolution': fields.text('Resolution'),
54         'create_date': fields.datetime('Creation Date' , readonly=True),
55         'write_date': fields.datetime('Update Date' , readonly=True),
56         'date_deadline': fields.date('Deadline'),
57         'date_closed': fields.datetime('Closed', readonly=True),
58         'date': fields.datetime('Claim Date', select=True),
59         'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
60         'categ_id': fields.many2one('crm.case.categ', 'Category', \
61                             domain="[('section_id','=',section_id),\
62                             ('object_id.model', '=', 'crm.claim')]"),
63         'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
64         'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'),
65         'user_id': fields.many2one('res.users', 'Responsible'),
66         'user_fault': fields.char('Trouble Responsible', size=64),
67         'section_id': fields.many2one('crm.case.section', 'Sales Team', \
68                         select=True, help="Sales team to which Case belongs to."\
69                                 "Define Responsible user and Email account for"\
70                                 " mail gateway."),
71         'company_id': fields.many2one('res.company', 'Company'),
72         'partner_id': fields.many2one('res.partner', 'Partner'),
73         'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
74                                 # domain="[('partner_id','=',partner_id)]"
75                                  ),
76         'email_cc': fields.text('Watchers Emails', size=252, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
77         'email_from': fields.char('Email', size=128, help="These people will receive email."),
78         'partner_phone': fields.char('Phone', size=32),
79         'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('section_ids','=',section_id)]"), 
80         'cause': fields.text('Root Cause'),
81         'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
82                                   help='The state is set to \'Draft\', when a case is created.\
83                                   \nIf the case is in progress the state is set to \'Open\'.\
84                                   \nWhen the case is over, the state is set to \'Done\'.\
85                                   \nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
86         'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
87     }
88
89     _defaults = {
90         'user_id': crm.crm_case._get_default_user,
91         'partner_id': crm.crm_case._get_default_partner,
92         'partner_address_id': crm.crm_case._get_default_partner_address,
93         'email_from':crm.crm_case. _get_default_email,
94         'state': lambda *a: 'draft',
95         'section_id':crm.crm_case. _get_section,
96         'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
97         'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
98         'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
99         'active': lambda *a: 1
100     }
101
102     def onchange_partner_id(self, cr, uid, ids, part, email=False):
103         """This function returns value of partner address based on partner
104            :param part: Partner's id
105            :param email: ignored
106         """
107         if not part:
108             return {'value': {'partner_address_id': False,
109                             'email_from': False,
110                             'partner_phone': False
111                             }}
112         addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
113         data = {'partner_address_id': addr['contact']}
114         data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
115         return {'value': data}
116
117     def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
118         """This function returns value of partner email based on Partner Address
119            :param part: Partner's id
120            :param email: ignored
121         """
122         if not add:
123             return {'value': {'email_from': False}}
124         address = self.pool.get('res.partner.address').browse(cr, uid, add)
125         return {'value': {'email_from': address.email, 'partner_phone': address.phone}}
126
127     def case_open(self, cr, uid, ids, *args):
128         """Opens Claim"""
129         for l in self.browse(cr, uid, ids):
130             # When coming from draft override date and stage otherwise just set state
131             if l.state == 'draft':
132                 message = _("The claim '%s' has been opened.") % l.name
133                 self.log(cr, uid, l.id, message)
134                 stage_id = self.stage_find(cr, uid, l.section_id.id or False, [('sequence','>',0)])
135                 if stage_id:
136                     self.stage_set(cr, uid, [l.id], stage_id)
137         res = super(crm_claim, self).case_open(cr, uid, ids, *args)
138         return res
139     
140     def message_new(self, cr, uid, msg, custom_values=None, context=None):
141         """Automatically called when new email message arrives"""
142         res_id = super(crm_claim,self).message_new(cr, uid, msg, custom_values=custom_values, context=context)
143         subject = msg.get('subject')
144         body = msg.get('body_text')
145         msg_from = msg.get('from')
146         priority = msg.get('priority')
147         vals = {
148             'name': subject,
149             'email_from': msg_from,
150             'email_cc': msg.get('cc'),
151             'description': body,
152             'user_id': False,
153         }
154         if priority:
155             vals['priority'] = priority
156         vals.update(self.message_partner_by_email(cr, uid, msg.get('from', False)))
157         self.write(cr, uid, [res_id], vals, context=context)
158         return res_id
159
160     def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
161         if isinstance(ids, (str, int, long)):
162             ids = [ids]
163
164         res_id = super(crm_claim,self).message_update(cr, uid, ids, msg, context=context)
165
166         if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
167             vals['priority'] = msg.get('priority')
168
169         maps = {
170             'cost':'planned_cost',
171             'revenue': 'planned_revenue',
172             'probability':'probability'
173         }
174         vls = {}
175         for line in msg['body_text'].split('\n'):
176             line = line.strip()
177             res = tools.misc.command_re.match(line)
178             if res and maps.get(res.group(1).lower()):
179                 key = maps.get(res.group(1).lower())
180                 vls[key] = res.group(2).lower()
181         vals.update(vls)
182
183         # Unfortunately the API is based on lists
184         # but we want to update the state based on the
185         # previous state, so we have to loop:
186         for case in self.browse(cr, uid, ids, context=context):
187             values = dict(vals)
188             if case.state in CRM_CLAIM_PENDING_STATES:
189                 values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
190             res = self.write(cr, uid, [case.id], values, context=context)
191         return res
192
193 class res_partner(osv.osv):
194     _inherit = 'res.partner'
195     _columns = {
196         'claims_ids': fields.one2many('crm.claim', 'partner_id', 'Claims'),
197     }
198
199 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: