mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[IMP] update of the posts
This commit is contained in:
@@ -28,6 +28,14 @@ from requests.packages.urllib3.filepost import encode_multipart_formdata
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
POST_SENDING_STATUS = {
|
||||
100: 'Ready/Pending',
|
||||
101: 'Processing',
|
||||
102: 'Waiting for confirmation',
|
||||
200: 'Sent',
|
||||
300: 'Some error occured and object wasn\'t sent',
|
||||
400: 'Sending cancelled',
|
||||
}
|
||||
|
||||
class PingenException(RuntimeError):
|
||||
"""There was an ambiguous exception that occurred while handling your
|
||||
@@ -42,7 +50,6 @@ class APIError(PingenException):
|
||||
"""An Error occured with the pingen API"""
|
||||
|
||||
|
||||
|
||||
class Pingen(object):
|
||||
""" Interface to pingen.com API
|
||||
"""
|
||||
@@ -90,7 +97,9 @@ class Pingen(object):
|
||||
response = method(complete_url, **kwargs)
|
||||
|
||||
if not response.ok:
|
||||
raise ConnectionError(response.error)
|
||||
raise ConnectionError(
|
||||
"%s: %s" % (response.json['errorcode'],
|
||||
response.json['errormessage']))
|
||||
|
||||
if response.json['error']:
|
||||
raise APIError(
|
||||
@@ -167,3 +176,24 @@ class Pingen(object):
|
||||
|
||||
return response.json['id']
|
||||
|
||||
def post_infos(self, post_id):
|
||||
""" Return the information of a post
|
||||
|
||||
:param int post_id: id of the document to send
|
||||
:return: dict of infos of the post
|
||||
"""
|
||||
response = self._send(
|
||||
requests.get,
|
||||
'post/get',
|
||||
params={'id': post_id})
|
||||
|
||||
return response.json['item']
|
||||
|
||||
@staticmethod
|
||||
def is_posted(post_infos):
|
||||
""" return True if the post has been sent
|
||||
|
||||
:param dict post_infos: post infos returned by `post_infos`
|
||||
"""
|
||||
return post_infos['status'] == 200
|
||||
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
##############################################################################
|
||||
|
||||
import logging
|
||||
import datetime
|
||||
|
||||
from cStringIO import StringIO
|
||||
|
||||
from openerp.osv import osv, orm, fields
|
||||
from openerp import tools
|
||||
from openerp.tools.translate import _
|
||||
from .pingen import Pingen, APIError, ConnectionError
|
||||
from .pingen import Pingen, APIError, ConnectionError, POST_SENDING_STATUS
|
||||
|
||||
# TODO should be configurable
|
||||
TOKEN = '6bc041af6f02854461ef31c2121ef853'
|
||||
STAGING = True
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -58,15 +58,28 @@ class pingen_task(orm.Model):
|
||||
('pingen_error', 'Pingen Error'),
|
||||
('canceled', 'Canceled')],
|
||||
string='State', readonly=True, required=True),
|
||||
'date': fields.datetime('Creation Date'),
|
||||
'push_date': fields.datetime('Push Date'),
|
||||
'date': fields.datetime('Creation Date', readonly=True),
|
||||
'push_date': fields.datetime('Push Date', readonly=True),
|
||||
|
||||
# for `error` and `pingen_error` states when we push
|
||||
'last_error_message': fields.text('Error Message', readonly=True),
|
||||
|
||||
# pingen IDs
|
||||
'pingen_id': fields.integer(
|
||||
'Pingen ID',
|
||||
'Pingen ID', readonly=True,
|
||||
help="ID of the document in the Pingen Documents"),
|
||||
'post_id': fields.integer(
|
||||
'Pingen Post ID',
|
||||
'Pingen Post ID', readonly=True,
|
||||
help="ID of the document in the Pingen Sendcenter"),
|
||||
|
||||
# sendcenter infos
|
||||
'post_status': fields.char('Post Status', size=128, readonly=True),
|
||||
'parsed_address': fields.text('Parsed Address', readonly=True),
|
||||
'cost': fields.float('Cost', readonly=True),
|
||||
'currency_id': fields.many2one('res.currency', 'Currency', readonly=True),
|
||||
'country_id': fields.many2one('res.country', 'Country', readonly=True),
|
||||
'send_date': fields.datetime('Date of sending', readonly=True),
|
||||
'pages': fields.integer('Pages', readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -79,6 +92,12 @@ class pingen_task(orm.Model):
|
||||
'Only one Pingen task is allowed per attachment.'),
|
||||
]
|
||||
|
||||
def _pingen(self, cr, uid, ids, context=None):
|
||||
""" Return a Pingen instance to work on """
|
||||
assert not ids, "ids is there by convention, should not be used"
|
||||
# TODO parameterize
|
||||
return Pingen(TOKEN, staging=STAGING)
|
||||
|
||||
def _push_to_pingen(self, cr, uid, task, context=None):
|
||||
""" Push a document to pingen.com """
|
||||
attachment_obj = self.pool.get('ir.attachment')
|
||||
@@ -88,31 +107,32 @@ class pingen_task(orm.Model):
|
||||
|
||||
pingen = self._pingen(cr, uid, [], context=context)
|
||||
try:
|
||||
doc_id, post_id, __ = pingen.push_document(
|
||||
doc_id, post_id, infos = pingen.push_document(
|
||||
task.datas_fname,
|
||||
StringIO(decoded_document),
|
||||
task.pingen_send,
|
||||
task.pingen_speed,
|
||||
task.pingen_color)
|
||||
except ConnectionError as e:
|
||||
_logger.exception('Connection Error when pushing Pingen Task %s to %s.' %
|
||||
_logger.exception(
|
||||
'Connection Error when pushing Pingen Task %s to %s.' %
|
||||
(task.id, pingen.url))
|
||||
raise
|
||||
|
||||
except APIError as e:
|
||||
_logger.error('API Error when pushing Pingen Task %s to %s.' %
|
||||
_logger.error(
|
||||
'API Error when pushing Pingen Task %s to %s.' %
|
||||
(task.id, pingen.url))
|
||||
raise
|
||||
|
||||
now = datetime.datetime.now().strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
task.write(
|
||||
{'last_error_message': False,
|
||||
'state': 'sendcenter' if post_id else 'pushed',
|
||||
'push_date': now,
|
||||
'push_date': infos['date'],
|
||||
'pingen_id': doc_id,
|
||||
'post_id': post_id},
|
||||
context=context)
|
||||
_logger.info('Pingen Task %s pushed to %s' % (task.id, pingen.url))
|
||||
_logger.info('Pingen Task %s: pushed to %s' % (task.id, pingen.url))
|
||||
|
||||
def push_to_pingen(self, cr, uid, ids, context=None):
|
||||
""" Push a document to pingen.com
|
||||
@@ -137,26 +157,29 @@ class pingen_task(orm.Model):
|
||||
'\n%s') % (task.name, e))
|
||||
return True
|
||||
|
||||
def _push_to_pingen_with_logs(self, cr, uid, ids, context=None):
|
||||
def _push_and_send_to_pingen_silent(self, cr, uid, ids, context=None):
|
||||
""" Push a document to pingen.com
|
||||
|
||||
Instead of raising, store the error in the pingen.document
|
||||
"""
|
||||
if not ids:
|
||||
ids = self.search(
|
||||
cr, uid,
|
||||
# do not retry pingen_error, they should be treated manually
|
||||
[('state', 'in', ['pending', 'pushed', 'error'])],
|
||||
context=context)
|
||||
for task in self.browse(cr, uid, ids, context=context):
|
||||
try:
|
||||
self._push_to_pingen(cr, uid, task, context=context)
|
||||
if not task.pingen_id:
|
||||
self._push_to_pingen(cr, uid, task, context=context)
|
||||
if not task.post_id and task.pingen_send:
|
||||
self._ask_pingen_send(cr, uid, task, context=context)
|
||||
except ConnectionError as e:
|
||||
task.write({'last_error_message': e, 'state': 'error'}, context=context)
|
||||
except APIError as e:
|
||||
task.write({'last_error_message': e, 'state': 'pingen_error'}, context=context)
|
||||
return True
|
||||
|
||||
def _pingen(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
"""
|
||||
assert not ids, "ids is there by convention, should not be used"
|
||||
# TODO parameterize
|
||||
return Pingen(TOKEN, staging=True)
|
||||
return True
|
||||
|
||||
def _ask_pingen_send(self, cr, uid, task, context=None):
|
||||
""" For a document already pushed to pingen, ask to send it.
|
||||
@@ -186,7 +209,7 @@ class pingen_task(orm.Model):
|
||||
'state': 'sendcenter',
|
||||
'post_id': post_id},
|
||||
context=context)
|
||||
_logger.info('Pingen Task %s asked for sending to %s' % (task.id, pingen.url))
|
||||
_logger.info('Pingen Task %s: asked for sending to %s' % (task.id, pingen.url))
|
||||
|
||||
return True
|
||||
|
||||
@@ -211,3 +234,84 @@ class pingen_task(orm.Model):
|
||||
'\n%s') % (task.name, e))
|
||||
return True
|
||||
|
||||
def _update_post_infos(self, cr, uid, task, context=None):
|
||||
""" Update the informations from pingen of a document in the Sendcenter
|
||||
"""
|
||||
if not task.post_id:
|
||||
return
|
||||
|
||||
pingen = self._pingen(cr, uid, [], context=context)
|
||||
try:
|
||||
post_infos = pingen.post_infos(task.post_id)
|
||||
except ConnectionError as e:
|
||||
_logger.exception('Connection Error when asking for sending Pingen Task %s to %s.' %
|
||||
(task.id, pingen.url))
|
||||
raise
|
||||
except APIError as e:
|
||||
_logger.exception('API Error when asking for sending Pingen Task %s to %s.' %
|
||||
(task.id, pingen.url))
|
||||
raise
|
||||
|
||||
currency_ids = self.pool.get('res.currency').search(
|
||||
cr, uid, [('name', '=', post_infos['currency'])], context=context)
|
||||
country_ids = self.pool.get('res.country').search(
|
||||
cr, uid, [('code', '=', post_infos['country'])], context=context)
|
||||
vals = {
|
||||
'post_status': POST_SENDING_STATUS[post_infos['status']],
|
||||
'cost': post_infos['cost'],
|
||||
'currency_id': currency_ids[0] if currency_ids else False,
|
||||
'parsed_address': post_infos['address'],
|
||||
'country_id': country_ids[0] if country_ids else False,
|
||||
'send_date': post_infos['date'],
|
||||
'pages': post_infos['pages'],
|
||||
}
|
||||
if pingen.is_posted(post_infos):
|
||||
vals['state'] = 'sent'
|
||||
|
||||
task.write(vals, context=context)
|
||||
_logger.info('Pingen Task %s: status updated' % task.id)
|
||||
|
||||
def _update_post_infos_silent(self, cr, uid, ids, context=None):
|
||||
""" Update the informations from pingen of a document in the Sendcenter
|
||||
|
||||
Do not raise errors, only skip the update of the record.
|
||||
"""
|
||||
if not ids:
|
||||
ids = self.search(
|
||||
cr, uid,
|
||||
[('state', '=', 'sendcenter')],
|
||||
context=context)
|
||||
|
||||
for task in self.browse(cr, uid, ids, context=context):
|
||||
try:
|
||||
self._update_post_infos(cr, uid, task, context=context)
|
||||
except (ConnectionError, APIError):
|
||||
# Intended silented exception, we can consider that it's not
|
||||
# important if the update not worked, that's
|
||||
# only informative, and it will be retried the next time
|
||||
# In any case, the error has been by _update_post_infos
|
||||
pass
|
||||
return True
|
||||
|
||||
def update_post_infos(self, cr, uid, ids, context=None):
|
||||
""" Update the informations from pingen of a document in the Sendcenter
|
||||
|
||||
Wrapper method for multiple ids (when triggered from button for
|
||||
instance) for public interface.
|
||||
"""
|
||||
for task in self.browse(cr, uid, ids, context=context):
|
||||
try:
|
||||
self._update_post_infos(cr, uid, task, context=context)
|
||||
except ConnectionError as e:
|
||||
raise osv.except_osv(
|
||||
_('Pingen Connection Error'),
|
||||
_('Connection Error when updating the status of Document %s'
|
||||
' from Pingen') % task.name)
|
||||
|
||||
except APIError as e:
|
||||
raise osv.except_osv(
|
||||
_('Pingen Error'),
|
||||
_('Error when updating the status of Document %s from Pingen: '
|
||||
'\n%s') % (task.name, e))
|
||||
return True
|
||||
|
||||
|
||||
@@ -46,15 +46,33 @@
|
||||
<field name="push_date"/>
|
||||
</group>
|
||||
|
||||
<separator string="Errors" colspan="4"/>
|
||||
<newline />
|
||||
<group col="2" colspan="2">
|
||||
<field nolabel="1" name="last_error_message"/>
|
||||
<group colspan="4" attrs="{'invisible': [('last_error_message', '=', False)]}">
|
||||
<separator string="Errors" colspan="4"/>
|
||||
<newline />
|
||||
<group col="2" colspan="2">
|
||||
<field nolabel="1" name="last_error_message"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group colspan="4" attrs="{'invisible': [('state', 'not in', ['sendcenter', 'sent'])]}">
|
||||
<separator string="Sendcenter" colspan="4"/>
|
||||
<newline />
|
||||
<group col="4" colspan="2">
|
||||
<field colspan="4" name="post_status"/>
|
||||
<group col="3" colspan="2">
|
||||
<field name="cost"/>
|
||||
<field colspan="1" nolabel="1" name="currency_id"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<field name="parsed_address"/>
|
||||
<field name="country_id"/>
|
||||
<field name="send_date"/>
|
||||
<field name="pages"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<separator string="Actions" colspan="4"/>
|
||||
<newline />
|
||||
|
||||
<group col="2" colspan="2">
|
||||
<button name="push_to_pingen" type="object"
|
||||
states="pending,error,pingen_error"
|
||||
@@ -62,6 +80,9 @@
|
||||
<button name="ask_pingen_send" type="object"
|
||||
states="pushed"
|
||||
string="Ask pingen.com to send the document" icon="terp-camera_test"/>
|
||||
<button name="update_post_infos" type="object"
|
||||
states="sendcenter"
|
||||
string="Update the letter's informations" icon="terp-camera_test"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Attachment">
|
||||
|
||||
Reference in New Issue
Block a user