from django.db.models import Q from django.utils import timezone from django.forms import widgets from django.utils.safestring import mark_safe # Ce widget permet d’afficher un champ de formulaire sous forme de texte class StringWidget(widgets.Input): def render(self, name, value, attrs=None): # Create a hidden field first hidden_field = widgets.HiddenInput(attrs) return mark_safe(u'%s %s' % (value, hidden_field.render(value, attrs))) # Cette fonction permet d’obtenir un filtre s’appliquant aux paiements et aux allocations de ressources def get_active_filter(prefix=''): if prefix and not prefix.endswith('__'): prefix += '__' now = timezone.now() # Début antérieur et fin non spécifié ou postérieur return Q(**{prefix + 'start__lte': now}) & (Q(**{prefix + 'end__isnull': True}) | Q(**{prefix + 'end__gte': now})) # Cette fonction vérifie que l’object « instance » ne chevauche pas temporellement un objet présent dans « queryset » # Le model associé doit posséder deux attributs « start » et « end ». # L’attribut « start » doit être obligatoire. def is_overlapping(instance, queryset): # Le champ « start » ne doit pas être None pour les comparaisons qui suivent if not instance.start: return False # Une erreur sera levé au niveau de ce field spécifiquement # S’il s’agit d’une modification et non d’un ajout, il faut ignorer l’objet déjà présent en db if instance.pk: queryset = queryset.exclude(pk=instance.pk) for existing in queryset.all(): if instance.end and existing.end: # Les deux périodes sont terminées latest_start = max(instance.start, existing.start) earliest_end = min(instance.end, existing.end) if earliest_end > latest_start: return True elif existing.end: assert(not instance.end) # La période existante est terminée et doit donc se terminer avant la modifiée if existing.end > instance.start: return True elif instance.end: assert(not existing.end) # La période existante n’est terminée, la modifiée doit se terminer avant if instance.end > existing.start: return True else: assert(not instance.end and not existing.end) # Aucune des périodes n’est terminées return True