def get_color(self, result): color_ids = {} for res in result: color_ids[res["id"]] = "black" res_lower = {} for key, vals in res.iteritems(): if self.fields_type.get(key, False) and vals != "False": type = self.fields_type[key]["type"] if type == "date": res_lower[key] = datetime_util.local_to_server_timestamp( vals, user_locale_format.get_date_format(), DT_FORMAT, tz_offset=False ) continue elif type == "datetime": res_lower[key] = datetime_util.local_to_server_timestamp( vals, user_locale_format.get_datetime_format(True), DT_FORMAT ) continue if isinstance(vals, (str, unicode)): res_lower[key] = vals.lower() else: res_lower[key] = vals for color, expt in self.colors.iteritems(): val = False for cond in expt: if isinstance(cond, basestring): val = tools.expr_eval(cond, res_lower) if val: color_ids[res_lower["id"]] = color break if val: break return color_ids
def display(self, models): datas = [] self.axis = copy.copy(self.old_axis) group_by = self.widget.screen.context.get('group_by', False) if group_by: if not self.key: del self.widget.screen.context['group_by'] self.key = True self.widget.screen.search_filter() ## TODO: Check why was this needed ? models = self.widget.screen.models self.widget.screen.context['group_by'] = group_by self.key = False self.axis[0] = group_by[0] self.axis_data[group_by[0]] = {} # This is to get the missing field. if the field is not available in the graph view # for use case :graph view loaded directly from a dashboard and user executes groupby if self.axis[0] not in models.mfields: missing_gb_field = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'fields_get', [self.axis[0]], {}) if missing_gb_field: models.add_fields(missing_gb_field, models) for m in models: res = {} for x in self.axis_data.keys(): if not self.axis_data[x]: self.axis_data[x] = self.fields[x] field_val = m[x].get_client(m) if self.fields[x]['type'] in ('many2one', 'char','time','text'): res[x] = field_val and str(field_val) or _('Undefined') elif self.fields[x]['type'] == 'selection': selection = dict(m[x].attrs['selection']) if field_val: val = str(field_val) res[x] = selection.get(val, val) else: res[x] = _('Undefined') elif self.fields[x]['type'] == 'date': if field_val: res[x] = datetime_util.server_to_local_timestamp(field_val, DT_FORMAT, user_locale_format.get_date_format(), tz_offset=False) else: res[x] = _('Undefined') elif self.fields[x]['type'] == 'datetime': if field_val: res[x] = datetime_util.server_to_local_timestamp(field_val, DHM_FORMAT, user_locale_format.get_datetime_format(True)) else: res[x] = _('Undefined') else: res[x] = field_val and float(field_val) or 0.0 datas.append(res) tinygraph.tinygraph(self._subplot, self.attrs.get('type', 'pie'), self.axis, self.axis_data, datas, axis_group_field=self.axis_group, orientation=self.attrs.get('orientation', 'vertical')) # the draw function may generate exception but it is not a problem as it will be redraw latter try: self._subplot.draw(None) #XXX it must have some better way to force the redraw but this one works self._canvas.queue_resize() except: pass
def _read(self, ids, fields): c = {} c.update(rpc.session.context) c.update(self.context) if self.invisible_fields: fields += self.invisible_fields try: res_ids = rpc.session.rpc_exec_auth_try("/object", "execute", self.view["model"], "read", ids, fields, c) except: res_ids = [] for id in ids: val = {"id": id} for f in fields: if self.fields_type[f]["type"] in ("one2many", "many2many"): val[f] = [] else: val[f] = "" res_ids.append(val) for field in self.fields + self.invisible_fields: for x in res_ids: if self.fields_type[field]["type"] in ("date",): display_format = user_locale_format.get_date_format() if x[field]: x[field] = datetime_util.server_to_local_timestamp( x[field], DT_FORMAT, display_format, tz_offset=False ) else: x[field] = str(x[field]) elif self.fields_type[field]["type"] in ("datetime",): display_format = user_locale_format.get_datetime_format(True) if x[field]: x[field] = datetime_util.server_to_local_timestamp(x[field], DHM_FORMAT, display_format) else: x[field] = str(x[field]) elif self.fields_type[field]["type"] in ("one2one", "many2one"): if x[field]: x[field] = x[field][1] elif self.fields_type[field]["type"] in ("selection"): if x[field]: x[field] = dict(self.fields_type[field]["selection"]).get(x[field], "") elif self.fields_type[field]["type"] in ("float",): interger, digit = self.fields_type[field].get("digits", (16, 2)) x[field] = user_locale_format.format("%." + str(digit) + "f", x[field] or 0.0) elif self.fields_type[field]["type"] in ("integer",): x[field] = int(user_locale_format.format("%d", int(x[field]) or 0)) elif self.fields_type[field]["type"] in ("float_time",): val = datetime_util.float_time_convert(x[field]) if x[field] < 0: val = "-" + val x[field] = val return res_ids
def __init__(self, name, parent, attrs={},screen=None): super(datetime, self).__init__(name, parent, attrs, screen) self.widget = gtk.HBox(spacing=5) self.format = user_locale_format.get_datetime_format(True) self.widget1 = date_widget.ComplexEntry(self.format, spacing=3) self.entry1 = self.widget1.widget self.entry1.set_property('width-chars', 19) self.entry1.set_property('activates_default', True) self.entry1.connect('key_press_event', self.sig_key_press, self.entry1, parent) self.entry1.set_tooltip_text(_('Start date')) self.widget.pack_start(self.widget1, expand=False, fill=True) self.eb1 = gtk.EventBox() self.eb1.set_tooltip_text(_('Open the calendar widget')) self.eb1.set_events(gtk.gdk.BUTTON_PRESS) self.eb1.connect('button_press_event', self.cal_open, self.entry1, parent) img = gtk.Image() img.set_from_stock('gtk-zoom-in', gtk.ICON_SIZE_MENU) img.set_alignment(0.5, 0.5) self.eb1.add(img) self.widget.pack_start(self.eb1, expand=False, fill=False) self.widget.pack_start(gtk.Label('-'), expand=False, fill=False) self.widget2 = date_widget.ComplexEntry(self.format, spacing=3) self.entry2 = self.widget2.widget self.entry2.set_property('width-chars', 19) self.entry2.set_property('activates_default', True) self.entry2.connect('key_press_event', self.sig_key_press, self.entry2, parent) self.entry2.set_tooltip_text(_('End date')) self.widget.pack_start(self.widget2, expand=False, fill=True) self.eb2 = gtk.EventBox() self.eb2.set_tooltip_text(_('Open the calendar widget')) self.eb2.set_events(gtk.gdk.BUTTON_PRESS) self.eb2.connect('button_press_event', self.cal_open, self.entry2, parent) img = gtk.Image() img.set_from_stock('gtk-zoom-in', gtk.ICON_SIZE_MENU) img.set_alignment(0.5, 0.5) self.eb2.add(img) self.widget.pack_start(self.eb2, expand=False, fill=False) if self.default_search: try: date = tools.datetime_util.strptime(self.default_search, DHM_FORMAT) self.entry1.set_text(date.strftime(self.format)) except: pass
def get_color(self, result): color_ids = {} for res in result: color_ids[res['id']] = 'black' res_lower = {} for key, vals in res.iteritems(): if self.fields_type.get(key, False) and vals != 'False': type = self.fields_type[key]['type'] if type == 'date': res_lower[ key] = datetime_util.local_to_server_timestamp( vals, user_locale_format.get_date_format(), DT_FORMAT, tz_offset=False) continue elif type == 'datetime': res_lower[ key] = datetime_util.local_to_server_timestamp( vals, user_locale_format.get_datetime_format(True), DT_FORMAT) continue if isinstance(vals, (str, unicode)): res_lower[key] = vals.lower() else: res_lower[key] = vals for color, expt in self.colors.iteritems(): val = False for cond in expt: if isinstance(cond, basestring): val = tools.expr_eval(cond, res_lower) if val: color_ids[res_lower['id']] = color break if val: break return color_ids
def __init__(self, window, parent, model, attrs={}, label=None): interface.widget_interface.__init__(self, window, parent, model, attrs=attrs, label_ebox=label) self.format = user_locale_format.get_datetime_format(True) self.fmt_length = len((DT.now()).strftime(self.format)) self.widget = date_widget.ComplexEntry(self.format, spacing=3) self.entry = self.widget.widget self.entry.set_property('activates_default', True) self.entry.connect('key_press_event', self.sig_key_press) self.entry.connect('populate-popup', self._menu_open) self.entry.connect('focus-in-event', lambda x,y: self._focus_in()) self.entry.connect('focus-out-event', lambda x,y: self._focus_out()) eb = gtk.EventBox() eb.set_tooltip_text(_('Open the calendar widget')) eb.set_events(gtk.gdk.BUTTON_PRESS) eb.connect('button_press_event', self.cal_open, model, self._window) img = gtk.Image() img.set_from_stock('gtk-zoom-in', gtk.ICON_SIZE_MENU) img.set_alignment(0.5, 0.5) eb.add(img) self.widget.pack_start(eb, expand=False, fill=False) self.readonly=False
def __init__(self, *args): self.server_format = '%Y-%m-%d %H:%M:%S' self.display_format = user_locale_format.get_datetime_format(True) self.fmt_length = len((DT.datetime.now()).strftime(self.display_format)) super(Datetime, self).__init__(*args)
def display(self, models): datas = [] self.axis = copy.copy(self.old_axis) group_by = self.widget.screen.context.get("group_by", False) if group_by: if not self.key: del self.widget.screen.context["group_by"] self.key = True self.widget.screen.search_filter() models = self.widget.screen.models self.widget.screen.context["group_by"] = group_by self.axis[0] = group_by[0] self.axis_data[group_by[0]] = {} # This is to get the missing field. if the field is not available in the graph view # for use case :graph view loaded directly from a dashboard and user executes groupby if self.axis[0] not in models.mfields: missing_gb_field = rpc.session.rpc_exec_auth( "/object", "execute", self.model, "fields_get", [self.axis[0]], {} ) if missing_gb_field: models.add_fields(missing_gb_field, models) for m in models: res = {} for x in self.axis_data.keys(): if not self.axis_data[x]: self.axis_data[x] = self.fields[x] field_val = m[x].get_client(m) if self.fields[x]["type"] in ("many2one", "char", "time", "text"): res[x] = field_val and str(field_val) or "Undefined" elif self.fields[x]["type"] == "selection": selection = dict(m[x].attrs["selection"]) if field_val: val = str(field_val) res[x] = selection.get(val, val) else: res[x] = "Undefined" elif self.fields[x]["type"] == "date": if field_val: res[x] = datetime_util.server_to_local_timestamp( field_val, DT_FORMAT, user_locale_format.get_date_format(), tz_offset=False ) else: res[x] = "Undefined" elif self.fields[x]["type"] == "datetime": if field_val: res[x] = datetime_util.server_to_local_timestamp( field_val, DHM_FORMAT, user_locale_format.get_datetime_format(True) ) else: res[x] = "Undefined" else: res[x] = field_val and float(field_val) or 0.0 datas.append(res) tinygraph.tinygraph( self._subplot, self.attrs.get("type", "pie"), self.axis, self.axis_data, datas, axis_group_field=self.axis_group, orientation=self.attrs.get("orientation", "vertical"), ) # the draw function may generate exception but it is not a problem as it will be redraw latter try: self._subplot.draw(None) # XXX it must have some better way to force the redraw but this one works self._canvas.queue_resize() except: pass
def tinygraph(subplot, type='pie', axis={}, axis_data={}, datas=[], axis_group_field={}, orientation='horizontal', overlap=1.0): subplot.clear() operators = { '+': lambda x, y: x + y, '*': lambda x, y: x * y, 'min': lambda x, y: min(x, y), 'max': lambda x, y: max(x, y), '**': lambda x, y: x**y } axis_group = {} dic_lable = {} data_axis = [] data_all = {} axis_type = axis_data[axis[0]].get('type', False) for field in axis[1:]: data_all = {} for d in datas: group_eval = ','.join(map(lambda x: d[x], axis_group_field.keys())) axis_group[group_eval] = 1 data_all.setdefault(d[axis[0]], {}) dic_lable[d[axis[0]]] = 1 if group_eval in data_all[d[axis[0]]]: oper = operators[axis_data[field].get('operator', '+')] data_all[d[axis[0]]][group_eval] = oper( data_all[d[axis[0]]][group_eval], d[field]) else: data_all[d[axis[0]]][group_eval] = d[field] data_axis.append(data_all) axis_group = axis_group.keys() axis_group.sort() axis_lable = dic_lable.keys() axis_lable.sort() tmp = {} except_tmp = [] if axis_type == 'datetime': for lable in axis_lable: try: tmp[lable] = datetime.strptime( lable, user_locale_format.get_datetime_format(True)) except: except_tmp += [lable] axis_lable = sorted(tmp, key=tmp.__getitem__) + except_tmp if axis_type == 'date': for lable in axis_lable: try: tmp[lable] = datetime.strptime( lable, user_locale_format.get_date_format()) except: except_tmp += [lable] axis_lable = sorted(tmp, key=tmp.__getitem__) + except_tmp if not datas: return False font_property = FontProperties(size=8) if type == 'pie': labels = tuple(data_all.keys()) value = tuple( map( lambda x: reduce(lambda x, y=0: x + y, data_all[x].values(), 0 ), labels)) explode = map(lambda x: (x % 4 == 2) and 0.06 or 0.0, range(len(value))) colors = choice_colors(len(value)) aa = subplot.pie(value, autopct='%1.1f%%', shadow=True, explode=explode, colors=colors) labels = map(lambda x: x.split('/')[-1], labels) subplot.legend(aa[0], labels, shadow=True, loc='best', prop=font_property) elif type == 'bar': n = len(axis) - 1 gvalue = [] gvalue2 = [] if float(n): width = 0.9 / (float(n)) else: width = 0.9 ind = map(lambda x: x + width * n / 2, xrange(len(axis_lable))) if orientation == 'horizontal': subplot.set_yticks(ind) subplot.set_yticklabels(tuple(axis_lable), visible=True, ha='right', size=8) subplot.xaxis.grid(True, 'major', linestyle='-', color='gray') else: subplot.set_xticks(ind) subplot.set_xticklabels(tuple(axis_lable), visible=True, ha='right', size=8, rotation='vertical') subplot.yaxis.grid(True, 'major', linestyle='-', color='gray') colors = choice_colors(max(n, len(axis_group))) for i in range(n): datas = data_axis[i] ind = map( lambda x: x + width * i * overlap + ((1.0 - overlap) * n * width) / 4, xrange(len(axis_lable))) #ind = map(lambda x: x, xrange(len(keys))) yoff = map(lambda x: 0.0, axis_lable) for y in range(len(axis_group)): value = [datas[x].get(axis_group[y], 0.0) for x in axis_lable] if len(axis_group) > 1: color = colors[y] else: color = colors[i] if orientation == 'horizontal': aa = subplot.barh(ind, tuple(value), width, left=yoff, color=color, edgecolor="#333333")[0] subplot.set_ylim(0, len(ind)) else: aa = subplot.bar(ind, tuple(value), width, bottom=yoff, color=color, edgecolor="#333333")[0] subplot.set_xlim(0, len(ind)) gvalue2.append(aa) for j in range(len(yoff)): yoff[j] += value[j] gvalue.append(aa) if True: if len(axis_group) > 1: axis_group = map(lambda x: x.split('/')[-1], axis_group) gvalue2 = map(lambda x: gvalue2[x], range(len(axis_group))) subplot.legend(gvalue2, axis_group, shadow=True, loc='best', prop=font_property) else: t1 = [axis_data[x]['string'] for x in axis[1:]] subplot.legend(gvalue, t1, shadow=True, loc='best', prop=font_property) else: pass else: raise Exception, 'Graph type ' + type + ' does not exist !'
def __init__(self, *args): self.server_format = '%Y-%m-%d %H:%M:%S' self.display_format = user_locale_format.get_datetime_format(True) self.fmt_length = len( (DT.datetime.now()).strftime(self.display_format)) super(Datetime, self).__init__(*args)
def _read(self, ids, fields): c = {} c.update(rpc.session.context) c.update(self.context) if self.invisible_fields: fields += self.invisible_fields try: res_ids = rpc.session.rpc_exec_auth_try('/object', 'execute', self.view['model'], 'read', ids, fields, c) except: res_ids = [] for id in ids: val = {'id': id} for f in fields: if self.fields_type[f]['type'] in ('one2many', 'many2many'): val[f] = [] else: val[f] = '' res_ids.append(val) for field in self.fields + self.invisible_fields: for x in res_ids: if self.fields_type[field]['type'] in ('date', ): display_format = user_locale_format.get_date_format() if x[field]: x[field] = datetime_util.server_to_local_timestamp( x[field], DT_FORMAT, display_format, tz_offset=False) else: x[field] = str(x[field]) elif self.fields_type[field]['type'] in ('datetime', ): display_format = user_locale_format.get_datetime_format( True) if x[field]: x[field] = datetime_util.server_to_local_timestamp( x[field], DHM_FORMAT, display_format) else: x[field] = str(x[field]) elif self.fields_type[field]['type'] in ('one2one', 'many2one'): if x[field]: x[field] = x[field][1] elif self.fields_type[field]['type'] in ('selection'): if x[field]: x[field] = dict( self.fields_type[field]['selection']).get( x[field], '') elif self.fields_type[field]['type'] in ('float', ): interger, digit = self.fields_type[field].get( 'digits', (16, 2)) x[field] = user_locale_format.format( '%.' + str(digit) + 'f', x[field] or 0.0) elif self.fields_type[field]['type'] in ('integer', ): x[field] = int( user_locale_format.format('%d', int(x[field]) or 0)) elif self.fields_type[field]['type'] in ('float_time', ): val = datetime_util.float_time_convert(x[field]) if x[field] < 0: val = '-' + val x[field] = val return res_ids
def display(self, models): datas = [] self.axis = copy.copy(self.old_axis) group_by = self.widget.screen.context.get('group_by', False) if group_by: if not self.key: del self.widget.screen.context['group_by'] self.key = True self.widget.screen.search_filter() models = self.widget.screen.models self.widget.screen.context['group_by'] = group_by self.axis[0] = group_by[0] self.axis_data[group_by[0]] = {} # This is to get the missing field. if the field is not available in the graph view # for use case :graph view loaded directly from a dashboard and user executes groupby if self.axis[0] not in models.mfields: missing_gb_field = rpc.session.rpc_exec_auth( '/object', 'execute', self.model, 'fields_get', [self.axis[0]], {}) if missing_gb_field: models.add_fields(missing_gb_field, models) for m in models: res = {} for x in self.axis_data.keys(): if not self.axis_data[x]: self.axis_data[x] = self.fields[x] field_val = m[x].get_client(m) if self.fields[x]['type'] in ('many2one', 'char', 'time', 'text'): res[x] = field_val and str(field_val) or 'Undefined' elif self.fields[x]['type'] == 'selection': selection = dict(m[x].attrs['selection']) if field_val: val = str(field_val) res[x] = selection.get(val, val) else: res[x] = 'Undefined' elif self.fields[x]['type'] == 'date': if field_val: res[x] = datetime_util.server_to_local_timestamp( field_val, DT_FORMAT, user_locale_format.get_date_format(), tz_offset=False) else: res[x] = 'Undefined' elif self.fields[x]['type'] == 'datetime': if field_val: res[x] = datetime_util.server_to_local_timestamp( field_val, DHM_FORMAT, user_locale_format.get_datetime_format(True)) else: res[x] = 'Undefined' else: res[x] = field_val and float(field_val) or 0.0 datas.append(res) tinygraph.tinygraph(self._subplot, self.attrs.get('type', 'pie'), self.axis, self.axis_data, datas, axis_group_field=self.axis_group, orientation=self.attrs.get('orientation', 'vertical')) # the draw function may generate exception but it is not a problem as it will be redraw latter try: self._subplot.draw(None) #XXX it must have some better way to force the redraw but this one works self._canvas.queue_resize() except: pass
def tinygraph(subplot, type='pie', axis={}, axis_data={}, datas=[], axis_group_field={}, orientation='horizontal', overlap=1.0): subplot.clear() operators = { '+': lambda x,y: x+y, '*': lambda x,y: x*y, 'min': lambda x,y: min(x,y), 'max': lambda x,y: max(x,y), '**': lambda x,y: x**y } axis_group = {} dic_lable = {} data_axis = [] data_all = {} axis_type = axis_data[axis[0]].get('type',False) for field in axis[1:]: data_all = {} for d in datas: group_eval = ','.join(map(lambda x: d[x], axis_group_field.keys())) axis_group[group_eval] = 1 data_all.setdefault(d[axis[0]], {}) dic_lable[d[axis[0]]] = 1 if group_eval in data_all[d[axis[0]]]: oper = operators[axis_data[field].get('operator', '+')] data_all[d[axis[0]]][group_eval] = oper(data_all[d[axis[0]]][group_eval], d[field]) else: data_all[d[axis[0]]][group_eval] = d[field] data_axis.append(data_all) axis_group = axis_group.keys() axis_group.sort() axis_lable = dic_lable.keys() axis_lable.sort() tmp = {} except_tmp = [] if axis_type == 'datetime': for lable in axis_lable: try: tmp[lable] = datetime.strptime(lable, user_locale_format.get_datetime_format(True)) except: except_tmp += [lable] axis_lable = sorted(tmp, key=tmp.__getitem__) + except_tmp if axis_type == 'date': for lable in axis_lable: try: tmp[lable] = datetime.strptime(lable, user_locale_format.get_date_format()) except: except_tmp += [lable] axis_lable = sorted(tmp, key=tmp.__getitem__) + except_tmp if not datas: return False font_property = FontProperties(size=8) if type == 'pie': labels = tuple(data_all.keys()) value = tuple(map(lambda x: reduce(lambda x,y=0: x+y, data_all[x].values(), 0), labels)) explode = map(lambda x: (x%4==2) and 0.06 or 0.0,range(len(value))) colors = choice_colors(len(value)) aa = subplot.pie(value, autopct='%1.1f%%', shadow=True, explode=explode, colors=colors) labels = map(lambda x: x.split('/')[-1], labels) subplot.legend(aa[0], labels, shadow = True, loc = 'best', prop = font_property) elif type == 'bar': n = len(axis)-1 gvalue = [] gvalue2 = [] if float(n): width = 0.9 / (float(n)) else: width = 0.9 ind = map(lambda x: x+width*n/2, xrange(len(axis_lable))) if orientation=='horizontal': subplot.set_yticks(ind) subplot.set_yticklabels(tuple(axis_lable), visible=True, ha='right', size=8) subplot.xaxis.grid(True,'major',linestyle='-',color='gray') subplot.xaxis.set_major_formatter(FormatStrFormatter('%0.0f')) else: subplot.set_xticks(ind) subplot.set_xticklabels(tuple(axis_lable), visible=True, ha='right', size=8, rotation='vertical') subplot.yaxis.grid(True,'major',linestyle='-',color='gray') subplot.yaxis.set_major_formatter(FormatStrFormatter('%0.0f')) colors = choice_colors(max(n,len(axis_group))) for i in range(n): datas = data_axis[i] ind = map(lambda x: x+width*i*overlap+((1.0-overlap)*n*width)/4, xrange(len(axis_lable))) #ind = map(lambda x: x, xrange(len(keys))) yoff = map(lambda x:0.0, axis_lable) for y in range(len(axis_group)): value = [ datas[x].get(axis_group[y],0.0) for x in axis_lable] if len(axis_group)>1: color = colors[y] else: color = colors[i] if orientation=='horizontal': aa = subplot.barh(ind, tuple(value), width, left=yoff, color=color, edgecolor="#333333")[0] subplot.set_ylim(0, len(ind)) else: aa = subplot.bar(ind, tuple(value), width, bottom=yoff, color=color, edgecolor="#333333")[0] subplot.set_xlim(0, len(ind)) gvalue2.append(aa) for j in range(len(yoff)): yoff[j]+=value[j] gvalue.append(aa) if True: if len(axis_group)>1: axis_group = map(lambda x: x.split('/')[-1], axis_group) gvalue2 = map(lambda x:gvalue2[x], range(len(axis_group))) subplot.legend(gvalue2,axis_group,shadow=True,loc='best',prop = font_property) else: t1 = [ axis_data[x]['string'] for x in axis[1:]] subplot.legend(gvalue,t1,shadow=True,loc='best',prop = font_property) else: pass else: raise Exception, 'Graph type '+type+' does not exist !'