# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from datetime import datetime, timedelta
+import os
+import tempfile
from django.apps import apps
from django.conf import settings
from django.contrib.sites.models import Site
-from django.core.mail import send_mail
+from django.core.mail import send_mail, EmailMessage
from django.urls import reverse
from django.db import models
from django import template
from django.utils.translation import ugettext_lazy as _, ungettext, ugettext, get_language
from catalogue.utils import get_random_hash
from messaging.states import Level
+from reporting.utils import render_to_pdf
from .payment_methods import recurring_payment_method, single_payment_method
from .payu import models as payu_models
from . import utils
amount = models.DecimalField(_('amount'), max_digits=10, decimal_places=2)
monthly = models.BooleanField(_('monthly'), default=True)
yearly = models.BooleanField(_('yearly'), default=False)
-
+
+ source = models.CharField(_('source'), max_length=255, blank=True)
+
is_cancelled = models.BooleanField(_('cancelled'), default=False)
payed_at = models.DateTimeField(_('payed at'), null=True, blank=True)
started_at = models.DateTimeField(_('started at'), auto_now_add=True)
""" Represents a user being recognized as a member of the club. """
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.CASCADE)
created_at = models.DateTimeField(_('created at'), auto_now_add=True)
- name = models.CharField(max_length=255, blank=True)
- honorary = models.BooleanField(default=False)
+ name = models.CharField(_('name'), max_length=255, blank=True)
+ manual = models.BooleanField(_('manual'), default=False)
+ notes = models.CharField(_('notes'), max_length=2048, blank=True)
+ updated_at = models.DateField(_('updated at'), auto_now=True, blank=True)
class Meta:
verbose_name = _('membership')
def __str__(self):
return str(self.user)
+ def save(self, *args, **kwargs):
+ super().save(*args, **kwargs)
+ self.update_contact()
+
+ def update_contact(self):
+ email = self.user.email
+ if not email:
+ return
+
+ Contact = apps.get_model('messaging', 'Contact')
+ if self.manual:
+ Contact.update(email, Level.MANUAL_MEMBER, self.updated_at)
+ else:
+ Contact.reset(email)
+
@classmethod
def is_active_for(cls, user):
if user.is_anonymous:
membership = user.membership
except cls.DoesNotExist:
return False
- if membership.honorary:
+ if membership.manual:
return True
return Schedule.objects.filter(
expires_at__gt=now(),
self.schedule.get_thanks_url())
def get_description(self):
- return ugettext('Towarzystwo Wolnych Lektur')
+ return ugettext('Towarzystwo Przyjaciół Wolnych Lektur')
def is_recurring(self):
return self.schedule.get_payment_method().is_recurring
if not self.schedule.email_sent:
self.schedule.send_email()
+ @classmethod
+ def send_receipt(cls, email, year):
+ Contact = apps.get_model('messaging', 'Contact')
+ Funding = apps.get_model('funding', 'Funding')
+ payments = []
+
+ try:
+ contact = Contact.objects.get(email=email)
+ except Contact.DoesNotExist:
+ funding = Funding.objects.filter(
+ email=email,
+ payed_at__year=year,
+ notifications=True).order_by('payed_at').first()
+ if funding is None:
+ print('no notifications')
+ return
+ optout = funding.wl_optout_url()
+ else:
+ if contact.level == Level.OPT_OUT:
+ print('opt-out')
+ return
+ optout = contact.wl_optout_url()
+
+ qs = cls.objects.filter(status='COMPLETED', schedule__email=email, completed_at__year=year).order_by('completed_at')
+ for order in qs:
+ payments.append({
+ 'timestamp': order.completed_at,
+ 'amount': order.get_amount(),
+ })
+
+ fundings = Funding.objects.filter(
+ email=email,
+ payed_at__year=year
+ ).order_by('payed_at')
+ for funding in fundings:
+ payments.append({
+ 'timestamp': funding.payed_at,
+ 'amount': funding.amount,
+ })
+
+ if not payments: return
+
+ payments.sort(key=lambda x: x['timestamp'])
+
+ ctx = {
+ "email": email,
+ "year": year,
+ "next_year": year + 1,
+ "total": sum(x['amount'] for x in payments),
+ "payments": payments,
+ "optout": optout,
+ }
+ temp = tempfile.NamedTemporaryFile(prefix='receipt-', suffix='.pdf', delete=False)
+ temp.close()
+ render_to_pdf(temp.name, 'club/receipt.texml', ctx, {
+ "fnp.eps": os.path.join(settings.STATIC_ROOT, "img/fnp.eps"),
+ })
+
+ message = EmailMessage(
+ f'Odlicz od podatku swoje darowizny przekazane dla Wolnych Lektur',
+ template.loader.render_to_string('club/receipt_email.txt', ctx),
+ settings.CONTACT_EMAIL, [email]
+ )
+ with open(temp.name, 'rb') as f:
+ message.attach('wolnelektury-darowizny.pdf', f.read(), 'application/pdf')
+ message.send()
+ os.unlink(f.name)
+
class PayUCardToken(payu_models.CardToken):
schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE)