[IMP] crm*: update crm modules to new mail module (wip)
[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.email_compose_message.email_model.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 class crm_claim(crm.crm_case, osv.osv):
38     """
39     Crm claim
40     """
41     _name = "crm.claim"
42     _description = "Claim"
43     _order = "priority,date desc"
44     _inherit = ['mail.thread']
45     _columns = {
46         'id': fields.integer('ID', readonly=True),
47         'name': fields.char('Claim Subject', size=128, required=True),
48         'action_next': fields.char('Next Action', size=200),
49         'date_action_next': fields.datetime('Next Action Date'),
50         'description': fields.text('Description'),
51         'resolution': fields.text('Resolution'),
52         'create_date': fields.datetime('Creation Date' , readonly=True),
53         'write_date': fields.datetime('Update Date' , readonly=True),
54         'date_deadline': fields.date('Deadline'),
55         'date_closed': fields.datetime('Closed', readonly=True),
56         'date': fields.datetime('Claim Date'),
57         'ref' : fields.reference('Reference', selection=crm._links_get, size=128),
58         'categ_id': fields.many2one('crm.case.categ', 'Category', \
59                             domain="[('section_id','=',section_id),\
60                             ('object_id.model', '=', 'crm.claim')]"),
61         'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority'),
62         'type_action': fields.selection([('correction','Corrective Action'),('prevention','Preventive Action')], 'Action Type'),
63         'user_id': fields.many2one('res.users', 'Responsible'),
64         'user_fault': fields.char('Trouble Responsible', size=64),
65         'section_id': fields.many2one('crm.case.section', 'Sales Team', \
66                         select=True, help="Sales team to which Case belongs to."\
67                                 "Define Responsible user and Email account for"\
68                                 " mail gateway."),
69         'company_id': fields.many2one('res.company', 'Company'),
70         'partner_id': fields.many2one('res.partner', 'Partner'),
71         'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', \
72                                 # domain="[('partner_id','=',partner_id)]"
73                                  ),
74         '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"),
75         'email_from': fields.char('Email', size=128, help="These people will receive email."),
76         'partner_phone': fields.char('Phone', size=32),
77         'stage_id': fields.many2one ('crm.case.stage', 'Stage', domain="[('type','=','claim')]"),
78         'cause': fields.text('Root Cause'),
79         'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
80                                   help='The state is set to \'Draft\', when a case is created.\
81                                   \nIf the case is in progress the state is set to \'Open\'.\
82                                   \nWhen the case is over, the state is set to \'Done\'.\
83                                   \nIf the case needs to be reviewed then the state is set to \'Pending\'.'),
84         'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
85     }
86
87     def stage_next(self, cr, uid, ids, context=None):
88         stage = super(crm_claim, self).stage_next(cr, uid, ids, context=context)
89         if stage:
90             stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context)
91             self.history(cr, uid, ids, _("Changed Stage to: ") + stage_obj.name)
92         return stage
93
94     def stage_previous(self, cr, uid, ids, context=None):
95         stage = super(crm_claim, self).stage_previous(cr, uid, ids, context=context)
96         if stage:
97             stage_obj = self.pool.get('crm.case.stage').browse(cr, uid, stage, context=context)
98             self.history(cr, uid, ids, _("Changed Stage to: ") + stage_obj.name)
99         return stage
100
101     def _get_stage_id(self, cr, uid, context=None):
102         """Finds type of stage according to object."""
103         if context is None:
104             context = {}
105         type = context and context.get('stage_type', '')
106         stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('type','=',type),('sequence','>=',1)])
107         return stage_ids and stage_ids[0] or False
108
109     _defaults = {
110         'user_id': crm.crm_case._get_default_user,
111         'partner_id': crm.crm_case._get_default_partner,
112         'partner_address_id': crm.crm_case._get_default_partner_address,
113         'email_from':crm.crm_case. _get_default_email,
114         'state': lambda *a: 'draft',
115         'section_id':crm.crm_case. _get_section,
116         'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
117         'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'crm.case', context=c),
118         'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0],
119         #'stage_id': _get_stage_id,
120     }
121
122     def onchange_partner_id(self, cr, uid, ids, part, email=False):
123         """This function returns value of partner address based on partner
124
125            :param part: Partner's id
126            :param email: ignored
127         """
128         if not part:
129             return {'value': {'partner_address_id': False,
130                             'email_from': False,
131                             'partner_phone': False,
132                             'partner_mobile': False
133                             }}
134         addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
135         data = {'partner_address_id': addr['contact']}
136         data.update(self.onchange_partner_address_id(cr, uid, ids, addr['contact'])['value'])
137         return {'value': data}
138
139     def onchange_partner_address_id(self, cr, uid, ids, add, email=False):
140         """This function returns value of partner email based on Partner Address
141
142            :param part: Partner's id
143            :param email: ignored
144         """
145         if not add:
146             return {'value': {'email_from': False}}
147         address = self.pool.get('res.partner.address').browse(cr, uid, add)
148         return {'value': {'email_from': address.email, 'partner_phone': address.phone, 'partner_mobile': address.mobile}}
149
150     def case_open(self, cr, uid, ids, *args):
151         """Opens Claim"""
152         res = super(crm_claim, self).case_open(cr, uid, ids, *args)
153         claims = self.browse(cr, uid, ids)
154
155         for i in xrange(0, len(ids)):
156             if not claims[i].stage_id :
157                 stage_id = self._find_first_stage(cr, uid, 'claim', claims[i].section_id.id or False)
158                 self.write(cr, uid, [ids[i]], {'stage_id' : stage_id})
159
160         return res
161
162     def message_new(self, cr, uid, msg, custom_values=None, context=None):
163         """Automatically called when new email message arrives"""
164         res_id = super(crm_claim,self).message_new(cr, uid, msg,
165                                                    custom_values=custom_values,
166                                                    context=context)
167         mail_thread = self.pool.get('mail.thread')
168         subject = msg.get('subject')
169         body = msg.get('body_text')
170         msg_from = msg.get('from')
171         priority = msg.get('priority')
172         vals = {
173             'name': subject,
174             'email_from': msg_from,
175             'email_cc': msg.get('cc'),
176             'description': body,
177             'user_id': False,
178         }
179         if priority:
180             vals['priority'] = priority
181         res = mail_thread.get_partner(cr, uid, msg.get('from', False))
182         if res:
183             vals.update(res)
184         self.write(cr, uid, [res_id], vals, context=context)
185         return res_id
186
187     def message_update(self, cr, uid, ids, msg, vals={}, default_act='pending', context=None):
188         if isinstance(ids, (str, int, long)):
189             ids = [ids]
190
191         res_id = super(crm_claim,self).message_update(cr, uid, msg, context=context)
192
193         if msg.get('priority') in dict(crm.AVAILABLE_PRIORITIES):
194             vals['priority'] = msg.get('priority')
195
196         maps = {
197             'cost':'planned_cost',
198             'revenue': 'planned_revenue',
199             'probability':'probability'
200         }
201         vls = {}
202         for line in msg['body_text'].split('\n'):
203             line = line.strip()
204             res = tools.misc.command_re.match(line)
205             if res and maps.get(res.group(1).lower()):
206                 key = maps.get(res.group(1).lower())
207                 vls[key] = res.group(2).lower()
208         vals.update(vls)
209
210         # Unfortunately the API is based on lists
211         # but we want to update the state based on the
212         # previous state, so we have to loop:
213         for case in self.browse(cr, uid, ids, context=context):
214             values = dict(vals)
215             if case.state in CRM_CLAIM_PENDING_STATES:
216                 values.update(state=crm.AVAILABLE_STATES[1][0]) #re-open
217             res = self.write(cr, uid, [case.id], values, context=context)
218         return res
219
220 class crm_stage_claim(osv.osv):
221
222     def _get_type_value(self, cr, user, context):
223         list = super(crm_stage_claim, self)._get_type_value(cr, user, context)
224         list.append(('claim','Claim'))
225         return list
226
227     _inherit = "crm.case.stage"
228     _columns = {
229             'type': fields.selection(_get_type_value, 'Type'),
230     }
231
232 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: