# -*- coding: utf-8 -*-
"""
PolyNum

Définition des entités administratives
"""

from django.db import models
from django.utils.translation import ugettext_lazy as _

class EntityType(models.Model):

    class Meta:
        app_label = 'base'
        verbose_name = _(u"Type d'entité administrative")
        verbose_name_plural = _(u"Type d'entités administratives")

    def __unicode__(self):
        return u'%s (%s)' % (self.description, self.name)

    name = models.CharField(max_length=128, verbose_name=_(u'Nom'))
    description = models.TextField(verbose_name=_(u'Description'), blank=True)

class Entity(models.Model):

    class Meta:
        app_label = 'base'
        verbose_name = _(u'Entité administrative')
        verbose_name_plural = _(u'Entités administratives')
        ordering = ('left_bound',)

    def __unicode__(self):
        return self.get_description() or self.get_name()

    code = models.CharField(max_length=64, verbose_name=_(u'Code'), db_index=True)
    is_active = models.BooleanField(verbose_name=_(u'Active'), default=True, blank=True, db_index=True)
    name = models.CharField(max_length=128, verbose_name=_(u'Nom'), blank=True, db_index=True)
    description = models.TextField(verbose_name=_(u'Description'), blank=True, db_index=True)
    types = models.ManyToManyField(EntityType, null=True, blank=True)
    name_override = models.CharField(max_length=128, verbose_name=_(u'Nom spécifique PolyNum'), blank=True, db_index=True)
    description_override = models.TextField(verbose_name=_(u'Description spécifique PolyNum'), blank=True, db_index=True)
    depth = models.PositiveIntegerField(verbose_name=_('Niveau'), default=0, db_index=True)
    left_bound = models.PositiveIntegerField(unique=True, db_index=True)
    right_bound = models.PositiveIntegerField(unique=True, db_index=True)

    def children(self, included=False):
        if included:
            return Entity.objects.filter(left_bound__lt=self.right_bound, left_bound__gte=self.left_bound)
        else:
            return Entity.objects.filter(left_bound__lt=self.right_bound, left_bound__gt=self.left_bound)

    def parents(self, included=False):
        if included:
            return Entity.objects.filter(left_bound__lte=self.left_bound, right_bound__gte=self.right_bound)
        else:
            return Entity.objects.filter(left_bound__lt=self.left_bound, right_bound__gt=self.right_bound)

    def accounting_codes(self):
        '''
        return a set of "accounting" codes: one of the entity and those of all its parents
        '''
        for parent in self.parents(included=True).order_by('-depth').prefetch_related('accountingcode_set'):
            if parent.accountingcode_set.all():
                return parent.accountingcode_set.all()
        return AccountingCode.objects.none()

    def get_name(self):
        return self.name_override or self.name
    get_name.short_description = _(u'Nom')

    def get_description(self):
        return self.description_override or self.description
    get_description.short_description = _(u'Description')

class AccountingCode(models.Model):
    class Meta:
        app_label = 'base'
        verbose_name = _(u'Code de comptabilité/financier')
        verbose_name_plural = _(u'Codes de comptabilité/financier')
        ordering = ('entity', 'code')

    entity = models.ForeignKey(Entity)
    code = models.CharField(max_length=32, verbose_name=_('Code financier'), db_index=True)
