mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[IMP] pingen: tie up everything with crons
This commit is contained in:
@@ -22,4 +22,5 @@
|
|||||||
import ir_attachment
|
import ir_attachment
|
||||||
import pingen
|
import pingen
|
||||||
import pingen_document
|
import pingen_document
|
||||||
|
import res_company
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,53 @@ Scope of the integration
|
|||||||
One can decide, per document / attachment, if it should be pushed
|
One can decide, per document / attachment, if it should be pushed
|
||||||
to pingen.com. The documents are pushed asynchronously.
|
to pingen.com. The documents are pushed asynchronously.
|
||||||
|
|
||||||
|
A second cron updates the informations of the documents from pingen.com, so we
|
||||||
|
know which of them have been sent.
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The authentication token is configured on the company's view. You can also
|
||||||
|
tick a checkbox if the staging environment (https://stage-api.pingen.com)
|
||||||
|
should be used.
|
||||||
|
|
||||||
|
The setup of the 2 crons can be changed as well:
|
||||||
|
|
||||||
|
* Run Pingen Document Push
|
||||||
|
* Run Pingen Document Update
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
On the attachment view, a new pingen.com tab has been added.
|
||||||
|
You can tick a box to push the document to pingen.com.
|
||||||
|
|
||||||
|
There is 3 additional options:
|
||||||
|
|
||||||
|
* Send: the document will not be only uploaded, but will be also send
|
||||||
|
* Speed: priority or economy
|
||||||
|
* Type of print: color or black and white
|
||||||
|
|
||||||
|
Once the configuration is done and the attachment saved, a Pingen Document
|
||||||
|
is created. You can directly access to the latter on the Link on the right on
|
||||||
|
the attachment view.
|
||||||
|
|
||||||
|
You can find them in `Settings > Customization > Low Level Objets > Pingen
|
||||||
|
Documents` or in the more convenient `Documents` menu if you have installed the
|
||||||
|
`document` module.
|
||||||
|
|
||||||
|
Errors
|
||||||
|
------
|
||||||
|
|
||||||
|
Sometimes, pingen.com will refuse to send a document because it does not meet
|
||||||
|
its requirements. In such case, the document's state becomes "Pingen Error" and
|
||||||
|
you will need to manually handle the case, either from the pingen.com backend,
|
||||||
|
or by changing the document on OpenERP and resolving the error on the Pingen
|
||||||
|
Document.
|
||||||
|
|
||||||
|
When a connection error occurs, the action will be retried on the next scheduler
|
||||||
|
run.
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@@ -50,16 +97,17 @@ Dependencies
|
|||||||
* The PDF files sent to pingen.com have to respect some `formatting rules
|
* The PDF files sent to pingen.com have to respect some `formatting rules
|
||||||
<https://stage-app.pingen.com/resources/pingen_requirements_v1_en.pdf>`_.
|
<https://stage-app.pingen.com/resources/pingen_requirements_v1_en.pdf>`_.
|
||||||
* The address must be in a format accepted by pingen.com: the last line
|
* The address must be in a format accepted by pingen.com: the last line
|
||||||
is the country.
|
is the country in English or German.
|
||||||
|
|
||||||
""",
|
""",
|
||||||
'website': 'http://www.camptocamp.com',
|
'website': 'http://www.camptocamp.com',
|
||||||
'init_xml': [],
|
'data': [
|
||||||
'update_xml': [
|
|
||||||
'ir_attachment_view.xml',
|
'ir_attachment_view.xml',
|
||||||
'pingen_document_view.xml',
|
'pingen_document_view.xml',
|
||||||
|
'pingen_data.xml',
|
||||||
|
'res_company_view.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
],
|
],
|
||||||
'demo_xml': [],
|
|
||||||
'tests': [],
|
'tests': [],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
|
|||||||
32
pingen/pingen_data.xml
Normal file
32
pingen/pingen_data.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data noupdate="1">
|
||||||
|
|
||||||
|
<record forcecreate="True" id="ir_cron_push_pingen" model="ir.cron">
|
||||||
|
<field name="name">Run Pingen Document Push</field>
|
||||||
|
<field eval="True" name="active"/>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">hours</field>
|
||||||
|
<field name="numbercall">-1</field>
|
||||||
|
<field eval="False" name="doall"/>
|
||||||
|
<field name="model">pingen.document</field>
|
||||||
|
<field name="function">_push_and_send_to_pingen_cron</field>
|
||||||
|
<field name="args">(None,)</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record forcecreate="True" id="ir_cron_update_pingen" model="ir.cron">
|
||||||
|
<field name="name">Run Pingen Document Update</field>
|
||||||
|
<field eval="True" name="active"/>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">days</field>
|
||||||
|
<field name="numbercall">-1</field>
|
||||||
|
<field eval="False" name="doall"/>
|
||||||
|
<field name="model">pingen.document</field>
|
||||||
|
<field name="function">_update_post_infos_cron</field>
|
||||||
|
<field name="args">(None,)</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
@@ -23,14 +23,12 @@ import logging
|
|||||||
|
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
|
from contextlib import closing
|
||||||
from openerp.osv import osv, orm, fields
|
from openerp.osv import osv, orm, fields
|
||||||
from openerp import tools
|
from openerp import tools
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
from .pingen import Pingen, APIError, ConnectionError, POST_SENDING_STATUS
|
from openerp import pooler
|
||||||
|
from .pingen import APIError, ConnectionError, POST_SENDING_STATUS
|
||||||
# TODO should be configurable
|
|
||||||
TOKEN = '6bc041af6f02854461ef31c2121ef853'
|
|
||||||
STAGING = True
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -60,7 +58,6 @@ class pingen_document(orm.Model):
|
|||||||
('pingen_error', 'Pingen Error'),
|
('pingen_error', 'Pingen Error'),
|
||||||
('canceled', 'Canceled')],
|
('canceled', 'Canceled')],
|
||||||
string='State', readonly=True, required=True),
|
string='State', readonly=True, required=True),
|
||||||
'date': fields.datetime('Creation Date', readonly=True),
|
|
||||||
'push_date': fields.datetime('Push Date', readonly=True),
|
'push_date': fields.datetime('Push Date', readonly=True),
|
||||||
|
|
||||||
# for `error` and `pingen_error` states when we push
|
# for `error` and `pingen_error` states when we push
|
||||||
@@ -94,12 +91,6 @@ class pingen_document(orm.Model):
|
|||||||
'Only one Pingen document is allowed per attachment.'),
|
'Only one Pingen document 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, document, context=None):
|
def _push_to_pingen(self, cr, uid, document, context=None):
|
||||||
""" Push a document to pingen.com """
|
""" Push a document to pingen.com """
|
||||||
attachment_obj = self.pool.get('ir.attachment')
|
attachment_obj = self.pool.get('ir.attachment')
|
||||||
@@ -107,7 +98,9 @@ class pingen_document(orm.Model):
|
|||||||
decoded_document = attachment_obj._decoded_content(
|
decoded_document = attachment_obj._decoded_content(
|
||||||
cr, uid, document.attachment_id, context=context)
|
cr, uid, document.attachment_id, context=context)
|
||||||
|
|
||||||
pingen = self._pingen(cr, uid, [], context=context)
|
company = self.pool.get('res.users').browse(
|
||||||
|
cr, uid, uid, context=context).company_id
|
||||||
|
pingen = self.pool.get('res.company')._pingen(cr, uid, company, context=context)
|
||||||
try:
|
try:
|
||||||
doc_id, post_id, infos = pingen.push_document(
|
doc_id, post_id, infos = pingen.push_document(
|
||||||
document.datas_fname,
|
document.datas_fname,
|
||||||
@@ -127,9 +120,17 @@ class pingen_document(orm.Model):
|
|||||||
(document.id, pingen.url))
|
(document.id, pingen.url))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
error = False
|
||||||
|
state = 'pushed'
|
||||||
|
if post_id:
|
||||||
|
state = 'sendcenter'
|
||||||
|
elif infos['requirement_failure']:
|
||||||
|
state = 'pingen_error'
|
||||||
|
error = _('The document does not meet the Pingen requirements.')
|
||||||
|
|
||||||
document.write(
|
document.write(
|
||||||
{'last_error_message': False,
|
{'last_error_message': error,
|
||||||
'state': 'sendcenter' if post_id else 'pushed',
|
'state': state,
|
||||||
'push_date': infos['date'],
|
'push_date': infos['date'],
|
||||||
'pingen_id': doc_id,
|
'pingen_id': doc_id,
|
||||||
'post_id': post_id},
|
'post_id': post_id},
|
||||||
@@ -157,11 +158,23 @@ class pingen_document(orm.Model):
|
|||||||
_('Pingen Error'),
|
_('Pingen Error'),
|
||||||
_('Error when asking Pingen to send the document %s: '
|
_('Error when asking Pingen to send the document %s: '
|
||||||
'\n%s') % (document.name, e))
|
'\n%s') % (document.name, e))
|
||||||
|
|
||||||
|
except:
|
||||||
|
_logger.exception(
|
||||||
|
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
||||||
|
document.id)
|
||||||
|
raise osv.except_osv(
|
||||||
|
_('Error'),
|
||||||
|
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _push_and_send_to_pingen_silent(self, cr, uid, ids, context=None):
|
def _push_and_send_to_pingen_cron(self, cr, uid, ids, context=None):
|
||||||
""" Push a document to pingen.com
|
""" Push a document to pingen.com
|
||||||
|
|
||||||
|
Intended to be used in a cron.
|
||||||
|
|
||||||
|
Commit after each record
|
||||||
|
|
||||||
Instead of raising, store the error in the pingen.document
|
Instead of raising, store the error in the pingen.document
|
||||||
"""
|
"""
|
||||||
if not ids:
|
if not ids:
|
||||||
@@ -169,18 +182,49 @@ class pingen_document(orm.Model):
|
|||||||
cr, uid,
|
cr, uid,
|
||||||
# do not retry pingen_error, they should be treated manually
|
# do not retry pingen_error, they should be treated manually
|
||||||
[('state', 'in', ['pending', 'pushed', 'error'])],
|
[('state', 'in', ['pending', 'pushed', 'error'])],
|
||||||
|
limit=100,
|
||||||
context=context)
|
context=context)
|
||||||
for document in self.browse(cr, uid, ids, context=context):
|
|
||||||
try:
|
|
||||||
if not document.pingen_id:
|
|
||||||
self._push_to_pingen(cr, uid, document, context=context)
|
|
||||||
if not document.post_id and document.pingen_send:
|
|
||||||
self._ask_pingen_send(cr, uid, document, context=context)
|
|
||||||
except ConnectionError as e:
|
|
||||||
document.write({'last_error_message': e, 'state': 'error'}, context=context)
|
|
||||||
except APIError as e:
|
|
||||||
document.write({'last_error_message': e, 'state': 'pingen_error'}, context=context)
|
|
||||||
|
|
||||||
|
with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr:
|
||||||
|
for document in self.browse(loc_cr, uid, ids, context=context):
|
||||||
|
|
||||||
|
if document.state == 'error':
|
||||||
|
self._resolve_error(loc_cr, uid, document, context=context)
|
||||||
|
document.refresh()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if document.state == 'pending':
|
||||||
|
self._push_to_pingen(loc_cr, uid, document, context=context)
|
||||||
|
|
||||||
|
elif document.state == 'pushed':
|
||||||
|
self._ask_pingen_send(loc_cr, uid, document, context=context)
|
||||||
|
except ConnectionError as e:
|
||||||
|
document.write({'last_error_message': e, 'state': 'error'}, context=context)
|
||||||
|
except APIError as e:
|
||||||
|
document.write({'last_error_message': e, 'state': 'pingen_error'}, context=context)
|
||||||
|
except:
|
||||||
|
_logger.error('Unexcepted error in pingen cron')
|
||||||
|
loc_cr.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
|
loc_cr.commit()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _resolve_error(self, cr, uid, document, context=None):
|
||||||
|
""" A document as resolved, put in the correct state"""
|
||||||
|
if document.post_id:
|
||||||
|
state = 'sendcenter'
|
||||||
|
elif document.pingen_id:
|
||||||
|
state = 'pushed'
|
||||||
|
else:
|
||||||
|
state = 'pending'
|
||||||
|
document.write({'state': state}, context=context)
|
||||||
|
|
||||||
|
def resolve_error(self, cr, uid, ids, context=None):
|
||||||
|
""" A document as resolved, put in the correct state"""
|
||||||
|
for document in self.browse(cr, uid, ids, context=context):
|
||||||
|
self._resolve_error(cr, uid, document, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _ask_pingen_send(self, cr, uid, document, context=None):
|
def _ask_pingen_send(self, cr, uid, document, context=None):
|
||||||
@@ -191,7 +235,9 @@ class pingen_document(orm.Model):
|
|||||||
if not document.pingen_send:
|
if not document.pingen_send:
|
||||||
document.write({'pingen_send': True}, context=context)
|
document.write({'pingen_send': True}, context=context)
|
||||||
|
|
||||||
pingen = self._pingen(cr, uid, [], context=context)
|
company = self.pool.get('res.users').browse(
|
||||||
|
cr, uid, uid, context=context).company_id
|
||||||
|
pingen = self.pool.get('res.company')._pingen(cr, uid, company, context=context)
|
||||||
try:
|
try:
|
||||||
post_id = pingen.send_document(
|
post_id = pingen.send_document(
|
||||||
document.pingen_id,
|
document.pingen_id,
|
||||||
@@ -235,6 +281,14 @@ class pingen_document(orm.Model):
|
|||||||
_('Pingen Error'),
|
_('Pingen Error'),
|
||||||
_('Error when asking Pingen to send the document %s: '
|
_('Error when asking Pingen to send the document %s: '
|
||||||
'\n%s') % (document.name, e))
|
'\n%s') % (document.name, e))
|
||||||
|
|
||||||
|
except:
|
||||||
|
_logger.exception(
|
||||||
|
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
||||||
|
document.id)
|
||||||
|
raise osv.except_osv(
|
||||||
|
_('Error'),
|
||||||
|
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _update_post_infos(self, cr, uid, document, context=None):
|
def _update_post_infos(self, cr, uid, document, context=None):
|
||||||
@@ -243,7 +297,9 @@ class pingen_document(orm.Model):
|
|||||||
if not document.post_id:
|
if not document.post_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
pingen = self._pingen(cr, uid, [], context=context)
|
company = self.pool.get('res.users').browse(
|
||||||
|
cr, uid, uid, context=context).company_id
|
||||||
|
pingen = self.pool.get('res.company')._pingen(cr, uid, company, context=context)
|
||||||
try:
|
try:
|
||||||
post_infos = pingen.post_infos(document.post_id)
|
post_infos = pingen.post_infos(document.post_id)
|
||||||
except ConnectionError as e:
|
except ConnectionError as e:
|
||||||
@@ -270,6 +326,7 @@ class pingen_document(orm.Model):
|
|||||||
'country_id': country_ids[0] if country_ids else False,
|
'country_id': country_ids[0] if country_ids else False,
|
||||||
'send_date': post_infos['date'],
|
'send_date': post_infos['date'],
|
||||||
'pages': post_infos['pages'],
|
'pages': post_infos['pages'],
|
||||||
|
'last_error_message': False,
|
||||||
}
|
}
|
||||||
if pingen.is_posted(post_infos):
|
if pingen.is_posted(post_infos):
|
||||||
vals['state'] = 'sent'
|
vals['state'] = 'sent'
|
||||||
@@ -277,9 +334,13 @@ class pingen_document(orm.Model):
|
|||||||
document.write(vals, context=context)
|
document.write(vals, context=context)
|
||||||
_logger.info('Pingen Document %s: status updated' % document.id)
|
_logger.info('Pingen Document %s: status updated' % document.id)
|
||||||
|
|
||||||
def _update_post_infos_silent(self, cr, uid, ids, context=None):
|
def _update_post_infos_cron(self, cr, uid, ids, context=None):
|
||||||
""" Update the informations from pingen of a document in the Sendcenter
|
""" Update the informations from pingen of a document in the Sendcenter
|
||||||
|
|
||||||
|
Intended to be used in a cron.
|
||||||
|
|
||||||
|
Commit after each record
|
||||||
|
|
||||||
Do not raise errors, only skip the update of the record.
|
Do not raise errors, only skip the update of the record.
|
||||||
"""
|
"""
|
||||||
if not ids:
|
if not ids:
|
||||||
@@ -288,15 +349,20 @@ class pingen_document(orm.Model):
|
|||||||
[('state', '=', 'sendcenter')],
|
[('state', '=', 'sendcenter')],
|
||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
for document in self.browse(cr, uid, ids, context=context):
|
with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr:
|
||||||
try:
|
for document in self.browse(loc_cr, uid, ids, context=context):
|
||||||
self._update_post_infos(cr, uid, document, context=context)
|
try:
|
||||||
except (ConnectionError, APIError):
|
self._update_post_infos(loc_cr, uid, document, context=context)
|
||||||
# Intended silented exception, we can consider that it's not
|
except (ConnectionError, APIError):
|
||||||
# important if the update not worked, that's
|
# will be retried the next time
|
||||||
# only informative, and it will be retried the next time
|
# In any case, the error has been logged by _update_post_infos
|
||||||
# In any case, the error has been by _update_post_infos
|
loc_cr.rollback()
|
||||||
pass
|
except:
|
||||||
|
_logger.error('Unexcepted error in pingen cron')
|
||||||
|
loc_cr.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
|
loc_cr.commit()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_post_infos(self, cr, uid, ids, context=None):
|
def update_post_infos(self, cr, uid, ids, context=None):
|
||||||
@@ -319,5 +385,13 @@ class pingen_document(orm.Model):
|
|||||||
_('Pingen Error'),
|
_('Pingen Error'),
|
||||||
_('Error when updating the status of Document %s from Pingen: '
|
_('Error when updating the status of Document %s from Pingen: '
|
||||||
'\n%s') % (document.name, e))
|
'\n%s') % (document.name, e))
|
||||||
|
|
||||||
|
except:
|
||||||
|
_logger.exception(
|
||||||
|
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
||||||
|
document.id)
|
||||||
|
raise osv.except_osv(
|
||||||
|
_('Error'),
|
||||||
|
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,6 @@
|
|||||||
<separator string="Dates" colspan="4"/>
|
<separator string="Dates" colspan="4"/>
|
||||||
<newline />
|
<newline />
|
||||||
<group col="2" colspan="2">
|
<group col="2" colspan="2">
|
||||||
<field name="date"/>
|
|
||||||
<field name="push_date"/>
|
<field name="push_date"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
@@ -75,14 +74,17 @@
|
|||||||
<newline />
|
<newline />
|
||||||
<group col="2" colspan="2">
|
<group col="2" colspan="2">
|
||||||
<button name="push_to_pingen" type="object"
|
<button name="push_to_pingen" type="object"
|
||||||
states="pending,error,pingen_error"
|
states="pending"
|
||||||
string="Push to pingen.com" icon="terp-camera_test"/>
|
string="Push to pingen.com" icon="terp-stage"/>
|
||||||
<button name="ask_pingen_send" type="object"
|
<button name="ask_pingen_send" type="object"
|
||||||
states="pushed"
|
states="pushed"
|
||||||
string="Ask pingen.com to send the document" icon="terp-camera_test"/>
|
string="Ask pingen.com to send the document" icon="gtk-print"/>
|
||||||
|
<button name="resolve_error" type="object"
|
||||||
|
states="error,pingen_error"
|
||||||
|
string="Errors resolved" icon="gtk-redo"/>
|
||||||
<button name="update_post_infos" type="object"
|
<button name="update_post_infos" type="object"
|
||||||
states="sendcenter"
|
states="sendcenter"
|
||||||
string="Update the letter's informations" icon="terp-camera_test"/>
|
string="Update the letter's informations" icon="gtk-refresh"/>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
<page string="Attachment">
|
<page string="Attachment">
|
||||||
@@ -117,15 +119,27 @@
|
|||||||
<field name="type">search</field>
|
<field name="type">search</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<search string="Pingen Document">
|
<search string="Pingen Document">
|
||||||
<filter icon="terp-stage"
|
<filter icon="terp-project"
|
||||||
string="Pending"
|
string="Pending"
|
||||||
domain="[('state','=','pending')]"/>
|
domain="[('state','=','pending')]"/>
|
||||||
<filter icon="terp-stock_align_left_24"
|
<filter icon="terp-stage"
|
||||||
string="Pushed"
|
string="Pushed"
|
||||||
domain="[('state','=','pushed')]"/>
|
domain="[('state','=','pushed')]"/>
|
||||||
<filter icon="terp-stock_align_left_24"
|
<filter icon="gtk-print"
|
||||||
|
string="In Sendcenter"
|
||||||
|
domain="[('state','=','sendcenter')]"/>
|
||||||
|
<filter icon="kanban-apply"
|
||||||
|
string="Sent"
|
||||||
|
domain="[('state','=','sent')]"/>
|
||||||
|
<filter icon="kanban-stop"
|
||||||
string="Error"
|
string="Error"
|
||||||
domain="[('state','=','error')]"/>
|
domain="[('state','=','error')]"/>
|
||||||
|
<filter icon="STOCK_NO"
|
||||||
|
string="Pingen Error"
|
||||||
|
domain="[('state','=','pingen_error')]"/>
|
||||||
|
<filter icon="terp-dialog-close"
|
||||||
|
string="Canceled"
|
||||||
|
domain="[('state','=','canceled')]"/>
|
||||||
<separator orientation="vertical"/>
|
<separator orientation="vertical"/>
|
||||||
<field name="attachment_id" />
|
<field name="attachment_id" />
|
||||||
</search>
|
</search>
|
||||||
|
|||||||
42
pingen/res_company.py
Normal file
42
pingen/res_company.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Author: Guewen Baconnier
|
||||||
|
# Copyright 2012 Camptocamp SA
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp.osv import orm, fields
|
||||||
|
from openerp.osv.orm import browse_record
|
||||||
|
from .pingen import Pingen
|
||||||
|
|
||||||
|
class res_company(orm.Model):
|
||||||
|
|
||||||
|
_inherit = 'res.company'
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'pingen_token': fields.char('Pingen Token', size=32),
|
||||||
|
'pingen_staging': fields.boolean('Pingen Staging')
|
||||||
|
}
|
||||||
|
|
||||||
|
def _pingen(self, cr, uid, company, context=None):
|
||||||
|
""" Return a Pingen instance to work on """
|
||||||
|
assert isinstance(company, (int, long, browse_record)), \
|
||||||
|
"one id or browse_record expected"
|
||||||
|
if not isinstance(company, browse_record):
|
||||||
|
company = self.browse(cr, uid, company_id, context=context)
|
||||||
|
return Pingen(company.pingen_token, staging=company.pingen_staging)
|
||||||
|
|
||||||
20
pingen/res_company_view.xml
Normal file
20
pingen/res_company_view.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data noupdate="0">
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="view_company_inherit_form">
|
||||||
|
<field name="name">res.company.form.inherit</field>
|
||||||
|
<field name="model">res.company</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="inherit_id" ref="base.view_company_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<page string="Configuration" position="inside">
|
||||||
|
<separator string="Pingen.com" colspan="4"/>
|
||||||
|
<field name="pingen_token" groups="base.group_system"/>
|
||||||
|
<field name="pingen_staging" groups="base.group_system"/>
|
||||||
|
</page>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
3
pingen/security/ir.model.access.csv
Normal file
3
pingen/security/ir.model.access.csv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||||
|
"access_pingen_document_all","pingen_document all","model_pingen_document",,1,0,0,0
|
||||||
|
"access_pingen_document_group_user","pingen_document group_user","model_pingen_document","base.group_user",1,1,1,1
|
||||||
|
Reference in New Issue
Block a user