261 lines
10 KiB
Python
261 lines
10 KiB
Python
from base.controllers.main import View
|
|
import openerpweb
|
|
import StringIO
|
|
import csv
|
|
import xml.dom.minidom
|
|
import re
|
|
|
|
def export_csv(fields, result):
|
|
fp = StringIO.StringIO()
|
|
writer = csv.writer(fp, quoting=csv.QUOTE_ALL)
|
|
|
|
writer.writerow(fields)
|
|
|
|
for data in result:
|
|
row = []
|
|
for d in data:
|
|
if isinstance(d, basestring):
|
|
d = d.replace('\n',' ').replace('\t',' ')
|
|
try:
|
|
d = d.encode('utf-8')
|
|
except:
|
|
pass
|
|
if d is False: d = None
|
|
row.append(d)
|
|
writer.writerow(row)
|
|
|
|
fp.seek(0)
|
|
data = fp.read()
|
|
fp.close()
|
|
return data
|
|
|
|
def export_xls(fieldnames, table):
|
|
try:
|
|
import xlwt
|
|
except ImportError:
|
|
common.error(_('Import Error.'), _('Please install xlwt library to export to MS Excel.'))
|
|
|
|
workbook = xlwt.Workbook()
|
|
worksheet = workbook.add_sheet('Sheet 1')
|
|
|
|
for i, fieldname in enumerate(fieldnames):
|
|
worksheet.write(0, i, str(fieldname))
|
|
worksheet.col(i).width = 8000 # around 220 pixels
|
|
|
|
style = xlwt.easyxf('align: wrap yes')
|
|
|
|
for row_index, row in enumerate(table):
|
|
for cell_index, cell_value in enumerate(row):
|
|
cell_value = str(cell_value)
|
|
cell_value = re.sub("\r", " ", cell_value)
|
|
worksheet.write(row_index + 1, cell_index, cell_value, style)
|
|
|
|
|
|
fp = StringIO.StringIO()
|
|
workbook.save(fp)
|
|
fp.seek(0)
|
|
data = fp.read()
|
|
fp.close()
|
|
#return data.decode('ISO-8859-1')
|
|
return unicode(data, 'utf-8', 'replace')
|
|
|
|
def node_attributes(node):
|
|
attrs = node.attributes
|
|
|
|
if not attrs:
|
|
return {}
|
|
# localName can be a unicode string, we're using attribute names as
|
|
# **kwargs keys and python-level kwargs don't take unicode keys kindly
|
|
# (they blow up) so we need to ensure all keys are ``str``
|
|
return dict([(str(attrs.item(i).localName), attrs.item(i).nodeValue)
|
|
for i in range(attrs.length)])
|
|
|
|
def _fields_get_all(req, model, views, context=None):
|
|
|
|
if context is None:
|
|
context = {}
|
|
|
|
def parse(root, fields):
|
|
for node in root.childNodes:
|
|
if node.nodeName in ('form', 'notebook', 'page', 'group', 'tree', 'hpaned', 'vpaned'):
|
|
parse(node, fields)
|
|
elif node.nodeName=='field':
|
|
attrs = node_attributes(node)
|
|
name = attrs['name']
|
|
fields[name].update(attrs)
|
|
return fields
|
|
|
|
def get_view_fields(view):
|
|
return parse(
|
|
xml.dom.minidom.parseString(view['arch'].encode('utf-8')).documentElement,
|
|
view['fields'])
|
|
|
|
model_obj = req.session.model(model)
|
|
tree_view = model_obj.fields_view_get(views.get('tree', False), 'tree', context)
|
|
form_view = model_obj.fields_view_get(views.get('form', False), 'form', context)
|
|
fields = {}
|
|
fields.update(get_view_fields(tree_view))
|
|
fields.update(get_view_fields(form_view))
|
|
return fields
|
|
|
|
|
|
class Export(View):
|
|
_cp_path = "/base_export/export"
|
|
|
|
def fields_get(self, req, model):
|
|
Model = req.session.model(model)
|
|
fields = Model.fields_get(False, req.session.eval_context(req.context))
|
|
return fields
|
|
|
|
@openerpweb.jsonrequest
|
|
def get_fields(self, req, model, prefix='', name= '', field_parent=None, params={}):
|
|
import_compat = params.get("import_compat", False)
|
|
views_id = params.get("views_id", {})
|
|
|
|
fields = _fields_get_all(req, model, views=views_id, context=req.session.eval_context(req.context))
|
|
field_parent_type = params.get("parent_field_type",False)
|
|
|
|
if import_compat and field_parent_type and field_parent_type == "many2one":
|
|
fields = {}
|
|
|
|
fields.update({'id': {'string': 'ID'}, '.id': {'string': 'Database ID'}})
|
|
records = []
|
|
fields_order = fields.keys()
|
|
fields_order.sort(lambda x,y: -cmp(fields[x].get('string', ''), fields[y].get('string', '')))
|
|
|
|
for index, field in enumerate(fields_order):
|
|
value = fields[field]
|
|
record = {}
|
|
if import_compat and value.get('readonly', False):
|
|
ok = False
|
|
for sl in value.get('states', {}).values():
|
|
for s in sl:
|
|
ok = ok or (s==['readonly',False])
|
|
if not ok: continue
|
|
|
|
id = prefix + (prefix and '/'or '') + field
|
|
nm = name + (name and '/' or '') + value['string']
|
|
record.update(id=id, string= nm, action='javascript: void(0)',
|
|
target=None, icon=None, children=[], field_type=value.get('type',False), required=value.get('required', False))
|
|
records.append(record)
|
|
|
|
if len(nm.split('/')) < 3 and value.get('relation', False):
|
|
if import_compat:
|
|
ref = value.pop('relation')
|
|
cfields = self.fields_get(req, ref)
|
|
if (value['type'] == 'many2many'):
|
|
record['children'] = []
|
|
record['params'] = {'model': ref, 'prefix': id, 'name': nm}
|
|
|
|
elif value['type'] == 'many2one':
|
|
record['children'] = [id + '/id', id + '/.id']
|
|
record['params'] = {'model': ref, 'prefix': id, 'name': nm}
|
|
|
|
else:
|
|
cfields_order = cfields.keys()
|
|
cfields_order.sort(lambda x,y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', '')))
|
|
children = []
|
|
for j, fld in enumerate(cfields_order):
|
|
cid = id + '/' + fld
|
|
cid = cid.replace(' ', '_')
|
|
children.append(cid)
|
|
record['children'] = children or []
|
|
record['params'] = {'model': ref, 'prefix': id, 'name': nm}
|
|
else:
|
|
ref = value.pop('relation')
|
|
cfields = self.fields_get(req, ref)
|
|
cfields_order = cfields.keys()
|
|
cfields_order.sort(lambda x,y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', '')))
|
|
children = []
|
|
for j, fld in enumerate(cfields_order):
|
|
cid = id + '/' + fld
|
|
cid = cid.replace(' ', '_')
|
|
children.append(cid)
|
|
record['children'] = children or []
|
|
record['params'] = {'model': ref, 'prefix': id, 'name': nm}
|
|
|
|
records.reverse()
|
|
return records
|
|
|
|
@openerpweb.jsonrequest
|
|
def save_export_lists(self, req, name, model, field_list):
|
|
result = {'resource':model, 'name':name, 'export_fields': []}
|
|
for field in field_list:
|
|
result['export_fields'].append((0, 0, {'name': field}))
|
|
return req.session.model("ir.exports").create(result, req.session.eval_context(req.context))
|
|
|
|
@openerpweb.jsonrequest
|
|
def exist_export_lists(self, req, model):
|
|
export_model = req.session.model("ir.exports")
|
|
return export_model.read(export_model.search([('resource', '=', model)]), ['name'])
|
|
|
|
@openerpweb.jsonrequest
|
|
def delete_export(self, req, export_id):
|
|
req.session.model("ir.exports").unlink(export_id, req.session.eval_context(req.context))
|
|
return True
|
|
|
|
@openerpweb.jsonrequest
|
|
def namelist(self,req, model, export_id):
|
|
|
|
result = self.get_data(req, model, req.session.eval_context(req.context))
|
|
ir_export_obj = req.session.model("ir.exports")
|
|
ir_export_line_obj = req.session.model("ir.exports.line")
|
|
|
|
field = ir_export_obj.read(export_id)
|
|
fields = ir_export_line_obj.read(field['export_fields'])
|
|
|
|
name_list = {}
|
|
[name_list.update({field['name']: result.get(field['name'])}) for field in fields]
|
|
return name_list
|
|
|
|
def get_data(self, req, model, context=None):
|
|
ids = []
|
|
context = context or {}
|
|
fields_data = {}
|
|
proxy = req.session.model(model)
|
|
fields = self.fields_get(req, model)
|
|
if not ids:
|
|
f1 = proxy.fields_view_get(False, 'tree', context)['fields']
|
|
f2 = proxy.fields_view_get(False, 'form', context)['fields']
|
|
|
|
fields = dict(f1)
|
|
fields.update(f2)
|
|
fields.update({'id': {'string': 'ID'}, '.id': {'string': 'Database ID'}})
|
|
|
|
def rec(fields):
|
|
_fields = {'id': 'ID' , '.id': 'Database ID' }
|
|
def model_populate(fields, prefix_node='', prefix=None, prefix_value='', level=2):
|
|
fields_order = fields.keys()
|
|
fields_order.sort(lambda x,y: -cmp(fields[x].get('string', ''), fields[y].get('string', '')))
|
|
|
|
for field in fields_order:
|
|
fields_data[prefix_node+field] = fields[field]
|
|
if prefix_node:
|
|
fields_data[prefix_node + field]['string'] = '%s%s' % (prefix_value, fields_data[prefix_node + field]['string'])
|
|
st_name = fields[field]['string'] or field
|
|
_fields[prefix_node+field] = st_name
|
|
if fields[field].get('relation', False) and level>0:
|
|
fields2 = self.fields_get(req, fields[field]['relation'])
|
|
fields2.update({'id': {'string': 'ID'}, '.id': {'string': 'Database ID'}})
|
|
model_populate(fields2, prefix_node+field+'/', None, st_name+'/', level-1)
|
|
model_populate(fields)
|
|
return _fields
|
|
return rec(fields)
|
|
|
|
@openerpweb.jsonrequest
|
|
def export_data(self, req, model, fields, ids, domain, import_compat=False, export_format="csv", context=None):
|
|
context = req.session.eval_context(req.context)
|
|
modle_obj = req.session.model(model)
|
|
ids = ids or modle_obj.search(domain, context=context)
|
|
|
|
field = fields.keys()
|
|
result = modle_obj.export_data(ids, field , context).get('datas',[])
|
|
|
|
if not import_compat:
|
|
field = [val.strip() for val in fields.values()]
|
|
|
|
if export_format == 'xls':
|
|
return export_xls(field, result)
|
|
else:
|
|
return export_csv(field, result)
|