Projet

Général

Profil

0002-lingo-send-emails-when-notifying-new-invoices-13122.patch

Voir les différences:

Subject: [PATCH 2/6] lingo: send emails when notifying new invoices (#13122)

 combo/apps/lingo/models.py                         | 28 ++++++++++++++++-
 .../combo/invoice_email_notification_body.html     | 20 ++++++++++++
 .../combo/invoice_email_notification_body.txt      | 12 ++++++++
 .../combo/invoice_email_notification_subject.txt   | 10 ++++++
 combo/settings.py                                  |  3 ++
 tests/test_lingo_remote_regie.py                   | 36 ++++++++++++++++++++++
 6 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 combo/apps/lingo/templates/lingo/combo/invoice_email_notification_body.html
 create mode 100644 combo/apps/lingo/templates/lingo/combo/invoice_email_notification_body.txt
 create mode 100644 combo/apps/lingo/templates/lingo/combo/invoice_email_notification_subject.txt
combo/apps/lingo/models.py
33 33
from django.forms import models as model_forms, Select
34 34
from django.utils.translation import ugettext_lazy as _
35 35
from django.utils import timezone, dateparse
36
from django.core.mail import EmailMultiAlternatives
37
from django.core.urlresolvers import reverse
36 38
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
37 39
from django.utils.http import urlencode
38 40

  
39 41
from django.contrib.auth.models import User
42
from django.template.loader import render_to_string
40 43

  
41 44
from combo.data.fields import RichTextField
42 45
from combo.data.models import CellBase
......
239 242
                    notification = Notification.objects.filter_by_id(invoice_id).filter(user=user).last()
240 243
                    if notification.end_timestamp < timezone.now():
241 244
                        remind_id = 'remind-%s' % invoice_id
242
                        Notification.notify(user, _('Reminder: invoice %s to pay') % invoice['label'],
245
                        notification, created = Notification.notify(user, _('Reminder: invoice %s to pay') % invoice['label'],
243 246
                                            id=remind_id, end_timestamp=notification_end_timestamp)
247
                if created:
248
                    self.notify_remote_invoice_by_email(user, invoice)
249

  
250
    def notify_remote_invoice_by_email(self, user, invoice):
251

  
252
        subject_template = 'lingo/combo/invoice_email_notification_subject.txt'
253
        text_body_template = 'lingo/combo/invoice_email_notification_body.txt'
254
        html_body_template = 'lingo/combo/invoice_email_notification_body.html'
255

  
256
        remote_item = build_remote_item(invoice, self)
257
        payment_url = reverse('view-item', kwargs={'regie_id': self.id,
258
                            'item_crypto_id': remote_item.crypto_id})
259
        ctx = {'item': remote_item}
260
        ctx.update({'payment_url': urlparse.urljoin(settings.SITE_BASE_URL, payment_url)})
261
        subject = render_to_string([subject_template], ctx).strip()
262
        text_body = render_to_string([text_body_template], ctx)
263
        html_body = render_to_string([html_body_template], ctx)
264
        message = EmailMultiAlternatives(subject, text_body, to=[user.email])
265
        message.attach_alternative(html_body, 'text/html')
266
        if invoice['has_pdf']:
267
            invoice_pdf = self.get_invoice_pdf(user, invoice['id'])
268
            message.attach('%s.pdf' % invoice['id'], invoice_pdf.content, 'application/pdf')
269
        message.send()
244 270

  
245 271

  
246 272
class BasketItem(models.Model):
combo/apps/lingo/templates/lingo/combo/invoice_email_notification_body.html
1
{% load i18n %}
2

  
3
<html>
4
  <body style="max-width: 60em">
5
    <p>{% blocktrans with id=item.id creation_date=item.creation_date|date:"DATE_FORMAT" amount=item.amount %}
6
      We inform you that your invoice nr. {{ id }} issued on {{ creation_date }} of amount of {{ amount }}€ is available on {{ site_title }}.
7
      {% endblocktrans %}</p>
8
    {% if item.online_payment %}
9
    <p>{% blocktrans %}You can <a href="{{ payment_url }}">view and pay it online</a>.{% endblocktrans %}</p>
10
    {% else %}
11
    <p>{% blocktrans %}You can view it by going on your <a href="{{ portal_url }}">{{ site_title }}</a>.{% endblocktrans %}</p>
12
    {% if item.no_online_payment_reason == 'autobilling' %}
13
    <p>{% blocktrans with debit_date=item.payment_limit_date|date:"DATE_FORMAT" %}
14
      The amount of this invoice will be debited from your account at {{ debit_date }}.
15
      {% endblocktrans %}
16
    </p>
17
    {% endif %}
18
    {% endif %}
19
  </body>
20
</html>
combo/apps/lingo/templates/lingo/combo/invoice_email_notification_body.txt
1
{% load i18n %}
2
{% blocktrans with id=item.id creation_date=item.creation_date|date:"DATE_FORMAT" amount=item.amount %}We inform you that your invoice nr. {{ id }} issued on {{ creation_date }} of amount of {{ amount }}€ is available on {{ site_title }}.{% endblocktrans %}
3

  
4
{% if item.online_payment %}
5
{% blocktrans %}You can view and pay it online on {{ payment_url }}.{% endblocktrans %}
6
{% else %}{% blocktrans %}You can view it by going on {{ portal_url }}.{% endblocktrans %}
7

  
8
{% if item.no_online_payment_reason == 'autobilling' %}
9
{% blocktrans with debit_date=item.payment_limit_date|date:"DATE_FORMAT" %}The amount of this invoice will be debited from your account at {{ debit_date }}.{% endblocktrans %}
10
{% endif %}
11
{% endif %}
12

  
combo/apps/lingo/templates/lingo/combo/invoice_email_notification_subject.txt
1
{% load i18n %}
2
{% if site_title %}
3
{% blocktrans with invoice_id=item.id %}
4
{{ site_title }}: new invoice nr. {{ invoice_id }} is available
5
{% endblocktrans %}
6
{% else %}
7
{% blocktrans with invoice_id=item.id %}
8
New invoice nr. {{ invoice_id }} is available
9
{% endblocktrans %}
10
{% endif %}
combo/settings.py
282 282
# default delay for invoice payment notifications in days
283 283
LINGO_NEW_INVOICES_NOTIFICATION_DELAY = 10
284 284

  
285
# default site
286
SITE_BASE_URL = 'http://localhost'
287

  
285 288
# timeout used in python-requests call, in seconds
286 289
# we use 28s by default: timeout just before web server, which is usually 30s
287 290
REQUESTS_TIMEOUT = 28
tests/test_lingo_remote_regie.py
9 9
from django.core.urlresolvers import reverse
10 10
from django.conf import settings
11 11
from django.core.management import call_command
12
from django.utils.timezone import timedelta, now
13
from django.contrib.auth.models import User
12 14

  
13 15
from combo.utils import check_query, aes_hex_encrypt
14 16
from combo.data.models import Page
......
36 38
    },
37 39
]
38 40

  
41
@pytest.fixture
42
def user():
43
    try:
44
        admin = User.objects.get(username='foo')
45
    except User.DoesNotExist:
46
        admin = User.objects.create_user('foo', email=None, password='bar')
47
    admin.email = 'foo@example.net'
48
    admin.save()
49
    return admin
50

  
39 51
@pytest.fixture
40 52
def remote_regie():
41 53
    try:
......
336 348
    assert Transaction.objects.all()[0].to_be_paid_remote_items is None
337 349

  
338 350
    call_command('update_transactions')
351

  
352
@mock.patch('combo.apps.lingo.models.requests.get')
353
def test_send_new_remote_invoices_by_email(mock_get, user, app, remote_regie, mailoutbox):
354
    datetime_format = '%Y-%m-%dT%H:%M:%S'
355
    invoice_now = now()
356
    creation_date = (invoice_now - timedelta(days=1)).strftime(datetime_format)
357
    pay_limit_date = (invoice_now + timedelta(days=30)).strftime(datetime_format)
358
    FAKE_PENDING_INVOICES = {
359
        'data' :  {'foo': {'invoices': [{'id': '01', 'label': '010101', 'paid': False,
360
                        'amount': '37.26',  'total_amount': '37.26', 'online_payment': True,
361
                        'has_pdf': True, 'created': creation_date,
362
                        'pay_limit_date': pay_limit_date}]},
363
        }
364
    }
365
    mock_response = mock.Mock(status_code=200, content=json.dumps(FAKE_PENDING_INVOICES))
366
    mock_response.json.return_value = FAKE_PENDING_INVOICES
367
    mock_get.return_value = mock_response
368
    remote_regie.notify_new_remote_invoices()
369
    assert len(mailoutbox) == 1
370
    assert mailoutbox[0].recipients() == ['foo@example.net']
371
    assert mailoutbox[0].from_email == settings.DEFAULT_FROM_EMAIL
372
    assert mailoutbox[0].subject == 'New invoice nr. 01 is available'
373
    assert mailoutbox[0].attachments[0][0] == '01.pdf'
374
    assert mailoutbox[0].attachments[0][2] == 'application/pdf'
339
-