This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
synchro-orleans/synchro_orleans/data/management/commands/email_new_invoices.py

136 lines
5.5 KiB
Python

# -*- coding: utf-8 -*-
from optparse import make_option
from datetime import datetime, timedelta
import json
import shutil
import os
import requests
import logging
from hashlib import sha256
import hmac
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.utils.timezone import make_aware, get_current_timezone
from django.db.models import Q
from django.template.loader import get_template
from django.template import Context
from django.core.mail import EmailMultiAlternatives
from synchro_orleans.data.models import Facture, InvoiceNotificationEmail
from synchro_orleans import signature
notification_timeout = settings.INVOICES_NOTIFICATION_TIMEOUT
invoice_view_url_base = settings.INVOICE_VIEW_URL_BASE
logger = logging.getLogger(__name__)
class Command(BaseCommand):
help = """
Sends email notifications about the invoices
"""
email_subject = 'Votre facture est disponible sur le portail citoyen'
email_from = settings.DEFAULT_FROM_EMAIL
secret = settings.INVOICE_HASHING_SECRET
option_list = BaseCommand.option_list + (
make_option('--list',
action='store_true',
default=False,
help='List outgoing emails in CSV format'),
make_option('--fake',
action='store_true',
default=False,
help='Fake emailing'),
make_option('--id',
action='store_true',
default=None,
help='Invoice\'s id to be emailed'),
make_option('--to',
action='store_true',
default=None,
help='Fake emailing destination'),
)
def get_invoice_hash(self, *args):
hash = hmac.HMAC(self.secret, digestmod=sha256, msg=''.join(map(lambda s: str(s), args)))
return hash.hexdigest()[:8]
def handle(self, *args, **options):
if options['list']:
print "destination;nr. facture;montant;montant regle"
queryset = Facture.objects.filter(Q(paye=False) | Q(date_reglement__isnull=True),
active=True, date_limite_paie__gte=datetime.now(),
famille__liaisonnameidfamille__isnull=False)
if options['fake']:
if not options['id']:
raise CommandError('An invoice id should be provided')
if not options['to']:
raise CommandError('A destination email should be provided')
queryset = queryset.filter(pk=options['id'])
for invoice in queryset:
try:
notification = InvoiceNotificationEmail.objects.filter(invoice_number=invoice.id).latest()
if notification.date_sent > make_aware(datetime.now(), get_current_timezone()) - timedelta(days=notification_timeout):
continue
except InvoiceNotificationEmail.DoesNotExist:
if not options['list'] or not options['fake']:
InvoiceNotificationEmail.objects.create(invoice_number=invoice.id)
nameid = invoice.famille.liaisonnameidfamille_set.all()[0]
signed_query = signature.sign_query('orig=synchro-orleans', settings.EMAILING_APIKEY)
url = '{url}/{nameid}?{query}'.format(url=settings.IDP_USER_INFO_URL,
nameid=nameid.name_id,
query=signed_query)
logger.debug('requesting: %s' % url)
response = requests.get(url)
try:
data = response.json()['data']
if not data:
raise ValueError
except (KeyError, ValueError):
continue
attachment = os.path.join(settings.INVOICES_DIR, 'facture_%s.pdf' % invoice.id)
invoice_hash = self.get_invoice_hash(invoice.id,
invoice.date_generation,
invoice.montant)
context = {'invoice': invoice, 'invoice_view_url_base': invoice_view_url_base,
'invoice_hash': invoice_hash}
context.update(data)
if invoice.prelevement_automatique:
email_template = 'autobilling_invoice_mail.txt'
elif invoice.solde == 0:
email_template = 'null_invoice_mail.txt'
elif invoice.solde < 1:
email_template = 'sub1_invoice_mail.txt'
else:
email_template = 'invoice_mail.txt'
if options['list']:
print "{email};{invoice.id};{invoice.montant};{invoice.montant_regle}".format(**context)
continue
context = Context(context)
text_body = get_template(email_template).render(context)
if options['fake']:
to = [options['to']]
else:
to = [data['email']]
message = EmailMultiAlternatives(self.email_subject, text_body, self.email_from, to)
message.attach_file(os.path.join(settings.INVOICES_DIR, 'facture_%s.pdf'% invoice.id))
message.send()
logger.debug('email for invoice nr. %s sent' % invoice.id)
invoice.date_envoi_dernier_mail = make_aware(datetime.now(), get_current_timezone())
InvoiceNotificationEmail.objects.create(invoice_number=invoice.id)
invoice.save()