Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
fun-apps / payment / models.py
Size: Mime:
# -*- coding: utf-8 -*-

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import get_language, ugettext_lazy as _
from django.conf import settings
from docutils.core import publish_string
from pyquery import PyQuery as S
import datetime

PAYMENT_TERMS = 'verified_certificate'
MARKER = object()
## Seen with legal department it is the language of the juridiction that
## mmanages the hosting
DEFAULT_LANGUAGE = "fr"
DEFAULT_LANGUAGE_NAME = _("French")

TERMS_TEMPLATE = """
.. Ce champs est dans un format ReST (comme un wiki)
.. Ceci est un commentaire
.. http://deusyss.developpez.com/tutoriels/Python/SphinxDoc/#LIV-G


.. Les 4 lignes finales (honor, privacy, tos, legal)
.. permettent la navigation dans le contrat au niveau des ancres
.. Prière de les insérer avant les titres correspondant
.. honor = Charte utilisateurs
.. privacy = Politique de confidentialité
.. tos = Conditions générales d'utilisation
.. legal =  Mentions légales

.. Ces commentaires ci dessus peuvent être retirés
.. ils sont juste là comme aide mémoire :)


.. _honor:

.. _privacy:

.. _tos:

.. _legal:

"""


class TermsAndConditions(models.Model):
    name = models.CharField(
        max_length=100, verbose_name=_(u"Name"),
        default=PAYMENT_TERMS, db_index=True,
    )
    version = models.CharField(max_length=12, verbose_name=_(u"Terms and conditions version (semver)"))
    datetime = models.DateTimeField(default=datetime.datetime.now, verbose_name=_(u"Acceptance date"), db_index=True)

    def __unicode__(self):
        return u"%s v%s" % (self.name, self.version)

    class Meta:
        verbose_name = _(u"Terms and conditions")
        verbose_name_plural = _(u"Terms and conditions")
        ordering = ('-datetime',)

    @property
    def text(self):
        """
        use django i18n mechanism to search for the right translation to
        present to the user. (order = user settings, cookies ...)
        Defaults to the one of reference for the country of reference if None
        available
        """
        language = get_language()
        just_in_case = ""
        to_return = None, None
        for translated_term in self.texts.all():
            if translated_term.language == language and len(translated_term.tr_text):
                to_return = unicode(translated_term.tr_text), translated_term.language
            if translated_term.language == DEFAULT_LANGUAGE:
                just_in_case = unicode(translated_term.tr_text),DEFAULT_LANGUAGE
        ## walking around ReST generating a 4.1 full html doc
        ## Accessibility
        text, lang = to_return if to_return[0] else just_in_case
        res = S(
            "body",
            publish_string(text, writer_name='html'),
            parser='html')
        res.remove_namespaces()
        res(".document").attr["lang"] = lang
        return res.html()

    @classmethod
    def version_accepted(cls, name, user):
        try:
            return UserAcceptance.objects.select_related("terms").filter(
                terms__name=name, user=user).latest('datetime')
        except UserAcceptance.DoesNotExist:
            return None

    @classmethod
    def get_latest(cls, name=MARKER, language=MARKER):
        if name is MARKER:
            name = PAYMENT_TERMS
        try:
            return TermsAndConditions.objects.filter(name=name).latest('datetime')
        except TermsAndConditions.DoesNotExist:
            return None

    @classmethod
    def user_has_to_accept_new_version(cls, name, user):
        # if name is None take the one that values
        name = name or PAYMENT_TERMS
        latest = TermsAndConditions.get_latest(name=name)
        if latest is None:
            return False  # terms do not exists yet, user is ok
        if latest.version == '0':  # terms of version 0 are considered as accepted
            return False
        try:
            accepted = TermsAndConditions.version_accepted(name, user)
        except TypeError:
            # TypeError
            # int() argument must be a string or a number, not 'SimpleLazyObject'
            # seems to me a bug of lazy loading or session hence the select related
            # ~ line 102
            # we are permissive here
            return False

        if accepted and accepted.terms.version == latest.version:
            return False   # user already has accepted latest version
        else:
            return latest  # user has to accept latest version

    def accept(self, user):
        accepted, created = UserAcceptance.objects.get_or_create(terms=self, user=user)
        if not created:
            if accepted.terms == self:
                return False  # user has already accepted those terms
            accepted.terms = self  # update accepted version
            accepted.save()
        return True


class UserAcceptance(models.Model):
    user = models.ForeignKey(User, related_name='terms_accepted')
    terms = models.ForeignKey(TermsAndConditions, related_name='accepted')
    datetime = models.DateTimeField(auto_now=True, verbose_name=_(u"Acceptance date"), db_index=True)

    def __unicode__(self):
        return u"%s: %s v%s" % (self.user.username, self.terms.name, self.terms.version)

    class Meta:
        verbose_name = _(u"User terms and conditions acceptance")
        unique_together = ['user', 'terms']

def legal_acceptance(user):
    COMPLIANT, NOT_COMPLIANT = True, False
    if user.is_anonymous():
        return COMPLIANT
    latest = TermsAndConditions.get_latest()
    if latest is None or latest == TERMS_TEMPLATE:
        return COMPLIANT
    try:
        latest_acceptation = UserAcceptance.objects.get(
            terms=latest,
            user=user,
        )
    except UserAcceptance.DoesNotExist:
        return NOT_COMPLIANT
    return COMPLIANT

class TranslatedTerms(models.Model):
    """Terms and conditions might have to be made available to
    any students for whom we support their language.
    """
    # XXX: use the same language as Studio
    tr_text = models.TextField(
        verbose_name=_(u"Terms and conditions.") + u" (ReStructured Text)",
        default=TERMS_TEMPLATE,
    )
    language = models.CharField(
        max_length=5,
        verbose_name=_(u"Language"),
        choices=settings.LANGUAGES,
        default={_("french"): "fr"}
    )
    term = models.ForeignKey(
        TermsAndConditions,
        related_name="texts",
        on_delete=models.CASCADE
    )
    def __repr__(slef):
        return u"term %d - %s" % (slef.term.id, slef.language)

    class Meta:
        unique_together = (('term', 'language', ), )