1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 OpenERP S.A. (<http://www.openerp.com>).
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.
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.
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/>.
20 ##############################################################################
22 Module to handle publisher warranty contracts as well as notifications from
34 from osv import osv, fields
35 from tools.translate import _
36 from tools.safe_eval import safe_eval
37 from tools.config import config
38 from tools import misc
40 _logger = logging.getLogger(__name__)
43 Time interval that will be used to determine up to which date we will
44 check the logs to see if a message we just received was already logged.
45 @type: datetime.timedelta
47 _PREVIOUS_LOG_CHECK = datetime.timedelta(days=365)
49 class publisher_warranty_contract(osv.osv):
51 Osv representing a publisher warranty contract.
53 _name = "publisher_warranty.contract"
55 def _get_valid_contracts(self, cr, uid):
57 Return the list of the valid contracts encoded in the system.
59 @return: A list of contracts
60 @rtype: list of publisher_warranty.contract browse records
62 return [contract for contract in self.browse(cr, uid, self.search(cr, uid, []))
63 if contract.state == 'valid']
65 def status(self, cr, uid):
66 """ Method called by the client to check availability of publisher warranty contract. """
68 contracts = self._get_valid_contracts(cr, uid)
70 'status': "full" if contracts else "none" ,
71 'uncovered_modules': list(),
74 def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None):
75 """ Method called by the client to send a problem to the publisher warranty server. """
80 valid_contracts = self._get_valid_contracts(cr, uid)
81 valid_contract = valid_contracts[0]
85 dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
86 db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
87 user = self.pool.get("res.users").browse(cr, uid, uid)
89 email = user.user_email
91 msg = {'contract_name': valid_contract.name,
93 'explanations': explanations,
98 'db_create_date': db_create_date,
99 'issue_name': issue_name,
101 'user_name': user_name,
105 add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
106 uo = urllib2.urlopen(config.get("publisher_warranty_url"),
107 urllib.urlencode({'arg0': msg, "action": "send",}),**add_arg)
109 submit_result = uo.read()
113 result = safe_eval(submit_result)
120 except osv.except_osv:
123 _logger.warning("Error sending problem report", exc_info=1)
124 raise osv.except_osv(_("Error"),
125 _("Error during communication with the publisher warranty server."))
129 def check_validity(self, cr, uid, ids, context=None):
131 Check the validity of a publisher warranty contract. This method just call get_logs() but checks
132 some more things, so it can be called from a user interface.
135 contract = self.browse(cr, uid, contract_id)
136 state = contract.state
137 validated = state != "unvalidated"
139 self.get_logs(cr, uid, ids, cron_mode=False, context=context)
141 contract = self.browse(cr, uid, contract_id)
142 validated2 = contract.state != "unvalidated"
143 if not validated and not validated2:
144 raise osv.except_osv(_("Contract validation error"),
145 _("Please verify your publisher warranty serial number and validity."))
148 def get_logs(self, cr, uid, ids, cron_mode=True, context=None):
150 Send a message to OpenERP's publisher warranty server to check the validity of
151 the contracts, get notifications, etc...
153 @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron).
154 @type cron_mode: boolean
158 result = get_sys_logs(cr, uid)
160 if cron_mode: # we don't want to see any stack trace in cron
162 _logger.debug("Exception while sending a get logs messages", exc_info=1)
163 raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server."))
165 contracts = result["contracts"]
166 for contract in contracts:
167 c_id = self.search(cr, uid, [("name","=",contract)])[0]
168 # for backward compatibility
169 if type(contracts[contract]) == tuple:
170 self.write(cr, uid, c_id, {
171 "date_start": contracts[contract][0],
172 "date_stop": contracts[contract][1],
173 "state": contracts[contract][2],
174 "check_support": False,
179 self.write(cr, uid, c_id, {
180 "date_start": contracts[contract]["date_from"],
181 "date_stop": contracts[contract]["date_to"],
182 "state": contracts[contract]["state"],
183 "check_support": contracts[contract]["check_support"],
184 "check_opw": contracts[contract]["check_opw"],
185 "kind": contracts[contract]["kind"],
189 limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
190 for message in result["messages"]:
191 ids = self.pool.get("res.log").search(cr, uid, [("res_model", "=", "publisher_warranty.contract"),
192 ("create_date", ">=", limit_date),
193 ("name", "=", message)])
196 self.pool.get('res.log').create(cr, uid,
199 'res_model': "publisher_warranty.contract",
207 return False # we don't want to see any stack trace in cron
212 def get_last_user_messages(self, cr, uid, limit, context=None):
214 Get the messages to be written in the web client.
215 @return: A list of html messages with ids, can be False or empty.
216 @rtype: list of tuples(int,string)
218 ids = self.pool.get('res.log').search(cr, uid, [("res_model", "=", "publisher_warranty.contract")]
219 , order="create_date desc", limit=limit)
222 messages = [(x.id, x.name) for x in self.pool.get('res.log').browse(cr, uid, ids)]
226 def del_user_message(self, cr, uid, id, context=None):
230 self.pool.get('res.log').unlink(cr, uid, [id])
235 'name' : fields.char('Serial Key', size=384, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."),
236 'date_start' : fields.date('Starting Date', readonly=True),
237 'date_stop' : fields.date('Ending Date', readonly=True),
238 'state' : fields.selection([('unvalidated', 'Unvalidated'), ('valid', 'Valid')
239 , ('terminated', 'Terminated'), ('canceled', 'Canceled')], string="State", readonly=True),
240 'kind' : fields.char('Kind', size=64, readonly=True),
241 "check_support": fields.boolean("Support Level 1", readonly=True),
242 "check_opw": fields.boolean("OPW", readonly=True, help="Checked if this is an OpenERP Publisher's Warranty contract (versus older contract types"),
246 'state': 'unvalidated',
250 ('uniq_name', 'unique(name)', "That contract is already registered in the system.")
253 publisher_warranty_contract()
255 class maintenance_contract(osv.osv_memory):
256 """ Old osv we only keep for compatibility with the clients. """
258 _name = "maintenance.contract"
260 def status(self, cr, uid):
261 return self.pool.get("publisher_warranty.contract").status(cr, uid)
263 def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None):
264 return self.pool.get("publisher_warranty.contract").send(cr, uid, tb,
265 explanations, remarks, issue_name)
267 maintenance_contract()
269 class publisher_warranty_contract_wizard(osv.osv_memory):
271 A wizard osv to help people entering a publisher warranty contract.
273 _name = 'publisher_warranty.contract.wizard'
274 _inherit = "ir.wizard.screen"
277 'name' : fields.char('Serial Key', size=256, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."),
278 'state' : fields.selection([("draft", "Draft"), ("finished", "Finished")])
285 def action_validate(self, cr, uid, ids, context=None):
289 wiz = self.browse(cr, uid, ids[0])
292 contract_osv = self.pool.get("publisher_warranty.contract")
293 contracts = contract_osv.search(cr, uid, [("name","=",c_name)])
295 raise osv.except_osv(_("Error"), _("That contract is already registered in the system."))
297 contract_id = contract_osv.create(cr, uid, {
299 "state": "unvalidated",
302 contract_osv.check_validity(cr, uid, [contract_id])
304 self.write(cr, uid, ids, {"state": "finished"})
306 # We should return an action ?
310 publisher_warranty_contract_wizard()
312 def get_sys_logs(cr, uid):
314 Utility method to send a publisher warranty get logs messages.
316 pool = pooler.get_pool(cr.dbname)
318 dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
319 db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
320 nbr_users = pool.get("res.users").search(cr, uid, [], count=True)
321 contractosv = pool.get('publisher_warranty.contract')
322 contracts = contractosv.browse(cr, uid, contractosv.search(cr, uid, []))
323 user = pool.get("res.users").browse(cr, uid, uid)
326 "nbr_users": nbr_users,
328 "db_create_date": db_create_date,
329 "version": release.version,
330 "contracts": [c.name for c in contracts],
331 "language": user.context_lang,
334 add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
335 arguments = {'arg0': msg, "action": "update",}
336 arguments_raw = urllib.urlencode(arguments)
337 url = config.get("publisher_warranty_url")
338 uo = urllib2.urlopen(url, arguments_raw, **add_arg)
340 submit_result = uo.read()
344 result = safe_eval(submit_result) if submit_result else {}
348 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: