34 |
34 |
from django.utils.translation import ugettext_lazy as _
|
35 |
35 |
from django.utils import timezone
|
36 |
36 |
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
|
37 |
from django.core.mail import EmailMultiAlternatives
|
|
38 |
from django.core.urlresolvers import reverse
|
37 |
39 |
from django.utils.http import urlencode
|
38 |
40 |
|
|
41 |
from django.contrib.auth.models import User
|
|
42 |
from django.template.loader import render_to_string
|
|
43 |
|
39 |
44 |
from combo.data.fields import RichTextField
|
40 |
45 |
from combo.data.models import CellBase
|
41 |
46 |
from combo.data.library import register_cell_class
|
42 |
47 |
from combo.utils import NothingInCacheException, aes_hex_encrypt, requests
|
|
48 |
from combo.apps.notifications.models import Notification
|
43 |
49 |
|
44 |
50 |
EXPIRED = 9999
|
45 |
51 |
|
... | ... | |
91 |
97 |
text_on_success = models.TextField(
|
92 |
98 |
verbose_name=_('Custom text displayed on success'),
|
93 |
99 |
blank=True, null=True)
|
|
100 |
invoice_email_notifications_delay = models.IntegerField(verbose_name=_('Delay after which email notifications will be resent'),
|
|
101 |
help_text=_('in days'), default=10)
|
94 |
102 |
|
95 |
103 |
def is_remote(self):
|
96 |
104 |
return self.webservice_url != ''
|
... | ... | |
203 |
211 |
extra_fee=True,
|
204 |
212 |
user_cancellable=False).save()
|
205 |
213 |
|
|
214 |
def notify_new_remote_invoices(self):
|
|
215 |
if not self.is_remote():
|
|
216 |
return
|
|
217 |
|
|
218 |
logger = logging.getLogger(__name__)
|
|
219 |
url = self.webservice_url + '/users/with-pending-invoices/'
|
|
220 |
response = requests.get(url, remote_service=None, cache_duration=0)
|
|
221 |
data = response.json()['data']
|
|
222 |
if not data:
|
|
223 |
return
|
|
224 |
now = timezone.now()
|
|
225 |
for uuid, items in data.iteritems():
|
|
226 |
try:
|
|
227 |
user = User.objects.get(username=uuid)
|
|
228 |
except User.DoesNotExist:
|
|
229 |
logger.warning('Invoices available for unknown user: %s', uuid)
|
|
230 |
continue
|
|
231 |
for invoice in items['invoices']:
|
|
232 |
invoice_id = '%s-%s' % (self.slug, invoice['id'])
|
|
233 |
notification = Notification.objects.filter(models.Q(end_timestamp__lt=now) | models.Q(acked=False),
|
|
234 |
external_id=invoice, user=user, summary=invoice['label']).last()
|
|
235 |
if notification:
|
|
236 |
continue
|
|
237 |
duration = timezone.timedelta(days=self.invoice_email_notifications_delay)
|
|
238 |
Notification.notify(user, summary=invoice['label'], id=invoice_id, start_timestamp=now,
|
|
239 |
duration=duration)
|
|
240 |
self.notify_remote_invoice_by_email(user, invoice)
|
|
241 |
|
|
242 |
def notify_remote_invoice_by_email(self, user, invoice):
|
|
243 |
|
|
244 |
subject_template = 'lingo/combo/invoice_email_notification_subject.txt'
|
|
245 |
text_body_template = 'lingo/combo/invoice_email_notification_body.txt'
|
|
246 |
html_body_template = 'lingo/combo/invoice_email_notification_body.html'
|
|
247 |
|
|
248 |
remote_item = build_remote_item(invoice, self)
|
|
249 |
payment_url = reverse('view-item', kwargs={'regie_id': self.id,
|
|
250 |
'item_crypto_id': remote_item.crypto_id})
|
|
251 |
ctx = {'item': remote_item}
|
|
252 |
# update context with template vars in order to get things such
|
|
253 |
# portal title and url
|
|
254 |
ctx.update(settings.TEMPLATE_VARS)
|
|
255 |
ctx.update({'payment_url': urlparse.urljoin(ctx['portal_url'], payment_url)})
|
|
256 |
subject = render_to_string([subject_template], ctx).strip()
|
|
257 |
text_body = render_to_string([text_body_template], ctx)
|
|
258 |
html_body = render_to_string([html_body_template], ctx)
|
|
259 |
message = EmailMultiAlternatives(subject, text_body,
|
|
260 |
settings.DEFAULT_FROM_EMAIL, [user.email])
|
|
261 |
message.attach_alternative(html_body, 'text/html')
|
|
262 |
if invoice['has_pdf']:
|
|
263 |
invoice_pdf = self.get_invoice_pdf(user, invoice['id'])
|
|
264 |
message.attach('%s.pdf' % invoice['id'], invoice_pdf.content)
|
|
265 |
message.send()
|
|
266 |
|
206 |
267 |
|
207 |
268 |
class BasketItem(models.Model):
|
208 |
269 |
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
|
... | ... | |
280 |
341 |
self.display_id = display_id or self.id
|
281 |
342 |
self.subject = subject
|
282 |
343 |
self.has_pdf = has_pdf
|
283 |
|
self.online_payment = online_payment
|
|
344 |
self.online_payment = online_payment and self.amount >= regie.payment_min_amount
|
284 |
345 |
self.paid = paid
|
285 |
346 |
self.no_online_payment_reason = no_online_payment_reason
|
286 |
347 |
if payment_date:
|