[IMP] wip
[odoo/odoo.git] / bin / addons / base / publisher_warranty / publisher_warranty.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #    
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 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 Module to handle publisher warranty contracts as well as notifications from
23 OpenERP.
24 """
25
26 from osv import osv, fields
27 import logging
28 from tools.translate import _
29 import urllib
30 from tools.safe_eval import safe_eval
31 import pooler
32 from tools.config import config
33 import release
34 import datetime
35 from tools import misc
36
37 _logger = logging.getLogger(__name__)
38
39 """
40 Time interval that will be used to determine up to which date we will
41 check the logs to see if a message we just received was already logged.
42 @type: datetime.timedelta
43 """
44 _PREVIOUS_LOG_CHECK = datetime.timedelta(days=365)
45
46 class publisher_warranty_contract(osv.osv):
47     """
48     Osv representing a publisher warranty contract.
49     """
50     _name = "publisher_warranty.contract"
51
52     def _get_valid_contracts(self, cr, uid):
53         """
54         Return the list of the valid contracts encoded in the system.
55         
56         @return: A list of contracts
57         @rtype: list of publisher_warranty.contract browse records
58         """
59         return [contract for contract in self.browse(cr, uid, self.search(cr, uid, []))
60                 if contract.state == 'valid']
61     
62     def status(self, cr, uid):
63         """ Method called by the client to check availability of publisher warranty contract. """
64         
65         contracts = self._get_valid_contracts(cr, uid)
66         return {
67             'status': "full" if contracts else "none" ,
68             'uncovered_modules': list(),
69         }
70     
71     def send(self, cr, uid, tb, explanations, remarks=None):
72         """ Method called by the client to send a problem to the publisher warranty server. """
73         
74         if not remarks:
75             remarks = ""
76
77         valid_contracts = self._get_valid_contracts(cr, uid)
78         valid_contract = valid_contracts[0]
79         
80         try:
81             origin = 'client'
82             dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
83             db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
84             
85             msg = {'contract_name': valid_contract.name,
86                 'tb': tb,
87                 'explanations': explanations,
88                 'remarks': remarks,
89                 'origin': origin,
90                 'dbname': cr.dbname,
91                 'dbuuid': dbuuid,
92                 'db_create_date': db_create_date}
93             
94             uo = urllib.urlopen(config.get("publisher_warranty_url"),
95                                     urllib.urlencode({'arg0': msg, "action": "send",}))
96             try:
97                 submit_result = uo.read()
98             finally:
99                 uo.close()
100             
101             result = safe_eval(submit_result)
102             
103             crm_case_id = result
104             
105             if not crm_case_id:
106                 return False
107             
108         except osv.except_osv:
109             raise
110         except:
111             _logger.warning("Error sending problem report", exc_info=1)
112             raise osv.except_osv("Connection error", "An error occured during the connection " +
113                                  "with the publisher warranty server.")
114         
115         return True
116     
117     def check_validity(self, cr, uid, ids, context={}):
118         """
119         Check the validity of a publisher warranty contract. This method just call get_logs() but checks
120         some more things, so it can be called from a user interface.
121         """
122         contract_id = ids[0]
123         contract = self.browse(cr, uid, contract_id)
124         state = contract.state
125         validated = state != "unvalidated"
126         
127         self.get_logs(cr, uid, ids, cron_mode=False, context=context)
128         
129         contract = self.browse(cr, uid, contract_id)
130         validated2 = contract.state != "unvalidated"
131         if not validated and not validated2:
132             raise osv.except_osv(_("Contract validation error"),
133                                  _("Please check your publisher warranty contract name and validity."))
134     
135     def get_logs(self, cr, uid, ids, cron_mode=True, context={}):
136         """
137         Send a message to OpenERP's publisher warranty server to check the validity of
138         the contracts, get notifications, etc...
139         
140         @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron).
141         @type cron_mode: boolean
142         """
143         try:
144             try:
145                 result = get_sys_logs(cr, uid)
146             except:
147                 _logger.debug("Exception while sending a get logs messages", exc_info=1)
148                 raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server."))
149             
150             contracts = result["contracts"]
151             for contract in contracts:
152                 c_id = self.search(cr, uid, [("name","=",contract)])[0]
153                 date_from = contracts[contract][0]
154                 date_to = contracts[contract][1]
155                 state = contracts[contract][2]
156                 self.write(cr, uid, c_id, {
157                     "date_start": date_from,
158                     "date_stop": date_to,
159                     "state": state,
160                 })
161             
162             limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
163             for message in result["messages"]:
164                 ids = self.pool.get("res.log").search(cr, uid, [("res_model", "=", "publisher_warranty.contract"),
165                                                           ("create_date", ">=", limit_date),
166                                                           ("name", "=", message)])
167                 if ids:
168                     continue
169                 self.pool.get('res.log').create(cr, uid,
170                         {
171                             'name': message,
172                             'res_model': "publisher_warranty.contract",
173                             "read": True,
174                             "user_id": False,
175                         },
176                         context=context
177                 )
178         except:
179             _logger.debug("Exception while interpreting the result of a logs message", exc_info=1)
180             if cron_mode:
181                 return False # same as before
182             else:
183                 raise
184             
185         return True
186     
187     def get_last_user_messages(self, cr, uid, limit, context={}):
188         """
189         Get the messages to be written in the web client.
190         @return: A list of html messages with ids, can be False or empty.
191         @rtype: list of tuples(int,string)
192         """
193         ids = self.pool.get('res.log').search(cr, uid, [("res_model", "=", "publisher_warranty.contract")]
194                                         , order="create_date desc", limit=limit)
195         if not ids:
196             return []
197         messages = [(x.id, x.name) for x in self.pool.get('res.log').browse(cr, uid, ids)]
198     
199         return messages
200     
201     def del_user_message(self, cr, uid, id, context={}):
202         """
203         Delete a message.
204         """
205         self.pool.get('res.log').unlink(cr, uid, [id])
206         
207         return True
208
209     _columns = {
210         'name' : fields.char('Contract Name', size=384, required=True),
211         'date_start' : fields.date('Starting Date', readonly=True),
212         'date_stop' : fields.date('Ending Date', readonly=True),
213         'state' : fields.selection([('unvalidated', 'Unvalidated'), ('valid', 'Valid')
214                             , ('terminated', 'Terminated'), ('canceled', 'Canceled')], string="State", readonly=True),
215         'kind' : fields.char('Kind', size=64, readonly=True),
216     }
217     
218     _defaults = {
219         'state': 'unvalidated',
220     }
221     
222     _sql_constraints = [
223         ('uniq_name', 'unique(name)', "Your publisher warranty contract is already subscribed in the system !")
224     ]
225
226 publisher_warranty_contract()
227
228 class maintenance_contract(osv.osv_memory):
229     """ Old osv we only keep for compatibility with the clients. """
230     
231     _name = "maintenance.contract"
232     
233     def status(self, cr, uid):
234         return self.pool.get("publisher_warranty.contract").status(cr, uid)
235         
236     def send(self, cr, uid, tb, explanations, remarks=None):
237         return self.pool.get("publisher_warranty.contract").send(cr, uid, tb, explanations, remarks)
238     
239 maintenance_contract()
240
241 class publisher_warranty_contract_wizard(osv.osv_memory):
242     """
243     A wizard osv to help people entering a publisher warranty contract.
244     """
245     _name = 'publisher_warranty.contract.wizard'
246
247     _columns = {
248         'name' : fields.char('Contract Name', size=256, required=True ),
249         'state' : fields.selection([("draft", "Draft"), ("finished", "Finished")])
250     }
251     
252     _defaults = {
253         "state": "draft",
254     }
255
256     def action_validate(self, cr, uid, ids, context=None):
257         if not ids:
258             return False
259
260         wiz = self.browse(cr, uid, ids[0])
261         c_name = wiz.name
262         
263         contract_osv = self.pool.get("publisher_warranty.contract")
264         contracts = contract_osv.search(cr, uid, [("name","=",c_name)])
265         if contracts:
266             raise osv.except_osv(_("Error"), _("That contract is already registered in the system."))
267         
268         contract_id = contract_osv.create(cr, uid, {
269             "name": c_name,
270             "state": "unvalidated",
271         })
272         
273         contract_osv.check_validity(cr, uid, [contract_id])
274         
275         self.write(cr, uid, ids, {"state": "finished"})
276         
277         return True
278
279
280 publisher_warranty_contract_wizard()
281
282 def get_sys_logs(cr, uid):
283     """
284     Utility method to send a publisher warranty get logs messages.
285     """
286     pool = pooler.get_pool(cr.dbname)
287     
288     dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
289     db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
290     nbr_users = pool.get("res.users").search(cr, uid, [], count=True)
291     contractosv = pool.get('publisher_warranty.contract')
292     contracts = contractosv.browse(cr, uid, contractosv.search(cr, uid, []))
293     user = pool.get("res.users").browse(cr, uid, uid)
294     msg = {
295         "dbuuid": dbuuid,
296         "nbr_users": nbr_users,
297         "dbname": cr.dbname,
298         "db_create_date": db_create_date,
299         "version": release.version,
300         "contracts": [c.name for c in contracts],
301         "language": user.context_lang,
302     }
303     
304     uo = urllib.urlopen(config.get("publisher_warranty_url"),
305                         urllib.urlencode({'arg0': msg, "action": "update",}))
306     try:
307         submit_result = uo.read()
308     finally:
309         uo.close()
310     
311     result = safe_eval(submit_result)
312     
313     return result
314
315 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
316