diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 9a05def5377..b28b24406fc 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -348,7 +348,7 @@ class orm_template(object): CONCURRENCY_CHECK_FIELD = '__last_update' - def read_group(self, cr, user, domain, fields, order, offset=0, limit=None, context=None): + def read_group(self, cr, user, ids, domain, fields, order, offset=0, limit=None, context=None): context = context or {} # compute the where, order by, limit and offset clauses (qu1, qu2, tables) = self._where_calc(cr, user, domain, context=context) @@ -359,8 +359,10 @@ class orm_template(object): if order: self._check_qorder(order) order_by = order or self._order - # sumof = ','.join(['sum('+field_name+')' for field_name,values in fields.items() if values['type'] in ('float','integer')]) # filter fields in args to only get float and int - sumof = ','.join([field_name for field_name,values in fields.items() if values['type'] in ('float','integer')]) # filter fields in args to only get float and int + + float_int_fields = list(field_name for field_name,values in fields.items() if values['type'] in ('float','integer')) + sumof = ','.join(map(lambda field_name:'sum('+field_name+') as '+field_name+'',float_int_fields)) # filter fields in args to only get float and int + # sumof = ','.join([field_name for field_name,values in fields.items() if values['type'] in ('float','integer')]) # filter fields in args to only get float and int limit_str = limit and ' limit %d' % limit or '' offset_str = offset and ' offset %d' % offset or '' @@ -370,18 +372,64 @@ class orm_template(object): if d1: qu1 = qu1 and qu1+' and '+d1 or ' where '+d1 qu2 += d2 - + if not ids: # execute the "main" query to fetch the ids we were searching for - cr.execute('select '+order_by+','+sumof+' from %s' % self._table + qu1+' group by '+order_by+','+sumof+limit_str+offset_str, qu2) - result = [] - for x in cr.fetchall(): - result.append({ - 'name':x[0], - 'domain':[(order_by,'=',x[0])], - 'fields': {x[0]:x[1]} - }) - print result - # return result + #cr.execute('select distinct('+order_by+'),'+self._table+'.id,'+sumof+' from ' + ','.join(tables) +qu1+' group by '+order_by +','+self._table+'.id'+limit_str+offset_str) + cr.execute('select distinct('+order_by+'),'+sumof+' from ' + ','.join(tables) +qu1+' group by '+order_by +limit_str+offset_str) + res = cr.fetchall() + uniq_ids = () + if fields[order_by]['type'] == 'many2one': + uniq_ids =tuple(set(map(lambda x:str(x[0]),res))) + if uniq_ids and len(uniq_ids) == 1: + cond = ' where id = %s'%(uniq_ids) + else: + cond = ' where id in %s'%(uniq_ids,) + qury = 'select name,id from ' + fields[order_by]['relation'].replace('.','_') + cond + cr.execute(qury) + uniq_order_by_res = dict(map(lambda x:(x[1],x[0]),cr.fetchall())) + result = [] + b = {} + for p_ids in uniq_ids: + cr.execute('select id from '+','.join(tables)+' where +'+order_by+' = %s'%(p_ids,)) + res2 = cr.fetchall() + for val in res2: + if int(p_ids) not in b: + b[int(p_ids)] = [val[0]] + else: + b[int(p_ids)].append(val[0]) + old_id = [] + for x in res: + if x[0] in old_id: + continue + temp = {'id':x[0],order_by:(x[0],uniq_order_by_res[x[0]]),'group_child':b[x[0]]} + for sum in float_int_fields: + temp[sum] = x[float_int_fields.index(sum)+1] + for field in fields.keys(): + if field not in temp: + temp[field] = False + old_id.append(x[0]) + result.append(temp) + return result + else: + query_fields = ','.join(fields.keys()) + result = [] + ids = ','.join(map(lambda x:str(x),ids)) + cr.execute('select id,' + query_fields+' from '+','.join(tables)+' where id in (%s)'%(ids)) + pos_orderby = fields.keys().index(order_by) + res1 = cr.fetchall() + if res1 and len(res1): + part = str(res1[0][pos_orderby+1]) + cr.execute('select id,name from %s where id = %s'%(fields[order_by]['relation'].replace('.','_'),part)) + partner = cr.fetchall()[0] + for val in res1: + temp = {'id':val[0],'group_child':[]} + for field in fields.keys(): + if field == order_by: + temp[field] = partner + continue + temp[field] = val[fields.keys().index(field)+1] + result.append(temp) + return result def _field_create(self, cr, context={}): cr.execute("SELECT id FROM ir_model WHERE model=%s", (self._name,)) @@ -2357,7 +2405,6 @@ class orm(orm_template): select = map(lambda x: isinstance(x,dict) and x['id'] or x, select) result = self._read_flat(cr, user, select, fields, context, load) - for r in result: for key, v in r.items(): if v == None: @@ -2386,6 +2433,8 @@ class orm(orm_template): context = {} if not ids: return [] + if len(ids) and type(ids[0])==tuple: + ids = list(set(map(lambda x:x[0],ids))) ids = map(lambda x:int(x), ids) if fields_to_read == None: fields_to_read = self._columns.keys() @@ -3201,8 +3250,6 @@ class orm(orm_template): ','.join(tables) +qu1 + limit_str + offset_str, qu2) res = cr.fetchall() return res[0][0] - - # execute the "main" query to fetch the ids we were searching for cr.execute('select %s.id from ' % self._table + ','.join(tables) +qu1+' order by '+order_by+limit_str+offset_str, qu2) res = cr.fetchall() return [x[0] for x in res]