21 |
21 |
from django.conf import settings
|
22 |
22 |
from django.db import transaction
|
23 |
23 |
from django.db.models import Q
|
|
24 |
from django.db.models.fields import BLANK_CHOICE_DASH
|
24 |
25 |
from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist
|
25 |
26 |
from django.utils.translation import ugettext_lazy as _
|
26 |
27 |
|
... | ... | |
54 |
55 |
transaction.on_commit(spooler.refresh_statistics_list)
|
55 |
56 |
|
56 |
57 |
|
57 |
|
class ChartNgForm(forms.ModelForm):
|
58 |
|
blank_choice = ('', '---------')
|
|
58 |
class ChartFiltersMixin:
|
59 |
59 |
time_intervals = (
|
60 |
60 |
('week', _('Week')),
|
61 |
61 |
('month', _('Month')),
|
... | ... | |
63 |
63 |
('weekday', _('Week day')),
|
64 |
64 |
)
|
65 |
65 |
|
|
66 |
def get_filter_fields(self, cell):
|
|
67 |
fields = OrderedDict()
|
|
68 |
for filter_ in cell.statistic.filters:
|
|
69 |
filter_id = filter_['id']
|
|
70 |
choices = [(option['id'], option['label']) for option in filter_['options']]
|
|
71 |
initial = cell.filter_params.get(filter_id, filter_.get('default'))
|
|
72 |
|
|
73 |
required = filter_.get('required', False)
|
|
74 |
multiple = filter_.get('multiple')
|
|
75 |
if not required and not multiple:
|
|
76 |
choices = BLANK_CHOICE_DASH + choices
|
|
77 |
|
|
78 |
field_class = forms.MultipleChoiceField if multiple else forms.ChoiceField
|
|
79 |
fields[filter_id] = field_class(
|
|
80 |
label=filter_['label'], choices=choices, required=required, initial=initial
|
|
81 |
)
|
|
82 |
|
|
83 |
# extend time interval choices if possible
|
|
84 |
if 'time_interval' in fields:
|
|
85 |
choice_ids = {choice_id for choice_id, _ in fields['time_interval'].choices}
|
|
86 |
if 'day' in choice_ids:
|
|
87 |
for choice in self.time_intervals:
|
|
88 |
if choice[0] not in choice_ids:
|
|
89 |
fields['time_interval'].choices.append(choice)
|
|
90 |
|
|
91 |
return fields
|
|
92 |
|
|
93 |
|
|
94 |
class ChartNgForm(ChartFiltersMixin, forms.ModelForm):
|
66 |
95 |
class Meta:
|
67 |
96 |
model = ChartNgCell
|
68 |
97 |
fields = (
|
... | ... | |
87 |
116 |
trigger_statistics_list_refresh()
|
88 |
117 |
super().__init__(*args, **kwargs)
|
89 |
118 |
|
90 |
|
field_ids = list(self._meta.fields)
|
91 |
119 |
if not self.instance.statistic or self.instance.statistic.service_slug == 'bijoe':
|
92 |
|
exclude = (
|
|
120 |
for field in (
|
93 |
121 |
'time_range',
|
94 |
122 |
'time_range_start',
|
95 |
123 |
'time_range_end',
|
96 |
124 |
'time_range_start_template',
|
97 |
125 |
'time_range_end_template',
|
98 |
|
)
|
99 |
|
field_ids = [x for x in field_ids if x not in exclude]
|
|
126 |
):
|
|
127 |
del self.fields[field]
|
100 |
128 |
|
101 |
129 |
stat_field = self.fields['statistic']
|
102 |
130 |
if not self.instance.statistic:
|
... | ... | |
107 |
135 |
Q(available=True) | Q(pk=self.instance.statistic.pk)
|
108 |
136 |
)
|
109 |
137 |
|
110 |
|
field_insert_index = field_ids.index('statistic') + 1
|
111 |
|
for filter_ in reversed(self.instance.statistic.filters):
|
112 |
|
filter_id = filter_['id']
|
113 |
|
choices = [(option['id'], option['label']) for option in filter_['options']]
|
114 |
|
initial = self.instance.filter_params.get(filter_id, filter_.get('default'))
|
115 |
|
|
116 |
|
required = filter_.get('required', False)
|
117 |
|
multiple = filter_.get('multiple')
|
118 |
|
if not required and not multiple:
|
119 |
|
choices.insert(0, self.blank_choice)
|
120 |
|
|
121 |
|
field_class = forms.MultipleChoiceField if multiple else forms.ChoiceField
|
122 |
|
self.fields[filter_id] = field_class(
|
123 |
|
label=filter_['label'], choices=choices, required=required, initial=initial
|
124 |
|
)
|
125 |
|
field_ids.insert(field_insert_index, filter_id)
|
126 |
|
|
127 |
|
self.fields = OrderedDict((field_id, self.fields[field_id]) for field_id in field_ids)
|
128 |
|
|
129 |
|
if 'time_interval' in self.fields:
|
130 |
|
self.extend_time_interval_choices()
|
|
138 |
new_fields = OrderedDict()
|
|
139 |
for field_name, field in self.fields.items():
|
|
140 |
new_fields[field_name] = field
|
|
141 |
if field_name == 'statistic':
|
|
142 |
# insert filter fields after statistic field
|
|
143 |
new_fields.update(self.get_filter_fields(self.instance))
|
|
144 |
self.fields = new_fields
|
131 |
145 |
|
132 |
146 |
def save(self, *args, **kwargs):
|
133 |
147 |
if 'statistic' in self.changed_data:
|
... | ... | |
141 |
155 |
self.instance.filter_params[filter_['id']] = self.cleaned_data.get(filter_['id'])
|
142 |
156 |
return super().save(*args, **kwargs)
|
143 |
157 |
|
144 |
|
def extend_time_interval_choices(self):
|
145 |
|
choice_ids = {choice_id for choice_id, _ in self.fields['time_interval'].choices}
|
146 |
|
if 'day' not in choice_ids:
|
147 |
|
return
|
148 |
|
for choice in self.time_intervals:
|
149 |
|
if choice[0] not in choice_ids:
|
150 |
|
self.fields['time_interval'].choices.append(choice)
|
151 |
|
|
152 |
158 |
def clean(self):
|
153 |
159 |
for template_field in ('time_range_start_template', 'time_range_end_template'):
|
154 |
160 |
if not self.cleaned_data.get(template_field):
|
155 |
|
-
|