[IMP] group by functionality
bzr revid: hda@tinyerp.com-20100120143132-oet7eoten9smy3m3
This commit is contained in:
parent
ce2a8bcb22
commit
95ea9b141b
224
bin/osv/orm.py
224
bin/osv/orm.py
|
@ -348,111 +348,8 @@ class orm_template(object):
|
|||
|
||||
CONCURRENCY_CHECK_FIELD = '__last_update'
|
||||
|
||||
def read_group(self, cr, user, ids, fields, groupby, context=None):
|
||||
context = context or {}
|
||||
if not ids:return
|
||||
|
||||
if fields[groupby]['type'] not in ('many2one','date','datetime'):
|
||||
raise Exception(_("Type Not supported for Group By: %s :Only many2one,date and datetime are supported ") %(fields[groupby]['type'],))
|
||||
|
||||
qu1 = ' where id in (' + ','.join([str(id) for id in ids]) + ')'
|
||||
qu2 = ''
|
||||
# construct a clause for the rules :
|
||||
d1, d2, d3 = self.pool.get('ir.rule').domain_get(cr, user, self._name)
|
||||
|
||||
if d1:
|
||||
qu1 = qu1 and qu1+' and '+d1 or ' where '+d1
|
||||
qu2 += d2
|
||||
|
||||
float_int_fields = list(field_name for field_name,values in fields.items() if values['type'] in ('float','integer'))
|
||||
sum = {}
|
||||
|
||||
cr.execute('select '+groupby+' from ' + self._table +qu1+' group by '+groupby+qu2)
|
||||
parent_res = cr.fetchall()
|
||||
try:
|
||||
parent_res = [(m[0],m[1]) for m in parent_res if m[0]]
|
||||
except:
|
||||
parent_res = [(m[0],) for m in parent_res if m[0]]
|
||||
groupby_ids = map(lambda x:x[0],parent_res)
|
||||
|
||||
groupby_name = {}
|
||||
child_ids_dict = {}
|
||||
|
||||
if fields[groupby]['type'] == 'many2one':
|
||||
groupby_name = dict(self.pool.get(fields[groupby]['relation']).name_get(cr,user,groupby_ids,context))
|
||||
|
||||
chqu1 =' where id in (' + ','.join([str(id) for id in ids]) + ') and '
|
||||
|
||||
# get child ids
|
||||
for parent_id in groupby_ids:
|
||||
cr.execute('select id from '+self._table+chqu1 +groupby+" = '%s'"%(parent_id,))
|
||||
child_ids = cr.fetchall()
|
||||
for val in child_ids:
|
||||
if parent_id not in child_ids_dict:
|
||||
child_ids_dict[parent_id] = [val[0]]
|
||||
else:
|
||||
child_ids_dict[parent_id].append(val[0])
|
||||
#create [{},{}] for parent ids i.e for group by field
|
||||
|
||||
result = []
|
||||
if fields[groupby]['type'] in ('date','datetime'):
|
||||
curr_date = datetime.date.today()
|
||||
yesterday = (curr_date - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
|
||||
lastweek = (curr_date + datetime.timedelta(weeks=-1)).strftime('%Y-%m-%d')
|
||||
date_result = {'Today':{'group_child':[]},'Yesterday':{'group_child':[]},
|
||||
'LastWeek':{'group_child':[]},'Old':{'group_child':[]}}
|
||||
for x in parent_res:
|
||||
db_date = x[0][:10]
|
||||
if db_date == curr_date.strftime('%Y-%m-%d'):
|
||||
date_format = 'Today'
|
||||
elif db_date == yesterday:
|
||||
date_format = 'Yesterday'
|
||||
elif (db_date < yesterday) and (db_date >= lastweek):
|
||||
date_format = 'LastWeek'
|
||||
else:
|
||||
date_format = 'Old'
|
||||
date_result[date_format].update({'id':None,groupby:date_format})
|
||||
date_result[date_format]['group_child'] += child_ids_dict[x[0]]
|
||||
float_int_sum = self.read(cr, user, child_ids_dict[x[0]], float_int_fields, context)
|
||||
for value in float_int_sum:
|
||||
for field,val in value.items():
|
||||
if field == 'id':continue
|
||||
if field not in sum:
|
||||
sum[field] = 0.0
|
||||
sum[field] += val
|
||||
for k,v in sum.items():
|
||||
date_result[date_format][k] = v
|
||||
sum = {}
|
||||
for key,val in date_result.items():
|
||||
if len(date_result[key]) == 1:
|
||||
del date_result[key]
|
||||
continue
|
||||
for field in fields.keys():
|
||||
if field not in val:
|
||||
val[field] = False
|
||||
if key in ('Today','Yesterday') and len(result):
|
||||
result.insert(0,val)
|
||||
else:
|
||||
result.insert(-1,val)
|
||||
return result
|
||||
else:
|
||||
for x in parent_res:
|
||||
parent_val_dict = {'id':str(x[0])+':Gpby',groupby:(x[0],groupby_name[x[0]]),'group_child':child_ids_dict[x[0]]}
|
||||
float_int_sum = self.read(cr, user, child_ids_dict[x[0]], float_int_fields, context)
|
||||
for value in float_int_sum:
|
||||
for field,val in value.items():
|
||||
if field == 'id':continue
|
||||
if field not in sum:
|
||||
sum[field] = 0.0
|
||||
sum[field] += val
|
||||
for k,v in sum.items():
|
||||
parent_val_dict[k] = v
|
||||
sum = {}
|
||||
for field in fields.keys():
|
||||
if field not in parent_val_dict:
|
||||
parent_val_dict[field] = False
|
||||
result.append(parent_val_dict)
|
||||
return result
|
||||
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None):
|
||||
raise _('The read_group method is not implemented on this object !')
|
||||
|
||||
def _field_create(self, cr, context={}):
|
||||
cr.execute("SELECT id FROM ir_model WHERE model=%s", (self._name,))
|
||||
|
@ -1899,6 +1796,123 @@ class orm(orm_template):
|
|||
_table = None
|
||||
_protected = ['read','write','create','default_get','perm_read','unlink','fields_get','fields_view_get','search','name_get','distinct_field_get','name_search','copy','import_data','search_count', 'exists']
|
||||
|
||||
def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None):
|
||||
context = context or {}
|
||||
|
||||
if fields[groupby]['type'] not in ('many2one','date','datetime'):
|
||||
raise Exception(_("Type Not supported for Group By: %s :Only many2one,date and datetime are supported ") %(fields[groupby]['type'],))
|
||||
|
||||
self.pool.get('ir.model.access').check(cr, uid, self._name, 'read', context=context)
|
||||
if not fields:
|
||||
fields = self._columns.keys() + self._inherit_fields.keys()
|
||||
|
||||
# compute the where, order by, limit and offset clauses
|
||||
(qu1, qu2, tables) = self._where_calc(cr, uid, domain, context=context)
|
||||
dom = self.pool.get('ir.rule').domain_get(cr, uid, self._name, context=context)
|
||||
qu1 = qu1 + dom[0]
|
||||
qu2 = qu2 + dom[1]
|
||||
for t in dom[2]:
|
||||
if t not in tables:
|
||||
tables.append(t)
|
||||
if len(qu1):
|
||||
qu1 = ' where '+string.join(qu1, ' and ')
|
||||
else:
|
||||
qu1 = ''
|
||||
# limit_str = limit and ' limit %d' % limit or ''
|
||||
# offset_str = offset and ' offset %d' % offset or ''
|
||||
|
||||
float_int_fields = list(field_name for field_name,values in fields.items() if values['type'] in ('float','integer'))
|
||||
sum = {}
|
||||
flist = groupby
|
||||
for f in float_int_fields:
|
||||
if f not in ['id','sequence']:
|
||||
flist += ',sum('+f+') as '+f
|
||||
|
||||
cr.execute('select '+flist+' from ' + self._table +qu1+' group by '+groupby,qu2)
|
||||
parent_res = cr.fetchall()
|
||||
try:
|
||||
parent_res = [(m[0],m[1]) for m in parent_res if m[0]]
|
||||
except:
|
||||
parent_res = [(m[0],) for m in parent_res if m[0]]
|
||||
groupby_ids = map(lambda x:x[0],parent_res)
|
||||
|
||||
groupby_name = {}
|
||||
child_ids_dict = {}
|
||||
|
||||
if fields[groupby]['type'] == 'many2one':
|
||||
groupby_name = dict(self.pool.get(fields[groupby]['relation']).name_get(cr,uid,groupby_ids,context))
|
||||
|
||||
# get child ids
|
||||
for parent_id in groupby_ids:
|
||||
cr.execute('select id from '+self._table+qu1 +' AND '+groupby+" = '%s'",qu2+[parent_id])
|
||||
child_ids = cr.fetchall()
|
||||
for val in child_ids:
|
||||
if parent_id not in child_ids_dict:
|
||||
child_ids_dict[parent_id] = [val[0]]
|
||||
else:
|
||||
child_ids_dict[parent_id].append(val[0])
|
||||
#create [{},{}] for parent ids i.e for group by field
|
||||
|
||||
result = []
|
||||
if fields[groupby]['type'] in ('date','datetime'):
|
||||
curr_date = datetime.date.today()
|
||||
yesterday = (curr_date - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
|
||||
lastweek = (curr_date + datetime.timedelta(weeks=-1)).strftime('%Y-%m-%d')
|
||||
date_result = {'Today':{'group_child':[]},'Yesterday':{'group_child':[]},
|
||||
'LastWeek':{'group_child':[]},'Old':{'group_child':[]}}
|
||||
for x in parent_res:
|
||||
db_date = x[0][:10]
|
||||
if db_date == curr_date.strftime('%Y-%m-%d'):
|
||||
date_format = 'Today'
|
||||
elif db_date == yesterday:
|
||||
date_format = 'Yesterday'
|
||||
elif (db_date < yesterday) and (db_date >= lastweek):
|
||||
date_format = 'LastWeek'
|
||||
else:
|
||||
date_format = 'Old'
|
||||
date_result[date_format].update({'id':None,groupby:date_format})
|
||||
date_result[date_format]['group_child'] += child_ids_dict[x[0]]
|
||||
float_int_sum = self.read(cr, uid, child_ids_dict[x[0]], float_int_fields, context)
|
||||
for value in float_int_sum:
|
||||
for field,val in value.items():
|
||||
if field in ['id','sequence']:continue
|
||||
if field not in sum:
|
||||
sum[field] = 0.0
|
||||
sum[field] += val
|
||||
for k,v in sum.items():
|
||||
date_result[date_format][k] = v
|
||||
sum = {}
|
||||
for key,val in date_result.items():
|
||||
if len(date_result[key]) == 1:
|
||||
del date_result[key]
|
||||
continue
|
||||
for field in fields.keys():
|
||||
if field not in val:
|
||||
val[field] = False
|
||||
if key in ('Today','Yesterday') and len(result):
|
||||
result.insert(0,val)
|
||||
else:
|
||||
result.insert(-1,val)
|
||||
return result
|
||||
else:
|
||||
for x in parent_res:
|
||||
parent_val_dict = {'id':str(x[0])+':Gpby',groupby:(x[0],groupby_name[x[0]]),'group_child':child_ids_dict[x[0]]}
|
||||
float_int_sum = self.read(cr, uid, child_ids_dict[x[0]], float_int_fields, context)
|
||||
for value in float_int_sum:
|
||||
for field,val in value.items():
|
||||
if field == 'id':continue
|
||||
if field not in sum:
|
||||
sum[field] = 0.0
|
||||
sum[field] += val
|
||||
for k,v in sum.items():
|
||||
parent_val_dict[k] = v
|
||||
sum = {}
|
||||
for field in fields.keys():
|
||||
if field not in parent_val_dict:
|
||||
parent_val_dict[field] = False
|
||||
result.append(parent_val_dict)
|
||||
return result
|
||||
|
||||
def _parent_store_compute(self, cr):
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel('orm', netsvc.LOG_INFO, 'Computing parent left and right for table %s...' % (self._table, ))
|
||||
|
|
Loading…
Reference in New Issue