diff --git a/mainapp/migrations/0062_contributorupdate.py b/mainapp/migrations/0062_contributorupdate.py new file mode 100644 index 000000000..2dc870d59 --- /dev/null +++ b/mainapp/migrations/0062_contributorupdate.py @@ -0,0 +1,28 @@ +# Generated by Django 2.1 on 2018-08-21 06:54 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0061_auto_20180820_1010'), + ] + + operations = [ + migrations.CreateModel( + name='ContributorUpdate', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('status', models.CharField(choices=[('hig', 'High priority'), ('med', 'Medium priority'), ('low', 'Low priority'), ('cls', 'Can be closed'), ('otr', 'Other')], max_length=10)), + ('other_status', models.CharField(blank=True, default='', max_length=255, verbose_name='Please specify other status')), + ('updater_name', models.CharField(max_length=100, verbose_name='Name of person or group updating')), + ('updater_phone', models.CharField(max_length=14, validators=[django.core.validators.RegexValidator(code='invalid_mobile', message='Please Enter 10/11 digit mobile number or landline as 0', regex='^((\\+91|91|0)[\\- ]{0,1})?[456789]\\d{9}$')], verbose_name='Phone number of person or group updating')), + ('notes', models.TextField(blank=True, verbose_name='Contributor comments')), + ('update_ts', models.DateTimeField(auto_now_add=True)), + ('contributor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mainapp.Contributor')), + ], + ), + ] diff --git a/mainapp/migrations/0065_merge_20180821_1426.py b/mainapp/migrations/0065_merge_20180821_1426.py new file mode 100644 index 000000000..12a285006 --- /dev/null +++ b/mainapp/migrations/0065_merge_20180821_1426.py @@ -0,0 +1,14 @@ +# Generated by Django 2.1 on 2018-08-21 08:56 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0062_contributorupdate'), + ('mainapp', '0064_privaterescuecamp'), + ] + + operations = [ + ] diff --git a/mainapp/migrations/0066_merge_20180821_1500.py b/mainapp/migrations/0066_merge_20180821_1500.py new file mode 100644 index 000000000..0fdede841 --- /dev/null +++ b/mainapp/migrations/0066_merge_20180821_1500.py @@ -0,0 +1,14 @@ +# Generated by Django 2.1 on 2018-08-21 09:30 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0065_merge_20180821_1422'), + ('mainapp', '0065_merge_20180821_1426'), + ] + + operations = [ + ] diff --git a/mainapp/migrations/0069_merge_20180821_2300.py b/mainapp/migrations/0069_merge_20180821_2300.py new file mode 100644 index 000000000..a90360b1e --- /dev/null +++ b/mainapp/migrations/0069_merge_20180821_2300.py @@ -0,0 +1,14 @@ +# Generated by Django 2.1 on 2018-08-21 17:30 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0066_merge_20180821_1500'), + ('mainapp', '0068_auto_20180821_1710'), + ] + + operations = [ + ] diff --git a/mainapp/migrations/0073_merge_20180822_0018.py b/mainapp/migrations/0073_merge_20180822_0018.py new file mode 100644 index 000000000..df9d79bff --- /dev/null +++ b/mainapp/migrations/0073_merge_20180822_0018.py @@ -0,0 +1,14 @@ +# Generated by Django 2.1 on 2018-08-21 18:48 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0069_merge_20180821_2300'), + ('mainapp', '0072_auto_20180822_0000'), + ] + + operations = [ + ] diff --git a/mainapp/migrations/0074_merge_20180822_0024.py b/mainapp/migrations/0074_merge_20180822_0024.py new file mode 100644 index 000000000..97e010d56 --- /dev/null +++ b/mainapp/migrations/0074_merge_20180822_0024.py @@ -0,0 +1,14 @@ +# Generated by Django 2.1 on 2018-08-21 18:54 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0073_merge_20180822_0018'), + ('mainapp', '0073_merge_20180822_0015'), + ] + + operations = [ + ] diff --git a/mainapp/models.py b/mainapp/models.py index 709692332..6266d42c5 100644 --- a/mainapp/models.py +++ b/mainapp/models.py @@ -85,6 +85,15 @@ ('M', 'Medium'), ('L', 'Low')] + +contributor_update_status_types = ( + ('hig', 'High priority'), + ('med', 'Medium priority'), + ('low', 'Low priority'), + ('cls', 'Can be closed'), + ('otr', 'Other') +) + person_status = ( ('new', 'New'), ('checked_out', 'Checked Out'), @@ -96,7 +105,6 @@ class LSGTypes(Enum): MUNICIPALITY = 1 GRAMA_PANCHAYATH = 2 - class Request(models.Model): district = models.CharField( max_length = 15, @@ -529,14 +537,51 @@ class RequestUpdate(models.Model): phone_number_regex = RegexValidator(regex='^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$', message='Please Enter 10/11 digit mobile number or landline as 0', code='invalid_mobile') updater_phone = models.CharField(max_length=14,verbose_name='Phone number of person or group updating', validators=[phone_number_regex]) - notes = models.TextField(verbose_name='Volunteer comments', blank=True) + update_ts = models.DateTimeField(auto_now_add=True) + def __str__(self): + return self.get_status_display() + + +class ContributorUpdate(models.Model): + contributor = models.ForeignKey(Contributor, on_delete=models.CASCADE) + status = models.CharField( + max_length = 10, + choices = contrib_status_types, + default = 'new' + ) + + other_status = models.CharField(max_length=255, verbose_name='Please specify other status', default='', blank=True) + updater_name = models.CharField(max_length=100, verbose_name='Name of person or group updating', blank=False) + + phone_number_regex = RegexValidator(regex='^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$', message='Please Enter 10/11 digit mobile number or landline as 0', code='invalid_mobile') + updater_phone = models.CharField(max_length=14,verbose_name='Phone number of person or group updating', validators=[phone_number_regex]) + notes = models.TextField(verbose_name='Contributor comments', blank=True) update_ts = models.DateTimeField(auto_now_add=True) def __str__(self): return self.get_status_display() +class ContributorUpdate(models.Model): + contributor = models.ForeignKey(Contributor, on_delete=models.CASCADE) + status = models.CharField( + max_length = 10, + choices = contrib_status_types, + default = 'new' + ) + + other_status = models.CharField(max_length=255, verbose_name='Please specify other status', default='', blank=True) + updater_name = models.CharField(max_length=100, verbose_name='Name of person or group updating', blank=False) + + phone_number_regex = RegexValidator(regex='^((\+91|91|0)[\- ]{0,1})?[456789]\d{9}$', message='Please Enter 10/11 digit mobile number or landline as 0', code='invalid_mobile') + updater_phone = models.CharField(max_length=14,verbose_name='Phone number of person or group updating', validators=[phone_number_regex]) + notes = models.TextField(verbose_name='Contributor comments', blank=True) + + update_ts = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.get_status_display() class CollectionCenter(models.Model): diff --git a/mainapp/templates/mainapp/contrib_list.html b/mainapp/templates/mainapp/contrib_list.html index 281228f70..afc91a85e 100644 --- a/mainapp/templates/mainapp/contrib_list.html +++ b/mainapp/templates/mainapp/contrib_list.html @@ -79,10 +79,13 @@

malayalam placeholder

District - ജില്ല Name - ml - Phone - ഫോണ്‍ നമ്പര്‍ + {% if user.is_authenticated %} + Phone - ഫോണ്‍ നമ്പര്‍ + {% endif %} address -ml- commodities -ml- Status -ml- + Update @@ -90,10 +93,13 @@

malayalam placeholder

{{ req.get_district_display }} {{ req.name }} - {{ req.phone }} + {% if user.is_authenticated %} + {{ req.phone }} + {% endif %} {{ req.address }} {{ req.commodities }} {{ req.get_status_display }} + Update {% endfor %} diff --git a/mainapp/templates/mainapp/contributor_update.html b/mainapp/templates/mainapp/contributor_update.html new file mode 100644 index 000000000..b44653134 --- /dev/null +++ b/mainapp/templates/mainapp/contributor_update.html @@ -0,0 +1,110 @@ +{% extends 'base.html' %} +{% load bootstrap3 %} + +{% block content %} + + +
+ + + + + + + + + + + + + + + {% if user.is_authenticated %} + + + + {% endif %} + + + + + + + + + + + +

Contributor Info

District : {{ view.contributor.district }}
Name : {{ view.contributor.name }}
Phone : {{ view.contributor.phone }}
Address : {{ view.contributor.address }}
Commodities : {{ view.contributor.commodities }}
Status : {{ view.contributor.status }}
+ +
+ +

Updates

+
+ + + + + + {% if user.is_authenticated %} + + {% endif %} + + + + + + + + {% for update in view.updates %} + + + + {% if user.is_authenticated %} + + {% endif %} + + + + {% endfor %} + + +
StatusUpdater NameUpdater PhoneNotesUpdate Time
{{ update.status }} {{ update.other_status }}{{ update.updater_name }}{{ update.updater_phone }}{{ update.notes }}{{ update.update_ts }}
+ +
+ +

Contributor Updates

+

placeholder for malayalam ‍

+
+ {% csrf_token %} + {% bootstrap_form form %} + + {% buttons %} + + {% endbuttons %} +
+ + + +{% endblock %} \ No newline at end of file diff --git a/mainapp/templates/mainapp/contributor_update_success.html b/mainapp/templates/mainapp/contributor_update_success.html new file mode 100644 index 000000000..5d9806725 --- /dev/null +++ b/mainapp/templates/mainapp/contributor_update_success.html @@ -0,0 +1,9 @@ +{% extends 'base.html' %} +{% load bootstrap3 %} + +{% block content %} + +

Thank You for updating Contributor info

+

Malayalam placeholder

+ +{% endblock %} \ No newline at end of file diff --git a/mainapp/urls.py b/mainapp/urls.py index 1fc3f7bb3..4413346ae 100644 --- a/mainapp/urls.py +++ b/mainapp/urls.py @@ -58,4 +58,6 @@ path('req_update_success/', views.ReqUpdateSuccess.as_view(), name='req_update_success'), path('consent_success/', views.ConsentSuccess.as_view(), name='consent_success'), url(r'c/(?P\d+)/(?P\d+)/$', views.VolunteerConsent.as_view(), name='volunteer_consent'), + url(r'contributor_update/(?P\d+)/$', views.ContributorUpdateView.as_view(), name='contributorupdateview'), + path('contributor_update_success/', views.ContributorUpdateSuccess.as_view(), name='contributor_update_success') ] diff --git a/mainapp/views.py b/mainapp/views.py index 059e7ffa6..0f86da0b5 100644 --- a/mainapp/views.py +++ b/mainapp/views.py @@ -7,7 +7,7 @@ from mainapp.redis_queue import sms_queue from mainapp.sms_handler import send_confirmation_sms from .models import Request, Volunteer, DistrictManager, Contributor, DistrictNeed, Person, RescueCamp, NGO, \ - Announcements , districts, RequestUpdate, PrivateRescueCamp + Announcements , districts, RequestUpdate, PrivateRescueCamp, ContributorUpdate import django_filters from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.http import JsonResponse @@ -791,6 +791,45 @@ def camp_requirements_list(request): page = request.GET.get('page') data = paginator.get_page(page) return render(request, "mainapp/camp_requirements_list.html", {'filter': filter , 'data' : data}) + +class ContributorUpdateView(CreateView): + model = ContributorUpdate + template_name='mainapp/contributor_update.html' + fields = [ + 'status', + 'other_status', + 'updater_name', + 'updater_phone', + 'notes' + ] + success_url = '/contributor_update_success/' + + def contributor(self): + return self.contributor + + def updates(self): + return self.updates + + #@method_decorator(login_required) + def dispatch(self, request, *args, **kwargs): + #could not use login_required decorator because it redirects to /accounts/login and we need /login + #disable authentication + # if not request.user.is_authenticated: + # return redirect('/login'+'?next=request_updates/'+kwargs['request_id']+'/') + + self.contributor = get_object_or_404(Contributor, pk=kwargs['contributor_id']) + self.updates = ContributorUpdate.objects.all().filter(contributor_id=kwargs['contributor_id']).order_by('-update_ts') + return super().dispatch(request, *args, **kwargs) + + def form_valid(self, form): + self.object = form.save(commit=False) + self.object.contributor = self.contributor + self.object = form.save() + return HttpResponseRedirect(self.get_success_url()) + + +class ContributorUpdateSuccess(TemplateView): + template_name = "mainapp/contributor_update_success.html" class RequestUpdateView(CreateView): model = RequestUpdate @@ -830,7 +869,6 @@ def form_valid(self, form): class ReqUpdateSuccess(TemplateView): template_name = "mainapp/request_update_success.html" - class CollectionCenterListView(ListView): model = CollectionCenter paginate_by = PER_PAGE @@ -854,4 +892,42 @@ class CollectionCenterView(CreateView): 'lsg_name', 'ward_name', 'city', + ] + +class ContributorUpdateView(CreateView): + model = ContributorUpdate + template_name='mainapp/contributor_update.html' + fields = [ + 'status', + 'other_status', + 'updater_name', + 'updater_phone', + 'notes' ] + success_url = '/contributor_update_success/' + + def contributor(self): + return self.contributor + + def updates(self): + return self.updates + + #@method_decorator(login_required) + def dispatch(self, request, *args, **kwargs): + #could not use login_required decorator because it redirects to /accounts/login and we need /login + #disable authentication + # if not request.user.is_authenticated: + # return redirect('/login'+'?next=request_updates/'+kwargs['request_id']+'/') + + self.contributor = get_object_or_404(Contributor, pk=kwargs['contributor_id']) + self.updates = ContributorUpdate.objects.all().filter(contributor_id=kwargs['contributor_id']).order_by('-update_ts') + return super().dispatch(request, *args, **kwargs) + + def form_valid(self, form): + self.object = form.save(commit=False) + self.object.contributor = self.contributor + self.object = form.save() + return HttpResponseRedirect(self.get_success_url()) + +class ContributorUpdateSuccess(TemplateView): + template_name = "mainapp/contributor_update_success.html"