11# vim: ai ts=4 sts=4 et sw=4
2+ import csv
23import json
34
45from django .contrib import messages
78from django .core .exceptions import ObjectDoesNotExist
89from django .core .urlresolvers import reverse , reverse_lazy
910from django .db import connection
11+ from django .db .models import (
12+ Case , Count , IntegerField , OuterRef , Subquery , When )
1013from django .forms .formsets import formset_factory
11- from django .http import HttpResponse , HttpResponseRedirect
14+ from django .http import (
15+ HttpResponse , HttpResponseRedirect , StreamingHttpResponse )
1216from django .shortcuts import get_object_or_404
17+ from django .utils .timezone import now
1318from django .views .generic import ListView , FormView , TemplateView
1419from drf_yasg .utils import swagger_auto_schema
1520import pandas as pd
1621
1722from django .conf import settings
1823
24+ from br .models import BirthRegistration
1925from locations import raw_queries
20- from locations .forms import generate_edit_form , CenterCreationForm
26+ from locations .forms import (
27+ generate_edit_form , CenterCreationForm , NonReportingCentresFilterForm )
2128from locations .filters import CenterFilterSet
2229from locations .models import Facility , Location , LocationType
2330
@@ -57,11 +64,14 @@ def get_queryset(self):
5764
5865class CenterUpdateView (
5966 LoginRequiredMixin , PermissionRequiredMixin , FormView ):
67+ permission_required = 'locations.edit_location'
6068 template_name = 'locations/center_edit.html'
6169
6270 def get_context_data (self , ** kwargs ):
6371 context = super (CenterUpdateView , self ).get_context_data (** kwargs )
6472
73+ self .object = self .get_object ()
74+
6575 context ['page_title' ] = 'Edit center: {}' .format (self .object .name )
6676 context [u'location' ] = self .object
6777
@@ -77,8 +87,7 @@ def form_valid(self, form):
7787 center = Location .objects .get (pk = form .cleaned_data ['id' ])
7888 center .name = form .cleaned_data ['name' ]
7989 center .code = form .cleaned_data ['code' ]
80- center .parent = Location .objects .get_object_or_404 (
81- pk = form .cleaned_data ['lga' ])
90+ center .parent = get_object_or_404 (Location , pk = form .cleaned_data ['lga' ])
8291 center .active = form .cleaned_data ['active' ]
8392 center .save ()
8493 center .facilities .update (
@@ -87,14 +96,14 @@ def form_valid(self, form):
8796
8897 return HttpResponseRedirect (self .get_success_url ())
8998
90- def get_form (self , form_class ):
91- return generate_edit_form (self .object )
99+ def get_form (self , form_class = None ):
100+ return generate_edit_form (self .get_object () )
92101
93102 def get_queryset (self ):
94103 return Location .objects .filter (type__name = 'RC' )
95104
96105 def get_success_url (self ):
97- return reverse ('center_list' )
106+ return reverse ('locations: center_list' )
98107
99108 def post (self , request , * args , ** kwargs ):
100109 form = generate_edit_form (self .get_object (), request .POST )
@@ -195,3 +204,86 @@ def facilities(request):
195204 facility_dataframe .to_csv (response , encoding = 'UTF-8' , index = False )
196205
197206 return response
207+
208+
209+
210+ class CSVBuffer (object ):
211+ def write (self , value ):
212+ return value
213+
214+
215+ def _get_rows (centres ):
216+ yield ['Centre' , 'Code' , 'LGA' , 'State' , 'Active?' , 'Last report date' ]
217+
218+ for centre in centres :
219+ last_report_time = centre .latest_birth_report_time ()
220+ yield [
221+ centre .name ,
222+ centre .code ,
223+ centre .parent .name ,
224+ centre .parent .parent .name ,
225+ 'Yes' if centre .active else 'No' ,
226+ last_report_time .strftime ('%d-%m-%Y' ) if last_report_time else 'N/A'
227+ ]
228+
229+
230+ class NonReportingCentresView (LoginRequiredMixin , ListView ):
231+ context_object_name = 'centres'
232+ page_title = 'Non-reporting centres'
233+ paginate_by = settings .PAGE_SIZE
234+ template_name = 'locations/non_reporting_centre_list.html'
235+
236+ def get (self , request , * args , ** kwargs ):
237+ centres = self .get_queryset ()
238+
239+ year = request .GET .get ('year' ) or None
240+ month = request .GET .get ('month' ) or None
241+
242+ if request .GET .get ('export' ):
243+ writer = csv .writer (CSVBuffer ())
244+ response = StreamingHttpResponse ((writer .writerow (row ) for row in _get_rows (centres )), content_type = 'text/csv' )
245+ filename = 'non-reporting-centres-{}-{}.csv' .format (
246+ year ,
247+ str (month ).zfill (2 )
248+ )
249+ response ['Content-Disposition' ] = 'attachment; filename={}' .format (
250+ filename )
251+
252+ return response
253+
254+ return super (NonReportingCentresView , self ).get (request , * args , ** kwargs )
255+
256+ def get_context_data (self , ** kwargs ):
257+ context = super (NonReportingCentresView , self ).get_context_data (** kwargs )
258+
259+ context ['page_title' ] = self .page_title
260+ context ['filter_form' ] = self .filter_form
261+ context ['year' ] = self .request .GET .get ('year' ) or now ().year
262+ context ['month' ] = self .request .GET .get ('month' ) or ''
263+
264+ return context
265+
266+ def get_queryset (self ):
267+ self .filter_form = NonReportingCentresFilterForm (self .request .GET )
268+ if self .filter_form .is_valid ():
269+ filter_data = self .filter_form .cleaned_data
270+ else :
271+ filter_data = {}
272+
273+ filter_kwargs = {}
274+ year = filter_data .get ('year' ) or now ().year
275+ filter_kwargs ['birthregistration_records__time__year' ] = int (year )
276+ month = filter_data .get ('month' )
277+ if month :
278+ filter_kwargs ['birthregistration_records__time__month' ] = int (month )
279+
280+ if len (filter_kwargs ) == 0 :
281+ centres = Location .objects .none ()
282+ else :
283+ centres = Location .objects .filter (
284+ type__name = 'RC'
285+ ).annotate (
286+ cnt = Count (Case (When (then = 1 , ** filter_kwargs )))
287+ ).filter (cnt = 0 )
288+
289+ return centres
0 commit comments