commit
6b111d9b1c
|
@ -26,30 +26,17 @@ import time
|
|||
import base64
|
||||
import urllib2
|
||||
import openerp.release as release
|
||||
from tools.translate import _
|
||||
import netsvc
|
||||
|
||||
edi_module = 'edi_import'
|
||||
|
||||
def safe_unique_id(model, database_id):
|
||||
"""Generate a unique string to represent a (model,database id) pair
|
||||
def safe_unique_id(database_id, model, record_id):
|
||||
"""Generate a unique string to represent a (database id,model,record_id) pair
|
||||
without being too long, without revealing the database id, and
|
||||
with a very low probability of collisions.
|
||||
|
||||
Each EDI record and each relationship value are represented using a unique
|
||||
database identifier. These database identifiers include the database unique
|
||||
ID, as a way to uniquely refer to any record within any OpenERP instance,
|
||||
without conflict.
|
||||
|
||||
For OpenERP records that have an existing "XML ID" (i.e. an entry in
|
||||
ir.model.data), the EDI unique identifier for this record will be made of
|
||||
"%s:%s" % (the database's UUID, the XML ID). The database's UUID MUST
|
||||
NOT contain a colon characters (this is guaranteed by the UUID algorithm).
|
||||
|
||||
For OpenERP records that have no existing "XML ID", a new one should be
|
||||
created during the EDI export. It is recommended that the generated XML ID
|
||||
contains a readable reference to the record model, plus a unique value that
|
||||
hides the database ID.
|
||||
"""
|
||||
msg = "%s-%s-%s" % (model, time.time(), database_id)
|
||||
msg = "%s-%s-%s-%s" % (time.time(), database_id, model, record_id)
|
||||
digest = hashlib.sha1(msg).digest()
|
||||
digest = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in zip(digest[:9], digest[9:-2]))
|
||||
# finally, use the b64-encoded folded digest as ID part of the unique ID:
|
||||
|
@ -70,14 +57,14 @@ class ir_edi_document(osv.osv):
|
|||
]
|
||||
|
||||
|
||||
def new_edi_token(self, record):
|
||||
def new_edi_token(self, cr, uid, record):
|
||||
"""
|
||||
Return a new, random unique token to identify an edi.document
|
||||
:param record: It's a object of browse_record of any model
|
||||
"""
|
||||
db_uuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
|
||||
|
||||
edi_token = hashlib.sha256('%s-%s-%s' % (time.time(), db_uuid, time.time())).hexdigest()
|
||||
edi_token = hashlib.sha256('%s-%s-%s-%s' % (time.time(), db_uuid, record._name, record.id)).hexdigest()
|
||||
return edi_token
|
||||
|
||||
def serialize(self, edi_documents):
|
||||
|
@ -123,8 +110,14 @@ class ir_edi_document(osv.osv):
|
|||
|
||||
:param edi_dicts: list of edi_dict
|
||||
"""
|
||||
module_obj =self.pool.get('ir.module.module')
|
||||
res = []
|
||||
for edi_document in edi_documents:
|
||||
module = edi_document.get('__module')
|
||||
module_ids = module_obj.search(cr, uid, [('name','=',module),('state','not in',['uninstalled', 'uninstallable', 'to remove'])])
|
||||
if not module_ids:
|
||||
raise osv.except_osv(_('Invalid action !'),
|
||||
_('The document you are trying to import requires the OpenERP "%s" application. The OpenERP configuration assistant will help with this if you are connected as an administrator.')%(module))
|
||||
model = edi_document.get('__model')
|
||||
assert model, _('model should be provided in EDI Dict')
|
||||
model_obj = self.pool.get(model)
|
||||
|
@ -154,7 +147,7 @@ class ir_edi_document(osv.osv):
|
|||
exported_ids = []
|
||||
for record in records:
|
||||
document = self.generate_edi(cr, uid, [record], context)
|
||||
token = self.new_edi_token(record)
|
||||
token = self.new_edi_token(cr, uid, record)
|
||||
self.create(cr, uid, {
|
||||
'name': token,
|
||||
'document': document
|
||||
|
@ -193,6 +186,23 @@ class edi(object):
|
|||
specific behavior, based on the primitives provided by this superclass."""
|
||||
|
||||
def edi_xml_id(self, cr, uid, record, context=None):
|
||||
"""
|
||||
Generate a unique string to represent a pair of (the database's UUID, the XML ID).
|
||||
Each EDI record and each relationship value are represented using a unique
|
||||
database identifier. These database identifiers include the database unique
|
||||
ID, as a way to uniquely refer to any record within any OpenERP instance,
|
||||
without conflict.
|
||||
|
||||
For OpenERP records that have an existing "XML ID" (i.e. an entry in
|
||||
ir.model.data), the EDI unique identifier for this record will be made of
|
||||
"%s:%s" % (the database's UUID, the XML ID). The database's UUID MUST
|
||||
NOT contain a colon characters (this is guaranteed by the UUID algorithm).
|
||||
|
||||
For OpenERP records that have no existing "XML ID", a new one should be
|
||||
created during the EDI export. It is recommended that the generated XML ID
|
||||
contains a readable reference to the record model, plus a unique value that
|
||||
hides the database ID.
|
||||
"""
|
||||
model_data_pool = self.pool.get('ir.model.data')
|
||||
db_uuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
|
||||
|
||||
|
@ -202,14 +212,13 @@ class edi(object):
|
|||
xml_record = model_data_pool.browse(cr, uid, xml_record_id, context=context)
|
||||
uuid = '%s:%s' % (db_uuid, xml_record.name)
|
||||
else:
|
||||
xml_id = safe_unique_id(model, db_uuid)
|
||||
xml_id = safe_unique_id(db_uuid, record._name, record.id)
|
||||
uuid = '%s:%s' % (db_uuid, xml_id)
|
||||
xml_record_id = model_data_pool.create(cr, uid, {
|
||||
'name': xml_id,
|
||||
'model': record._name,
|
||||
'module': uuid,
|
||||
'res_id': record.id}, context=context)
|
||||
|
||||
return uuid
|
||||
|
||||
def edi_metadata(self, cr, uid, records, context=None):
|
||||
|
@ -250,9 +259,9 @@ class edi(object):
|
|||
})
|
||||
|
||||
|
||||
db_uuid = self.edi_xml_id(cr, uid, record, context=context)
|
||||
uuid = self.edi_xml_id(cr, uid, record, context=context)
|
||||
edi_dict = {
|
||||
'__id': db_uuid,
|
||||
'__id': uuid,
|
||||
'__last_update': False, #record.write_date, #TODO: convert into UTC
|
||||
}
|
||||
if not context.get('o2m_export'):
|
||||
|
@ -320,7 +329,7 @@ class edi(object):
|
|||
dict_list = []
|
||||
|
||||
for record in records:
|
||||
dict_list.append(self.edi_o2m(cr, uid, [record], context=None))
|
||||
dict_list.append(self.edi_m2o(cr, uid, [record], context=None))
|
||||
|
||||
return dict_list
|
||||
|
||||
|
|
|
@ -111,7 +111,8 @@ class res_partner(osv.osv):
|
|||
_order = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128, required=True, select=True),
|
||||
'opt_out':fields.boolean('Opt-out'),
|
||||
'opt_out':fields.boolean('Opt-out', help="If checked, this partner will not receive any automated email \
|
||||
notifications, such as the availability of invoices."),
|
||||
'date': fields.date('Date', select=1),
|
||||
'title': fields.many2one('res.partner.title','Partner Firm'),
|
||||
'parent_id': fields.many2one('res.partner','Parent Partner'),
|
||||
|
@ -151,7 +152,7 @@ class res_partner(osv.osv):
|
|||
'address': [{'type': 'default'}],
|
||||
'category_id': _default_category,
|
||||
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=c),
|
||||
'opt_out' : False
|
||||
'opt_out' : False,
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default={}, context={}):
|
||||
|
|
|
@ -94,57 +94,68 @@
|
|||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_agrolait" model="res.partner">
|
||||
<field name="name">Agrolait</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_8')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_c2c" model="res.partner">
|
||||
<field name="name">Camptocamp</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_10'), ref('res_partner_category_5')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_sednacom" model="res.partner">
|
||||
<field name="website">http://www.syleam.fr</field>
|
||||
<field name="name">Syleam</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_5')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_thymbra" model="res.partner">
|
||||
<field name="name">Thymbra</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_4')])]" name="category_id"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_desertic_hispafuentes" model="res.partner">
|
||||
<field name="name">Axelor</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_4')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_tinyatwork" model="res.partner">
|
||||
<field name="name">Tiny AT Work</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_5'), ref('res_partner_category_10')])]" name="category_id"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_2" model="res.partner">
|
||||
<field name="name">Bank Wealthy and sons</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_3" model="res.partner">
|
||||
<field name="name">China Export</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_4" model="res.partner">
|
||||
<field name="name">Distrib PC</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_5" model="res.partner">
|
||||
<field name="name">Ecole de Commerce de Liege</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_1')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_6" model="res.partner">
|
||||
<field name="name">Elec Import</field>
|
||||
|
@ -152,6 +163,7 @@
|
|||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_maxtor" model="res.partner">
|
||||
<field name="name">Maxtor</field>
|
||||
|
@ -160,6 +172,7 @@
|
|||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_seagate" model="res.partner">
|
||||
<field name="name">Seagate</field>
|
||||
|
@ -168,6 +181,7 @@
|
|||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="supplier">1</field>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_8" model="res.partner">
|
||||
<field name="website">http://mediapole.net</field>
|
||||
|
@ -175,6 +189,7 @@
|
|||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_1')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_9" model="res.partner">
|
||||
<field name="website">http://balmerinc.com</field>
|
||||
|
@ -184,12 +199,14 @@
|
|||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_1')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_10" model="res.partner">
|
||||
<field name="name">Tecsas</field>
|
||||
<field name="ean13">3020170000003</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_11" model="res.partner">
|
||||
<field name="name">Leclerc</field>
|
||||
|
@ -197,6 +214,7 @@
|
|||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_0')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_14" model="res.partner">
|
||||
<field name="name">Centrale d'achats BML</field>
|
||||
|
@ -205,6 +223,7 @@
|
|||
<field name="parent_id" ref="res_partner_10"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_11')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_15" model="res.partner">
|
||||
<field name="name">Magazin BML 1</field>
|
||||
|
@ -214,11 +233,13 @@
|
|||
<field name="user_id" ref="user_demo"/>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_11')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
<record id="res_partner_accent" model="res.partner">
|
||||
<field name="name">Université de Liège</field>
|
||||
<field eval="[(6, 0, [ref('res_partner_category_9')])]" name="category_id"/>
|
||||
<field name="address" eval="[]"/>
|
||||
<field name="opt_out" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -40,10 +40,8 @@ import openerp.tools as tools
|
|||
import openerp.modules
|
||||
|
||||
class edi(netsvc.ExportService):
|
||||
def exp_get_edi_document(self, edi_token, db_name=None):
|
||||
def exp_get_edi_document(self, edi_token, db_name):
|
||||
res = None
|
||||
if not db_name:
|
||||
db_name = getattr(threading.currentThread(), 'dbname', None)
|
||||
if db_name:
|
||||
cr = pooler.get_db(db_name).cursor()
|
||||
else:
|
||||
|
@ -62,8 +60,10 @@ class edi(netsvc.ExportService):
|
|||
pool = pooler.get_pool(db)
|
||||
edi_pool = pool.get('ir.edi.document')
|
||||
try:
|
||||
cr.autocommit(True)
|
||||
res = edi_pool.import_edi(cr, uid, edi_document=edi_document, context=context)
|
||||
cr.commit()
|
||||
except:
|
||||
cr.rollback()
|
||||
finally:
|
||||
cr.close()
|
||||
return res
|
||||
|
@ -74,8 +74,10 @@ class edi(netsvc.ExportService):
|
|||
pool = pooler.get_pool(db)
|
||||
edi_pool = pool.get('ir.edi.document')
|
||||
try:
|
||||
cr.autocommit(True)
|
||||
res = edi_pool.import_edi(cr, uid, edi_url=edi_url, context=context)
|
||||
cr.commit()
|
||||
except:
|
||||
cr.rollback()
|
||||
finally:
|
||||
cr.close()
|
||||
return res
|
||||
|
|
Loading…
Reference in New Issue