Skip to content

Commit 9e701f4

Browse files
committed
Report responses to report columns
1 parent 8297cee commit 9e701f4

File tree

8 files changed

+1182
-194
lines changed

8 files changed

+1182
-194
lines changed

tigacrafting/views.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,20 +1316,7 @@ def get_reports_unfiltered_sites_other(reports_imbornal):
13161316
return new_reports_unfiltered_sites_other
13171317

13181318
def get_reports_imbornal():
1319-
reports_imbornal = ReportResponse.objects.filter(
1320-
Q(question='Is this a storm drain or sewer?', answer='Yes') | Q(question=u'\xc9s un embornal o claveguera?',
1321-
answer=u'S\xed') | Q(
1322-
question=u'\xbfEs un imbornal o alcantarilla?', answer=u'S\xed') | Q(question='Selecciona lloc de cria',
1323-
answer='Embornals') | Q(
1324-
question='Selecciona lloc de cria', answer='Embornal o similar') | Q(question='Tipo de lugar de cría',
1325-
answer='Sumidero o imbornal') | Q(
1326-
question='Tipo de lugar de cría', answer='Sumideros') | Q(question='Type of breeding site',
1327-
answer='Storm drain') | Q(
1328-
question='Type of breeding site', answer='Storm drain or similar receptacle')).values('report').distinct()
1329-
1330-
reports_imbornal_new = ReportResponse.objects.filter(question_id=12).filter(answer_id=121).values('report').distinct()
1331-
1332-
return reports_imbornal | reports_imbornal_new
1319+
return Report.objects.filter(breeding_site_type=Report.BREEDING_SITE_TYPE_STORM_DRAIN)
13331320

13341321
def get_reports_unfiltered_adults_except_being_validated():
13351322
new_reports_unfiltered_adults = Report.objects.exclude(creation_time__year=2014).exclude(type='site').exclude(note__icontains='#345').exclude(photos=None).annotate(n_annotations=Count('expert_report_annotations')).filter(n_annotations=0).order_by('-server_upload_time')

tigamap/templates/tigamap/report_map.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
'{{ report.tigaprob_text }}</td></tr><tr><td>cc score:</td><td>{{ score|floatformat:2 }}</td></tr><tr><td>lat:</td><td>{{ lat }}</td></tr><tr><td>lon:</td><td>{{ lon }}</td></tr></table>{{ report.get_validated_photo_html | safe }}';
111111
{% else %}
112112
popup_text = '<table><tr><td>{% trans 'type' %}:</td><td>'+
113-
'{{ report.site_type_trans }}</td></tr><tr><td>cc score:</td><td>{{ score|floatformat:2 }}</td></tr><tr><td>lat:</td><td>{{ lat }}</td></tr><tr><td>lon:</td><td>{{ report.lon }}</td></tr></table>{{ report.get_validated_photo_html | safe }}';
113+
'{{ report.breeding_site_type }}</td></tr><tr><td>cc score:</td><td>{{ score|floatformat:2 }}</td></tr><tr><td>lat:</td><td>{{ lat }}</td></tr><tr><td>lon:</td><td>{{ report.lon }}</td></tr></table>{{ report.get_validated_photo_html | safe }}';
114114
{% endif %}
115115

116116
{% endwith %}
@@ -123,7 +123,7 @@
123123
'{{ report.tigaprob_text }}</td></tr><tr><td>lat:</td><td>{{ lat }}</td></tr><tr><td>lon:</td><td>{{ lon }}</td></tr></table>';
124124
{% else %}
125125
popup_text = '<table><tr><td>{% trans 'type' %}:</td><td>'+
126-
'{{ report.site_type_trans }}</td></tr><tr><td>lat:</td><td>{{ lat }}</td></tr><tr><td>lon:</td><td>{{ report.lon }}</td></tr></table>';
126+
'{{ report.breeding_site_type }}</td></tr><tr><td>lat:</td><td>{{ lat }}</td></tr><tr><td>lon:</td><td>{{ report.lon }}</td></tr></table>';
127127
{% endif %}
128128
{% endif %}
129129
{% if detailed == 'detailed' %}

tigascoring/xp_scoring.py

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,12 @@
2222
SITE_STORM_DRAIN_REWARD = 4
2323
BREEDING_SITE_MOSQUITO_REWARD = 3
2424

25-
MOSQUITO_HOW_LOOKS_QUESTION_ID = 7
26-
MOSQUITO_THORAX_ANSWER_IDS = [711, 712, 713, 714]
27-
MOSQUITO_ABDOMEN_ANSWER_IDS = [721, 722, 723, 724]
28-
MOSQUITO_LEG_ANSWER_IDS = [731, 732, 733, 734]
29-
3025
MOSQUITO_BITE_QUESTION_ID = 8
3126
MOSQUITO_BITE_ANSWER_ID = 101
3227

3328
BREEDING_SITE_MOSQUITO_QUESTION_ID = 11
3429
BREEDING_SITE_MOSQUITO_ANSWER_ID = 101
3530

36-
SITE_WATER_QUESTION_ID = 10
37-
SITE_WATER_ANSWER_IDS = [81, 101]
38-
39-
STORM_DRAIN_QUESTION_ID = 12
40-
STORM_DRAIN_ANSWER_ID = 121
41-
4231
CULEX_CATEGORY_ID = 10
4332
AEDES_CATEGORY_IDS = [4, 5, 6, 7]
4433

@@ -88,53 +77,31 @@
8877

8978

9079
def is_thorax_answered(report):
91-
for response in report.responses.all():
92-
if response.question_id == MOSQUITO_HOW_LOOKS_QUESTION_ID and response.answer_id in MOSQUITO_THORAX_ANSWER_IDS:
93-
return True
94-
return False
80+
return report.user_perceived_mosquito_thorax is not None
9581

9682

9783
def is_abdomen_answered(report):
98-
for response in report.responses.all():
99-
if response.question_id == MOSQUITO_HOW_LOOKS_QUESTION_ID and response.answer_id in MOSQUITO_ABDOMEN_ANSWER_IDS:
100-
return True
101-
return False
84+
return report.user_perceived_mosquito_abdomen is not None
10285

10386

10487
def is_leg_answered(report):
105-
for response in report.responses.all():
106-
if response.question_id == MOSQUITO_HOW_LOOKS_QUESTION_ID and response.answer_id in MOSQUITO_LEG_ANSWER_IDS:
107-
return True
108-
return False
88+
return report.user_perceived_mosquito_legs is not None
10989

11090

11191
def is_water_answered(report):
112-
for response in report.responses.all():
113-
if response.question_id == SITE_WATER_QUESTION_ID and response.answer_id in SITE_WATER_ANSWER_IDS:
114-
return True
115-
return False
92+
return report.breeding_site_has_water is not None
11693

11794

11895
def is_bite_report_followed(report):
119-
for response in report.responses.all():
120-
if response.question_id == MOSQUITO_BITE_QUESTION_ID and response.answer_id == MOSQUITO_BITE_ANSWER_ID:
121-
return True
122-
return False
96+
return report.responses.filter(question_id=MOSQUITO_BITE_QUESTION_ID, answer_id=MOSQUITO_BITE_ANSWER_ID).exists()
12397

12498

12599
def is_mosquito_report_followed(report):
126-
for response in report.responses.all():
127-
if response.question_id == BREEDING_SITE_MOSQUITO_QUESTION_ID and response.answer_id == BREEDING_SITE_MOSQUITO_ANSWER_ID:
128-
return True
129-
return False
100+
return report.responses.filter(question_id=BREEDING_SITE_MOSQUITO_QUESTION_ID, answer_id=BREEDING_SITE_MOSQUITO_ANSWER_ID).exists()
130101

131102

132103
def is_storm_drain(report):
133-
for response in report.responses.all():
134-
if response.question_id == STORM_DRAIN_QUESTION_ID and response.answer_id == STORM_DRAIN_ANSWER_ID:
135-
return True
136-
return False
137-
104+
return report.breeding_site_type == Report.BREEDING_SITE_TYPE_STORM_DRAIN
138105

139106
def is_culex(validation_result):
140107
if validation_result['category'] is not None:

tigaserver_app/admin.py

Lines changed: 141 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from django.utils.encoding import smart_str
88
from django.http.response import HttpResponse
99
from django.utils.html import mark_safe
10+
from django.utils.translation import ugettext_lazy as _
1011

1112

1213
def export_full_csv(modeladmin, request, queryset):
@@ -107,42 +108,162 @@ class PhotoInline(admin.StackedInline):
107108

108109

109110
class ReportAdmin(admin.ModelAdmin):
110-
list_display = ('report_id', 'deleted', 'user', 'version_number', 'creation_time', 'version_time', 'type', 'mission',
111-
'package_version', 'os', 'n_photos', 'map_link', 'movelab_score', 'crowd_score')
112-
inlines = [ReportResponseInline, PhotoInline]
113-
ordering = ('creation_time', 'report_id', 'version_number')
114-
readonly_fields = ('deleted', 'version_UUID', 'user', 'report_id', 'version_number', 'other_versions_of_this_report', 'creation_time', 'version_time', 'server_upload_time', 'updated_at', 'datetime_fix_offset', 'phone_upload_time', 'type', 'mission', 'location_choice', 'current_location_lon', 'current_location_lat', 'selected_location_lon', 'selected_location_lat', 'note', 'package_name', 'package_version', 'device_manufacturer', 'device_model', 'os', 'os_version', 'os_language', 'app_language', 'n_photos', 'lon', 'lat', 'tigaprob', 'tigaprob_text', 'site_type', 'site_type_trans', 'embornals', 'fonts', 'basins', 'buckets', 'wells', 'other', 'masked_lat', 'masked_lon', 'map_link', 'movelab_score', 'crowd_score')
115-
fields = ('hide', 'deleted', 'map_link', 'version_UUID', 'user', 'report_id', 'version_number', 'other_versions_of_this_report', ('creation_time', 'version_time', 'datetime_fix_offset'), ('server_upload_time','phone_upload_time'), 'updated_at', 'type', 'mission', 'location_choice', 'current_location_lon', 'current_location_lat', 'selected_location_lon', 'selected_location_lat', 'note', 'package_name', 'package_version', 'device_manufacturer', 'device_model', 'os', 'os_version', 'os_language', 'app_language', 'n_photos', 'lon', 'lat', 'tigaprob', 'tigaprob_text', 'site_type', 'site_type_trans', 'embornals', 'fonts', 'basins', 'buckets', 'wells', 'other', 'masked_lat', 'masked_lon', 'movelab_score', 'crowd_score')
111+
list_display = (
112+
'report_id', 'deleted', 'user', 'version_number', 'creation_time', 'version_time', 'type', 'mission',
113+
'package_version', 'os', 'n_photos'
114+
)
116115
list_filter = ['os', 'type', 'mission', 'package_name', 'package_version']
116+
117+
inlines = [ReportResponseInline, PhotoInline]
117118
actions = [export_full_csv, export_full_csv_sc]
118119

120+
readonly_fields = [
121+
"deleted",
122+
"report_id",
123+
"version_number",
124+
"type",
125+
"user",
126+
"mission",
127+
"session",
128+
"server_upload_time",
129+
"updated_at",
130+
"version_time",
131+
"phone_upload_time",
132+
"creation_time",
133+
"other_versions_of_this_report"
134+
]
135+
136+
fieldsets = [
137+
(
138+
_('General info'),
139+
{
140+
"fields": [
141+
("report_id", "version_number"),
142+
("hide", "deleted"),
143+
"type",
144+
"user",
145+
("mission","session"),
146+
"other_versions_of_this_report",
147+
("server_upload_time", "updated_at"),
148+
("version_time", "datetime_fix_offset"),
149+
("creation_time", "phone_upload_time")
150+
]
151+
}
152+
),
153+
(
154+
_("Location information"),
155+
{
156+
"fields": [
157+
("country", "nuts_2", "nuts_3"),
158+
"location_choice",
159+
"point"
160+
]
161+
}
162+
),
163+
(
164+
_("Other"),
165+
{
166+
"fields": [
167+
("package_name", "package_version", "app_language"),
168+
("device_manufacturer", "device_model"),
169+
("os", "os_version", "os_language"),
170+
"note"
171+
],
172+
"classes": ["collapse",]
173+
}
174+
)
175+
]
176+
177+
def get_readonly_fields(self, request, obj=None):
178+
# Only allow to edit 'hide' field.
179+
result = super().get_readonly_fields(request, obj)
180+
181+
readonly_fields = [field.name for field in self.model._meta.get_fields()]
182+
allow_edit_fields = ['hide',]
183+
184+
for field_name in readonly_fields:
185+
if not field_name in allow_edit_fields:
186+
result.append(field_name)
187+
188+
return result
189+
190+
def get_fieldsets(self, request, obj = None):
191+
result = super().get_fieldsets(request, obj)
192+
193+
if not obj:
194+
return result
195+
196+
extra_fieldsets = []
197+
if obj.type == Report.TYPE_ADULT:
198+
extra_fieldsets.append(
199+
(
200+
_("Classification"),
201+
{
202+
"fields": [
203+
"ia_filter_1", "ia_filter_2"
204+
]
205+
}
206+
)
207+
)
208+
extra_fieldsets.append(
209+
(
210+
_("Specific information"),
211+
{
212+
"fields": [
213+
("event_environment", "event_moment"),
214+
"user_perceived_mosquito_specie",
215+
("user_perceived_mosquito_thorax", "user_perceived_mosquito_abdomen", "user_perceived_mosquito_legs")
216+
]
217+
}
218+
)
219+
)
220+
elif obj.type == Report.TYPE_BITE:
221+
extra_fieldsets.append(
222+
(
223+
_("Specific information"),
224+
{
225+
"fields": [
226+
("event_environment", "event_moment"),
227+
"bite_count",
228+
("head_bite_count", "left_arm_bite_count", "right_arm_bite_count", "chest_bite_count", "left_leg_bite_count", "right_leg_bite_count")
229+
]
230+
}
231+
)
232+
)
233+
elif obj.type == Report.TYPE_SITE:
234+
extra_fieldsets.append(
235+
(
236+
_("Specific information"),
237+
{
238+
"fields": [
239+
"breeding_site_type",
240+
"breeding_site_has_water",
241+
"breeding_site_in_public_area",
242+
"breeding_site_has_near_mosquitoes",
243+
"breeding_site_has_larvae"
244+
]
245+
}
246+
)
247+
)
248+
249+
return result + extra_fieldsets
250+
119251
def has_add_permission(self, request):
120252
return False
121253

122254
def has_delete_permission(self, request, obj=None):
123255
return False
124256

125257
def other_versions_of_this_report(self, obj):
126-
result = []
258+
result = ""
127259
for this_version in obj.other_versions:
128260
result += '<a href="/admin/tigaserver_app/report/%s">Version %s</a> ' % (
129261
this_version.version_UUID,
130262
this_version.version_number,
131263
)
132-
return result
264+
return mark_safe(result)
133265
other_versions_of_this_report.allow_tags = True
134266

135-
def movelab_score(self, obj):
136-
return obj.movelab_score
137-
138-
def crowd_score(self, obj):
139-
return obj.crowd_score
140-
141-
def map_link(self, obj):
142-
return '<a href="/single_report_map/%s/">Show map</a>' % obj.version_UUID
143-
map_link.allow_tags = True
144-
145-
146267
def export_csv_photo(modeladmin, request, queryset):
147268
response = HttpResponse(mimetype='text/csv')
148269
response['Content-Disposition'] = 'attachment; filename=tigatrapp_photos.csv'
@@ -237,7 +358,7 @@ def other_report_versions(self, obj):
237358
this_version.version_UUID,
238359
this_version.version_number,
239360
)
240-
return result
361+
return mark_safe(result)
241362
other_report_versions.allow_tags = True
242363

243364
def map_link(self, obj):

0 commit comments

Comments
 (0)