#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# $Id: controle_tresorier2.py,v 1.3 2007-11-08 21:18:32 dimino Exp $
#
# tresorier.py
# ------------
#
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.


import os, sys
sys.path.append('/usr/scripts/gestion')

from ldap_crans import crans_ldap, Adherent, Club
from config import ann_scol
import dialog, time, config, re

db = crans_ldap()

# Détermination de l'uid du câbleur
from user_tests import getuser
uid = getuser()
if not uid :
    print "Impossible de determiner l'utilisateur !"
    sys.exit(1)
cableur = db.search('uid=%s' % uid)['adherent'][0]

# Vérification des droits
if u'Tresorier' not in cableur.droits():
    print "Il faut etre tresorier pour executer ce script !"
    sys.exit(1)

dlg = dialog.Dialog()
dlg.setBackgroundTitle('Tresorerie')
encoding = sys.stdin.encoding or 'UTF-8'

########################################################################
# Retrait des accents
#

_unaccent_dict = {u'Æ': u'AE', u'æ': u'ae', u'Œ': u'OE', u'œ': u'oe', u'ß': 'ss'}
_re_latin_letter = re.compile(r"^(LATIN [A-Z]+ LETTER [A-Z]+) WITH")
def unaccent(string):
    """Remove accents ``string``."""
    result = []
    for char in string:
        if char in _unaccent_dict:
            char = _unaccent_dict[char]
        else:
            try:
                name = unicodedata.name(char)
                match = _re_latin_letter.search(name)
                if match:
                    char = unicodedata.lookup(match.group(1))
            except:
                pass
        result.append(char)
    return "".join(result)

########################################################################
# Ajoute un cheque a la liste
#

_civilite = [ "M", "MLLE", "MME" ]
_banque = [("CIC", u"CiC"),
           ("BNP", u"BNP"),
           ("BP", u"Banque Populaire"),
           ("CA", u"Crédit Agricole"),
           ("CE", u"Caisse d'Épargne"),
           ("CL", u"Crédit Lyonnais"),
           ("CM", u"Crédit Mutuel"),
           ("CN", u"Crédit du Nord"),
           ("HSBC", u"HSBC"),
           ("LBP", u"La Banque Postale"),
           ("LCL", u"Le Crédit Lyonnais"),
           ("LP", u"La Poste"),
           ("SG", u"Société Générale")]
_banque.sort()
_banque.insert(0, ("Autre", u"Éspèces"))
def add_cheque(adh):
    annul, result = dlg.menu(u"Banque", choices = _banque)
    if annul: return False

    banque = result
    if banque == "Autre":
        return True

    annul, result = dlg.menu(u"Civilité",
                             choices=[("1", u"Monsieur"),
                                      ("2", u"Mademoiselle"),
                                      ("3", u"Madame")])
    if annul: return False

    civilite = _civilite[int(result)-1]


    line = '%s %s %s' % (civilite, unaccent(adh.Nom()).upper(), banque)

    annul, line = dlg.inputbox(u"Vérification de l'émetteur du chèque", init=line)

    f = open("%s/remise_cheques" % os.getenv("HOME"), 'a')
    f.write('%s\n' % line)
    f.close()
    return True

########################################################################
# Menu de sélection des adhérents
#

def main_menu():
    while True:

        annul, result = dlg.checklist(u"Choisissez les adhérents à inclure dans la liste",
                                      choices=[("1", u'Nouvelles adhésions', 1),
                                               ("2", u'Réadhésions', 0),
                                               ("3", u'Inscriptions(gratuite)', 1),
                                               ("4", u'Clubs', 0)])

        if annul:
            return

        include_new_adhs = "1" in result
        include_re_adhs = "2" in result
        include_inscriptions = "3" in result
        include_clubs = "4" in result

        # Construction de la liste des adhérents à contrôler
        search_result_p = db.search('paiement=%d&controle!=*p*' % ann_scol)
        search_result_c = db.search('paiement=%d&controle!=*c*' % ann_scol)
        lst_p = search_result_p['adherent'] + search_result_p['club']
        lst_c = search_result_c['adherent'] + search_result_c['club']

        lst = {}
        for adh in lst_p:
            lst[adh.id()] = adh
        for adh in lst_c:
            lst[adh.id()] = adh
        lst = lst.values()

        # Date de début de la nouvelle année
        start_date = time.mktime((ann_scol, 8, 1, 0, 0, 0, 0, 0, 0))

        # Filtre des adhérents
        lst = [adh for adh in lst if
               ((include_new_adhs and isinstance(adh, Adherent) and adh.adherentPayant() and adh.dateInscription() >= start_date) or
                (include_re_adhs and isinstance(adh, Adherent) and adh.adherentPayant() and adh.dateInscription() < start_date) or
                (include_inscriptions and isinstance(adh, Adherent) and not adh.adherentPayant()) or
                (include_clubs and isinstance(adh, Club)))]

        adherent_menu(lst)


########################################################################
# Liste des adhérents
#

def adherent_menu(lst):
    if lst == []:
        dlg.msgbox(u"Il n'y a personne à contrôler!")
        return

    nom_adh = {}
    adhs = []
    for adh in lst:
        disp = ' '.join([unicode(adh.id()).rjust(4), adh.Nom()]).encode(encoding)
        adhs.append((disp, ''))
        nom_adh[disp] = adh

    adhs.sort()

    while True:
        annul, result = dlg.menu(u'Liste des adhérents', choices=adhs)

        if annul:
            return

        adh = nom_adh[result]

        if admin_menu(adh):
            adhs.remove((result, ''))


########################################################################
# Controle d'un adhérent (repompé de gest_crans.py)
#

def on_off(cond):
    if cond:
        return 1
    else:
        return 0

def admin_menu(adh):

    # Le proprietaire a-t-il une section carte d'étudiant (pas les clubs) ?
    has_card = adh.idn != 'cid'

    # Initialisation des différentes checkbox
    carte = on_off(ann_scol in adh.carteEtudiant())
    paiement = on_off(ann_scol in adh.paiement())
    #precab = on_off(ann_scol + 1 in adh.paiement())
    caution = on_off('k' in adh.controle())
    paiement_ok = on_off('p' in adh.controle())
    carte_ok = on_off('c' in adh.controle())

    # Construction de la boîte de dialogue
    texte = []
    checklist = []

    if has_card:
        checklist.append(("1", u"Carte d'étudiant %d/%d fournie" % (ann_scol, ann_scol+1), carte))

        checklist.append(("2", u"Cotisation %d/%d réglée et charte signée" % (ann_scol, ann_scol+1), paiement))

    # TODO: controle pour le précâblage
    #if config.precab:
    #    checklist.append(("3", u"Adhésion %d/%d réglée et charte signée (précâblage)" % (ann_scol+1, ann_scol+2), precab))

    if has_card:
        checklist.append(("4", u"Carte d\'étudiant vérifiée", carte_ok))
    checklist.append(("5", u"Cotisation/charte/caution vérifées", paiement_ok))

    annul, result = dlg.checklist(u"Etat administratif de %s" % adh.Nom(),
                                  choices=checklist)
    if annul:
        return False

    modif = False
    # On cherche s'il y a des modifs
    for tag, item, state in checklist:
        if (tag in result) ^ state:
            modif = True

    if not modif:
        return False

    if isinstance(adh, Club):
        adh = db.search('cid=%s' % adh.id(), 'w')['club'][0]
    else:
        adh = db.search('aid=%s' % adh.id(), 'w')['adherent'][0]

    # Traitement
    if has_card:
        if '1' in result:
            adh.carteEtudiant(ann_scol)
        elif carte_ok:
            adh.carteEtudiant(-ann_scol)
        if '4' in result:
            adh.controle('+c')
        else:
            adh.controle('-c')

    if '2' in result and ann_scol not in adh.paiement():
        adh.paiement(ann_scol)
    elif '2' not in result and paiement_ok:
        adh.paiement(-ann_scol)

    if '3' in result:
        adh.paiement(ann_scol+1)
    elif paiement_ok:
        adh.paiement(-ann_scol-1)

    if '5' in result:
        adh.controle('+p')
    else:
        adh.controle('-p')

    if 'C' in result:
        adh.controle('+k')
    else:
        adh.controle('-k')

    adh.save()

    return True

main_menu()
