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