notify sectors about new demands (#7604)

This commit is contained in:
Serghei Mihai 2015-06-23 17:40:27 +02:00
parent 5bea7ec74e
commit 6f64d3b239
9 changed files with 155 additions and 64 deletions

3
debian/cron.daily vendored Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
TENANT="passerelle-montpellier.dev.entrouvert.org"
su passerelle -s /bin/sh -c "/usr/bin/passerelle-manage tenant_command notify_sectors -d $TENANT"

View File

@ -0,0 +1,36 @@
import requests
import urllib
from datetime import datetime, timedelta
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from passerelle.base.signature import sign_url
from passerelle_montpellier_encombrants.utils import email_sectors
class Command(BaseCommand):
def get(self, url, sign=False):
api_user = getattr(settings, 'ENCOMBRANTS_API_USER')
secret = getattr(settings, 'ENCOMBRANTS_API_SECRET')
orig = getattr(settings, 'ENCOMBRANTS_API_ORIG')
if sign:
url = sign_url(url + '&email=' + urllib.quote(api_user), secret) + '&orig='+urllib.quote(orig)
return requests.get(url, headers={'Accept': 'application/json'})
def handle(self, *args, **kwargs):
tomorrow = datetime.today() + timedelta(days=1)
filter_query = '?filter=pending&filter-date=%s' % tomorrow.strftime('%Y-%m-%d')
url = getattr(settings, 'ENCOMBRANTS_FORM_URL') + filter_query
r = self.get(url, True)
formdefs = []
if not 'err' in r.json():
for formdata in r.json():
if formdata.get('url'):
r = self.get(formdata['url'])
formdefs.append(r.json())
email_sectors(formdefs, tomorrow)
else:
raise CommandError('Error while retreiving formdefs: %s' % r.json())

View File

@ -0,0 +1,3 @@
Bonjour,
Veuillez trouver ci-jointe la liste des demandes d'enlevement d'encombrants.

View File

@ -0,0 +1 @@
Demandes d'enlevement d'encombrants du {{ date|date:"d-m-Y" }}

View File

@ -36,13 +36,13 @@ class EncombrantsTestCase(TestCase):
('sussargues@montpellier3m.fr', '34307', 'Sussargues')):
sector = Sector.objects.create(contact_email=mail)
commune = Commune.objects.create(sector=sector, insee=insee, name=name)
for i in xrange(1, randint(1, 10)):
for i in xrange(2, randint(3, 10)):
when = self.now + datetime.timedelta(days=i)
CollectDay.objects.create(sector=sector, date=when)
def test_collectdays(self):
params = {'adresse': 'PLAN DU MAS DE COCON'}
for commune in Commune.objects.all():
params = {'adresse': 'PLAN DU MAS DE COCON'}
r = self.client.get(reverse('montpellier-encombrants-available-days',
kwargs={'slug': self.instance.slug, 'insee': commune.insee}))
data = json.loads(r.content)
@ -103,7 +103,7 @@ class EncombrantsTestCase(TestCase):
kwargs={'slug': self.instance.slug,
'insee': '34970'}), {'adresse': 'Nonexisting street'})
data = json.loads(r.content)
self.assertNotEqual(data['data'], [])
self.assertEqual(data['data'], [])
def test_collectdays_random_case_street(self):
lattes_sector = Sector.objects.create(contact_email='lattes@montpellier3m.fr')

View File

@ -0,0 +1,100 @@
# -*- coding: utf-8 -*-
import csv
from collections import defaultdict
import StringIO
from django.core.mail import EmailMessage
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.template.loader import get_template, Context
from .models import Commune
prefix_map = {
'ALL': 'ALLEE',
'AUTO': 'AUTOROUTE',
'AV': 'AVENUE',
'BASS': 'BASSIN',
'BD': 'BOULEVARD',
'CAR': 'CARREFOUR',
'CHE': 'CHAUSSEE',
'COUR': 'COUR',
'CRS': 'COURS',
'DESC': 'DESCENTE',
'DOM': 'DOMAINE',
'ENCL': 'ENCLOS',
'ESP': 'ESPLANADE',
'ESPA': 'ESPACE',
'GR': '', # "GR GRAND-RUE JEAN MOULIN"
'IMP': 'IMPASSE',
'JARD': 'JARDIN',
'MAIL': '', # "MAIL LE GRAND MAIL"
'PARC': 'PARC',
'PARV': '', # "PARV PARVIS DE LA LEGION D HONNEUR"
'PAS': 'PASSAGE',
'PL': 'PLACE',
'PLAN': 'PLAN',
'PONT': 'PONT',
'QUA': 'QUAI',
'R': 'RUE',
'RAMB': '', # "RAMB RAMBLA DES CALISSONS"
'RPT': 'ROND-POINT',
'RTE': 'ROUTE',
'SQ': 'SQUARE',
'TSSE': '', # "TSSE TERRASSE DES ALLEES DU BOIS"
'TUN': 'TUNNEL',
'VIAD': 'VIADUC',
'VOI': 'VOIE',
}
def prefix_cleanup(name):
name = name.strip()
for prefix, full in prefix_map.items():
if name.startswith(prefix + ' '):
name = (full + name[len(prefix):]).strip()
return name
def get_sector(insee, address=None):
communes = Commune.objects.filter(insee=insee)
for commune in communes:
streets = commune.street_set.all()
if address and streets:
for s in streets:
if prefix_cleanup(s.name) in address.upper():
return commune.sector
else:
return commune.sector
def email_sectors(formdefs, when):
subject = get_template('passerelle_montpellier_encombrants/email_subject.txt')
message = get_template('passerelle_montpellier_encombrants/email_body.txt')
header = ('Adresse', 'Date', 'Volume',
'Type d\'encombrant', u'Téléphone', 'Commentaire')
sectors = defaultdict(list)
context = Context({'date': when})
for formdef in formdefs:
fields = formdef['fields']
data = [fields.get(d) for d in ('adresse', 'date',
'volume', 'type_encombrant',
'telephone', 'commentaire')]
sector = get_sector(fields.get('commune_raw'), fields.get('adresse'))
if sector:
sectors[sector.contact_email].append(data)
for destination, data in sectors.iteritems():
mail = EmailMessage(subject.render(context), message.render(context),
settings.DEFAULT_FROM_EMAIL, [destination])
attachement_body = StringIO.StringIO()
attachment = csv.writer(attachement_body)
attachment.writerow([e.encode("utf-8") for e in header])
for d in data:
attachment.writerow([e.encode("utf-8") for e in d])
mail.attach('demandes.csv', attachement_body.getvalue(), 'text/csv')
mail.send()

View File

@ -23,56 +23,14 @@ from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
from django.db import transaction
from passerelle import utils
from passerelle import utils as passerelle_utils
from .models import EncombrantsManagement, Sector, Commune, CollectDay, Street
from .forms import EncombrantsManagementForm, EncombrantsManagementUpdateForm, CommuneForm, StreetsForm
from .forms import EncombrantsManagementForm, EncombrantsManagementUpdateForm, CommuneForm
from .utils import prefix_cleanup, get_sector
prefix_map = {
'ALL': 'ALLEE',
'AUTO': 'AUTOROUTE',
'AV': 'AVENUE',
'BASS': 'BASSIN',
'BD': 'BOULEVARD',
'CAR': 'CARREFOUR',
'CHE': 'CHAUSSEE',
'COUR': 'COUR',
'CRS': 'COURS',
'DESC': 'DESCENTE',
'DOM': 'DOMAINE',
'ENCL': 'ENCLOS',
'ESP': 'ESPLANADE',
'ESPA': 'ESPACE',
'GR': '', # "GR GRAND-RUE JEAN MOULIN"
'IMP': 'IMPASSE',
'JARD': 'JARDIN',
'MAIL': '', # "MAIL LE GRAND MAIL"
'PARC': 'PARC',
'PARV': '', # "PARV PARVIS DE LA LEGION D HONNEUR"
'PAS': 'PASSAGE',
'PL': 'PLACE',
'PLAN': 'PLAN',
'PONT': 'PONT',
'QUA': 'QUAI',
'R': 'RUE',
'RAMB': '', # "RAMB RAMBLA DES CALISSONS"
'RPT': 'ROND-POINT',
'RTE': 'ROUTE',
'SQ': 'SQUARE',
'TSSE': '', # "TSSE TERRASSE DES ALLEES DU BOIS"
'TUN': 'TUNNEL',
'VIAD': 'VIADUC',
'VOI': 'VOIE',
}
def prefix_cleanup(name):
name = name.strip()
for prefix, full in prefix_map.items():
if name.startswith(prefix + ' '):
name = (full + name[len(prefix):]).strip()
return name
class EncombrantsManagementDetailView(DetailView):
model = EncombrantsManagement
template_name = 'passerelle_montpellier_encombrants/detail.html'
@ -183,27 +141,17 @@ class AvailableDaysView(View, SingleObjectMixin):
model = EncombrantsManagement
def get(self, request, *args, **kwargs):
address = request.GET.get('adresse')
collect_days = []
communes = Commune.objects.filter(insee=kwargs.get('insee'))
if not communes:
communes = Commune.objects.all()
for commune in communes:
days = commune.sector.collectday_set.filter(date__gt=datetime.datetime.today()+datetime.timedelta(days=1)).order_by('date')
if address and commune.street_set.all():
for s in commune.street_set.all():
if prefix_cleanup(s.name) in address.upper():
collect_days.extend(days)
break
else:
collect_days.extend(days)
sector = get_sector(kwargs.get('insee'), request.GET.get('adresse'))
if sector:
collect_days = sector.collectday_set.filter(date__gt=datetime.datetime.today()+datetime.timedelta(days=1)).order_by('date')
else:
collect_days = []
limit = request.GET.get('limit')
result = [{'id': x.date.strftime('%Y-%m-%d'),
'text': x.date.strftime('%d/%m/%Y')} for x in collect_days]
if limit:
result = result[:int(limit)]
return utils.response_for_json(request, {'data': result})
return passerelle_utils.response_for_json(request, {'data': result})
class StreetEditView(FormView):