def __init__(self, user, *args, **kwargs): self.report_id = None if 'report_id' in kwargs: self.report_id = kwargs.pop('report_id') if 'chart_id' in kwargs: self.chart_id = kwargs.pop('chart_id') chart = get_object_or_404(Chart, pk=self.chart_id) self.report_id = chart.report_id super(ChartForm, self).__init__(*args, **kwargs) if not self.report_id: return report = get_object_or_404(Report, pk=self.report_id) chart = None if hasattr(self, 'chart_id'): chart = get_object_or_404(Chart, pk=self.chart_id) model = loads(report.model) object = model.name object = object.split('.') module_name = object[0] + '.' + object[1] + '.' + object[2] import_name = object[3] module = __import__( module_name, globals(), locals(), [import_name], -1) classobj = getattr(module, import_name) unfiltered_set = classobj.objects.exclude(trash=True) set = [] for s in unfiltered_set: filtered = False for field in model.fields: if field.filters and str(getattr(s, field.name)) not in field.filters: filtered = True if not filtered: set.append(s) # perhaps do type checking on a setting list of types (for each type) self.fields['grouping'].choices = [('', '--------')] # Check for group groupname = None groups = None for field in model.fields: self.fields['grouping'].choices.append( (str(field.name), str(field.name).replace('_', ' ').title())) if field.groupby == 1: self.fields['grouping'].initial = str(field.name) if chart: options = loads(chart.options) for f in options: if f in self.fields: self.fields[f].initial = options[f]
def report_group(request, report_id, field_name, response_format='html'): "View to Group by a given field in a report" t = get_object_or_404(Report, pk=report_id) if not request.user.profile.has_permission(t, mode='w'): return user_denied(request, message="You don't have access to this Report") model = loads(t.model) # Check if this field is already grouped, if so then remove grouping thisfield = model.get_field(field_name) if thisfield.groupby == 1: thisfield.groupby = 0 else: # Other wise reset grouping and set selected field as groupfield for field in model.fields: field.groupby = 0 field = model.get_field(field_name) field.groupby = 1 t.model = dumps(model) t.save() return report_edit(request, report_id=report_id, response_format=response_format)
def report_filter_remove(request, report_id, field_name, filter_index, response_format='html'): "Remove a Filter on a given field for a Report" report = get_object_or_404(Report, pk=report_id) if not request.user.profile.has_permission(report, mode='w'): return user_denied(request, message="You don't have write access to this Report") model = loads(report.model) field = model.get_field(field_name) field.filters.pop(int(filter_index) - 1) report.model = dumps(model) report.save() return HttpResponseRedirect(reverse('reports_report_edit', args=[int(report_id)]))
def save(self): # add filter to field if not self.data['choice']: return t = self.report model = loads(t.model) classobj = model.get_class_object() xfield = classobj._meta.get_field_by_name(self.field_name)[0] field = model.get_field(self.field_name) if not field.filters: field.filters = [] c = self.data['choice'] type = xfield.get_internal_type() if type == 'ManyToManyField': c = xfield.related.parent_model.objects.filter(pk=c)[0] if type == 'ForeignKey': c = xfield.related.parent_model.objects.filter(pk=c)[0] display_choice = c if hasattr(self.fields['choice'], 'choices'): for choice, dc in self.fields['choice'].choices: if unicode(c) == unicode(choice): display_choice = dc break for choice, dc in self.fields['operand'].choices: if unicode(self.data['operand']) == unicode(choice): display_operand = dc break display = "{0!s} {1!s} {2!s}".format( field.get_human_name(), display_operand, unicode(display_choice)) field.filters.append({'choice': c, 'operand': self.data['operand'], 'display': display }) t.model = dumps(model) t.save()
def __init__(self, user, *args, **kwargs): if not ('report' in kwargs and 'field_name' in kwargs): return report = kwargs.pop('report') field_name = kwargs.pop('field_name') super(FilterForm, self).__init__(*args, **kwargs) model = loads(report.model) self.report = report self.field_name = field_name classobj = model.get_class_object() field = classobj._meta.get_field_by_name(field_name)[0] # TODO: Provisions for ManyToMany fields self.fields['operand'] = forms.ChoiceField() if field.get_internal_type() == 'ForeignKey': self.fields['choice'] = forms.ModelChoiceField(queryset=Object.filter_permitted(user, field.related.parent_model.objects.all(), mode='x')) fc = (('is', 'is'), ('not', 'is not')) elif field.get_internal_type() == 'DateTimeField': self.fields['choice'] = forms.DateTimeField() self.fields['choice'].widget.attrs.update( {'class': 'datetimepicker'}) fc = (('beforedatetime', 'before'), ('afterdatetime', 'after')) elif field.get_internal_type() == 'DateField': self.fields['choice'] = forms.DateField() self.fields['choice'].widget.attrs.update({'class': 'datepicker'}) fc = (('beforedate', 'before'), ( 'afterdate', 'after'), ('on', 'on')) else: self.fields['choice'] = field.formfield() fc = (('is', 'is'), ('not', 'is not')) self.fields['operand'].choices = fc self.fields['operand'].label = "" self.fields['choice'].label = "" self.fields['choice'].help_text = ""
def report_edit(request, report_id=None, response_format='html'): "Create new report based on user choice" report = get_object_or_404(Report, pk=report_id) if not request.user.profile.has_permission(report, mode='w'): return user_denied(request, message="You don't have access to edit this Report") model = loads(report.model) if request.POST and 'commit' in request.POST: # UPDATE MODEL if 'report_name' in request.POST: report.name = request.POST['report_name'] fieldnames = [] aggregations = {} for key in request.POST: if 'field' in key: fieldnames.append(request.POST[key]) elif 'aggregation-' in key: aggregations[key[12:]] = request.POST[key] for field in model.fields: field.aggregation = aggregations.get(field.name) if field.name in fieldnames: field.display = True else: field.display = False report.model = dumps(model) report.save() if 'commit' in request.POST: return HttpResponseRedirect(reverse('reports_report_view', args=[report.id])) return render_to_response('reports/report_edit', {'report': report, 'model': model, }, context_instance=RequestContext(request), response_format=response_format)
def _get_report_content(report, request=None): model = loads(report.model) object = model.name object = object.split('.') module_name = object[0] + '.' + object[1] + '.' + object[2] import_name = object[3] module = __import__(module_name, globals(), locals(), [import_name], -1) classobj = getattr(module, import_name) if request: unfiltered_set = Object.filter_by_request(request, classobj.objects) else: unfiltered_set = classobj.objects.exclude(trash=True) # construct filter filters = {} excludes = {} for field in model.fields: for filter in field.filters: if filter['operand'] == 'is': filters.setdefault(field.name + '__in', []).append(filter['choice']) elif filter['operand'] == 'not': excludes.setdefault(field.name + '__in', []).append(filter['choice']) elif filter['operand'] == 'beforedate': filters[field.name + '__gte'] = datetime.date(datetime.strptime(filter['choice'], '%m/%d/%Y')) elif filter['operand'] == 'afterdate': filters[field.name + '__lte'] = datetime.date(datetime.strptime(filter['choice'], '%m/%d/%Y')) elif filter['operand'] == 'beforedatetime': filters[field.name + '__gte'] = datetime.strptime(filter['choice'], '%m/%d/%Y %H:%M') elif filter['operand'] == 'afterdatetime': filters[field.name + '__lte'] = datetime.strptime(filter['choice'], '%m/%d/%Y %H:%M') elif filter['operand'] == 'on': filters.setdefault(field.name + '__in', []).append(datetime.strptime(filter['choice'], '%m/%d/%Y')) set = unfiltered_set.filter(**filters).exclude(**excludes) # Check for group groupname = None groups = None for field in model.fields: if field.groupby == 1: groupname = field.name if groupname: xfield = classobj._meta.get_field_by_name(groupname)[0] xtype = xfield.get_internal_type() if xtype == 'ManyToManyField': set = sorted(set, key=lambda item: ( ", ".join([unicode(i) for i in getattr(item, groupname).all()])), reverse=True) groups, groupnames = [], [] for obj in set: for n in getattr(obj, groupname).all(): if n not in groupnames: groupnames.append(n) for n in groupnames: l = [] for obj in set: if n in getattr(obj, groupname).all(): l.append(obj) groups.append((unicode(n), l)) elif xtype == ('DateTimeField' or 'DateField'): set = set.order_by(groupname) #set = sorted(set, key = lambda item: getattr(item,groupname)) # TODO: Fix this sort groups, groupnames, l, ng = [], [], [], [] n = None if xtype == 'DateTimeField': def dt(ob): return getattr(ob, groupname).date() else: def dt(ob): return getattr(ob, groupname) for x in set: n = dt(x) if n: break if n: for obj in set: if getattr(obj, groupname): if dt(obj) == n: l.append(obj) else: groups.append((unicode(n), l)) l = [] n = dt(obj) l.append(obj) else: ng.append(obj) if ng: groups.append(('None', ng)) else: set = sorted(set, key=lambda item: unicode( item.get_field_value(groupname)), reverse=True) groups = [] for g, ks in groupby(set, key=lambda item: unicode(item.get_field_value(groupname))): groups.append((g, list(ks))) xfield = set[0]._meta.get_field_by_name(groupname)[0] # Count aggregate functions agg_funcs = {} for field in model.fields: # get fields and aggregate functions for them if field.display and getattr(field, 'aggregation', None): xfield = classobj._meta.get_field_by_name(field.name)[0] if number_field_regex.match(xfield.get_internal_type()) and field.aggregation in aggregate_functions: agg_funcs[field.name] = aggregate_functions[ field.aggregation]['function'] aggregations = {} if agg_funcs: for grouper, ls in groups if groups else (('set', set),): data = {} for s in ls: for key in agg_funcs: data.setdefault(key, []).append(getattr(s, key, 0)) aggrs = {} for key, func in agg_funcs.items(): aggrs[key] = func(data.get(key, [0, ])) aggregations[grouper] = aggrs return {'model': model, 'set': set, 'groups': groups, 'groupname': groupname, 'aggregations': aggregations}