class ExemplaireVenteForm(ModelForm):

    exclude = ( 'actif', 'livre', 'etat',)

    isbn = CharField(required=True, 
                        help_text="Scannez le code barre du livre",
                        label="ISBN",
                        max_length=13)

    titre = CharField(required=True, 
                      label="Titre",
                      help_text="Titre")

    identifiant = IntegerField(required=True, 
                      label="Identifiant",
                      help_text="Identifiant",
                      widget=IdentifiantTextInput)

    auteur = CharField(required=True, 
                       label="Auteur",
                       help_text="Auteur")
    
    prix = DecimalField(required=True, 
                        label="Prix demandé",
                        help_text="Prix")

    def clean(self):
        cleaned_data = super(ExemplaireVenteForm, self).clean()
        self.instance = Exemplaire.objects.get(pk=cleaned_data['identifiant'])
        self.instance.etat = 'VEND'
        self.instance.save()
        return cleaned_data

    class Meta:
        model = Exemplaire class ExemplaireReceptionForm(ModelForm):
    exclude = ( 'actif', 'livre', 'etat',)

    isbn = CharField(
                     required=True, 
                     help_text="Scannez le code barre du livre",
                     label="ISBN",
                     widget=IsbnTextInput,
                     max_length=13
                    )

    titre = CharField(required=True, 
                      label="Titre",
                      help_text="Titre")

    auteur = CharField(required=True, 
                       label="Auteur",
                       help_text="Auteur")
    
    def clean(self):
        cleaned_data = super(ExemplaireReceptionForm, self).clean()
        
        livre, created = Livre.objects.get_or_create(isbn=cleaned_data.get('isbn'))
        if created:
            livre.auteur = cleaned_data.get('auteur')
            livre.titre = cleaned_data.get('titre')

        livre.save()
        self.instance.livre = livre
        
        return cleaned_data

    class Meta:
        model = Exemplaire class Vendeur(Metadata):
    class Meta:
        verbose_name = "Vendeur (Vrai)"
        verbose_name_plural = "Vendeurs (Vrai)"

    # En attendant les scanners, ce champ est inutile.
    #code_carte_etudiante = models.IntegerField(null=False, blank=False,
                                       #verbose_name="Code carte étudiante",
                                       #help_text="Scannez la carte étudiante")
    nom = models.CharField(max_length=255)
    prenom = models.CharField(max_length=255, verbose_name='Prénom', )
    code_permanent = models.CharField(max_length=12)
    email = models.EmailField(max_length=255, blank=False)
    telephone = models.CharField(max_length=255, verbose_name='Téléphone',
                                 blank=True)

    def __unicode__(self):
        return '%s, %s' % (self.nom, self.prenom)

    def nb_livres(self):
        return self.exemplaires.count()
    nb_livres.short_description = 'Nombre de livres'

    def envoyer_recu(self):
        '''
        lorsque le vendeur apporte des livres, on envoie le contrat par email.
        '''
        plaintext = get_template('encefal/vendeur/initial.txt')
        htmly     = get_template('encefal/vendeur/initial.html')

        d = Context({ 'vendeur': self })

        subject, from_email, to = 'contrat', 'aess@aessuqam.org', self.email
        text_content = plaintext.render(d)
        html_content = htmly.render(d)
        msg = EmailMultiAlternatives(subject, text_content, from_email, [to],)
        msg.attach_alternative(html_content, "text/html")
        msg.send(fail_silently=True) class Session(Metadata):
    nom = models.CharField(max_length=255, unique=True, )
    date_debut = models.DateField(verbose_name="Date début",
                             help_text=HELP_TEXT_FORMAT_DATE, null=True, blank=True)
    date_fin = models.DateField(help_text=HELP_TEXT_FORMAT_DATE, null=True, blank=True)

    def __unicode__(self):
        return '%s' % (self.nom)

    @staticmethod
    def next_session():
        reponse = Session.objects.filter(date_debut__gte=datetime.date.today())
        if not reponse.count():
            return None
        else:
            return reponse.order_by('date_debut')[0]

    @staticmethod
    def current_session():
        try:
            reponse = Session.objects.get(date_debut__lte=datetime.date.today(),
                                       date_fin__gte=datetime.date.today())
        except Session.DoesNotExist:
            reponse = None

        return reponse

    @staticmethod
    def session_null():
        return Session.objects.get(nom="/dev/null") class Livre(Metadata):
    vendeur = models.ManyToManyField(Vendeur, db_column='vendeur',
                                     related_name='livres', through='Exemplaire')
    isbn = models.CharField(max_length=13, blank=True, null=False, unique=True)
    titre = models.CharField(max_length=255, blank=True, )
    auteur = models.CharField(max_length=255, blank=True)
    edition = models.PositiveIntegerField(verbose_name='Édition', default=1,
                                          blank=True, null=False,)

    def exemplaires_en_vente(self):
        return [e for e in self.exemplaires.all() if e.etat == 'VENT']
    exemplaires_en_vente.short_description = 'Exemplaires en vente'

    def nb_exemplaires_en_vente(self):
        return len(self.exemplaires_en_vente())
    nb_exemplaires_en_vente.short_description = 'Nombre d\'exemplaires en vente'

    def prix_moyen(self):
        exemplaires = self.exemplaires_en_vente()
        return (sum([e.prix for e in exemplaires]) / len(exemplaires))

    def __unicode__(self):
      return '%s [%s]' % (self.titre, self.auteur) class Facture(Metadata):
    employe = models.ForeignKey(User, db_column='employe',
                                related_name='factures',blank=True)
    session = models.ForeignKey(Session, db_column='session',
                                related_name='factures',blank=True)

    def __unicode__(self):
      return 'Facture #%s' % (self.id)

    def nb_livres(self):
        return self.exemplaires.count()
    nb_livres.short_description = 'Nombre de livres'

    def prix_total(self):
        return sum([e.prix for e in self.exemplaires.all()]) or 0
    prix_total.short_description = 'Prix total de la facture' ETAT_LIVRE_CHOICES = (
    ('VENT', 'En vente'),
    ('VEND', 'Vendu'),
    ('PERD', 'Perdu'),
    ('VOLE', 'Volé'),
    ('REND', 'Rendu'),
    ('REMB', 'Remboursé'),
) class Exemplaire(Metadata):
    facture = models.ForeignKey(Facture, db_column='facture',
                                related_name='exemplaires', null=True,
                                blank=True)
    livre = models.ForeignKey(Livre, db_column='livre',
                              related_name='exemplaires',)
    vendeur = models.ForeignKey(Vendeur, db_column='vendeur',
                                related_name='exemplaires',)
    etat = models.CharField(max_length=4, choices=ETAT_LIVRE_CHOICES,
                            default='VENT', verbose_name='État', )
    prix = models.IntegerField(help_text="Le prix doit être un entier!")

    def __unicode__(self):
        return self.livre.__unicode__()

    def titre(self):
        return (self.livre.titre)
    titre.short_description = 'Titre'

    def code_permanent_vendeur(self):
        return (self.vendeur.code_permanent)
    code_permanent_vendeur.short_description = 'Vendeur'

    def save(self,*args,**kwargs):

        code_permanent = self.vendeur.code_permanent
        pk_vendeur_temp = self.vendeur.id
        vendeur = None

        try:
            self.vendeur = (
                            Vendeur.objects.all().
                            exclude(pk=pk_vendeur_temp).
                            get(code_permanent=code_permanent)
                           )
        except Vendeur.DoesNotExist:
            pass

        super(Exemplaire,self).save(*args,**kwargs) class Reception(Vendeur):
    class Meta:
        proxy = True
        verbose_name = "Vendeur"
        verbose_name_plural = "Vendeurs"

    def __unicode__(self):
        return ("Reception de livres de " + self.nom + ', ' + self.prenom) class Vente(Facture):
    class Meta:
        proxy = True

    def __unicode__(self):
        return "" class Facture(Metadata):
    employe = models.ForeignKey(User, db_column='employe',
                                related_name='factures',blank=True)
    session = models.ForeignKey(Session, db_column='session',
                                related_name='factures',blank=True)

    def __unicode__(self):
      return 'Facture #%s' % (self.id)

    def nb_livres(self):
        return self.exemplaires.count()
    nb_livres.short_description = 'Nombre de livres'

    def prix_total(self):
        return sum([e.prix for e in self.exemplaires.all()]) or 0
    prix_total.short_description = 'Prix total de la facture'
import datetime
import pdb
from django.contrib import admin
from django.core.urlresolvers import reverse
from django import forms
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import Context
from project.encefal.forms import (
                                   ExemplaireVenteForm,
                                   ExemplaireReceptionForm,
                                  )
from project.encefal.models import (
                                    Vendeur, Session,
                                    Livre, Facture,
                                    ETAT_LIVRE_CHOICES,
                                    Exemplaire, Reception,
                                    Vente, Facture
                                   )
        # Afficher recu
        try:
            vendeur = Vendeur.objects.all().exclude(pk=obj.pk).get(code_permanent=obj.code_permanent)
            context['vendeur'] = vendeur
            context['exemplaires'] = vendeur.exemplaires.filter(date_creation__startswith=datetime.date.today())

        except Vendeur.DoesNotExist:
            context['vendeur'] = obj
            context['exemplaires'] = obj.exemplaires.all()

        context['date_transaction'] = datetime.date.today()
        context['employe'] = request.user.username
        context['montant_total'] = sum([e.prix for e in context['exemplaires']]) or 0

        return render_to_response('encefal/depots.html', Context(context))

    def has_change_permission(self, request, obj=None):
        return obj is None or False

def annuler_vente(modeladmin, request, queryset):
    for vente in queryset.all():
        exemplaires = vente.exemplaires
        for exemplaire in exemplaires.all():
            exemplaire.etat = 'VENT'
            exemplaire.facture = None
            exemplaire.save()
    queryset.delete()
    return HttpResponseRedirect('/employee/')
annuler_vente.short_description = "Annuler la ou les vente(s) selectionnée(s)"

class VenteAdmin(admin.ModelAdmin):

    def __init__(self, *args, **kwargs):
        super(VenteAdmin, self).__init__(*args, **kwargs)
        self.model.session = Session.current_session()

    def get_form(self, request, obj=None, **kwargs):
        form = super(VenteAdmin, self).get_form(request, obj, **kwargs)
        self.model.employe = request.user
        return form

    def save_model(self, request, obj, form, change):
        obj.employe_id = self.model.employe.id
        # If the book is from this session
        if not self.model.session:
            session = Session.session_null()
        else:
            session = self.model.session
        obj.session_id = session.id
        obj.save()

    #TODO: utiliser url reverser admin_index ??
    def response_add(self, request, obj, post_url_continue=None):
        return HttpResponseRedirect('/factures/?id=' + str(obj.id))

    def has_change_permission(self, request, obj=None):
        return obj is None or False

    def has_delete_permission(self, request, obj=None):
        return obj is not None or False

    def get_actions(self, request):
        actions = { 'annuler_vente':(annuler_vente, 'annuler_vente', annuler_vente.short_description) }
        return actions

    model = Facture
    readonly_fields = ('employe','session',)
    fields = ('employe', 'session')
    list_display = ( 'date_creation', 'employe', 'session', 'nb_livres', 'prix_total',)
    exclude = ('actif',)
    actions = [ annuler_vente ]
    inlines = [ ExemplaireVenteInline, ]

class LivreAdmin(admin.ModelAdmin):
    fields = ('isbn', 'titre', 'auteur', 'edition')
    list_display = ('isbn', 'titre', 'auteur', 'edition')
    search_fields = ['titre', 'auteur', 'isbn']

def remettre_exemplaires(modeladmin, request, queryset):
    for exemplaire in queryset.all():

        if exemplaire.etat != 'VENT':
            modeladmin.message_user(request, "Erreur! Seul les exemplaires en vente peuvent être rendus")
            return

    queryset.all().update(etat='REND')
remettre_exemplaires.short_description = "Remettre le(s) exemplaire(s) au client"


def rembourser_exemplaires(modeladmin, request, queryset):
    for exemplaire in queryset.all():

        if exemplaire.etat != 'VEND':
            modeladmin.message_user(request, "Erreur! Seul les exemplaires vendus peuvent être remboursés")
            return

    queryset.all().update(etat='REMB')

rembourser_exemplaires.short_description = "Rembourser le(s) exemplaire(s) au client"

class ExemplaireAdmin(admin.ModelAdmin):
    list_display = ('id','titre','code_permanent_vendeur','etat','prix','date_creation', 'date_modification', 'facture' )
    order_by = ('date_creation', 'date_modification')
    search_fields = ('livre__isbn','livre__titre','id', 'vendeur__code_permanent')
    actions = [remettre_exemplaires, rembourser_exemplaires]

class FactureAdmin(admin.ModelAdmin):
    list_display = ('id', 'date_creation', 'employe', 'session', 'nb_livres',)

class VendeurAdmin(admin.ModelAdmin):
    list_display = ('date_creation', 'nom', 'prenom', 'nb_livres', 'code_permanent')
    exclude = ['actif']
    fields = [
              'code_permanent',
              'prenom',
              'nom' ,
              'email'
             ]

admin.site.register(Vendeur, VendeurAdmin)

admin.site.register(Reception, ReceptionAdmin)