示例#1
0
    def generer(self, trans_vals, paramtexte, dossier_destination, par_plate):
        """
        génération du fichier de bilan des usages à partir des transactions
        :param trans_vals: valeurs des transactions générées
        :param paramtexte: paramètres textuels
        :param dossier_destination: Une instance de la classe dossier.DossierDestination
        :param par_plate: tri des transactions par plateforme, par item
        """
        ii = 0
        for id_plate in par_plate.keys():
            par_item = par_plate[id_plate]['items']
            for item in par_item.keys():
                tbtr = par_item[item]
                base = trans_vals[tbtr[0]]
                if base['item-type'] == paramtexte.donnees['item-service']:
                    donnee = []
                    for cle in range(2, len(self.cles)-1):
                        donnee.append(base[self.cles[cle]])
                    usage = 0
                    for indice in tbtr:
                        val, info = Outils.est_un_nombre(trans_vals[indice]['transac-usage'], "l'usage", arrondi=4)
                        if info != "":
                            Outils.affiche_message(info)
                        usage += val
                    donnee += [round(usage, 4)]
                    self.ajouter_valeur(donnee, ii)
                    ii += 1

        self.csv(dossier_destination, paramtexte)
示例#2
0
    def verification_date(self, annee, mois):
        """
        vérifie que le mois et l'année présents sur la ligne sont bien ceux espérés
        :param annee: année selon paramètres d'édition
        :param mois: mois selon paramètres d'édition
        :return: 0 si ok, 1 sinon
        """
        if self.verifie_date == 1:
            print(self.libelle + ": date déjà vérifiée")
            return 0

        msg = ""
        position = 1
        for donnee in self.donnees:
            try:
                if (int(donnee["mois"]) != mois) or (int(donnee["annee"]) != annee):
                    msg += "date incorrect ligne " + str(position) + "\n"
            except ValueError:
                msg += "année ou mois n'est pas valable" + str(position) + "\n"
            position += 1

        del self.donnees[0]
        self.verifie_date = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            print("msg : " + msg)
            Outils.affiche_message(msg)
            return 1
        return 0
示例#3
0
 def ouvrir_csv_sans_comptes_client(dossier_source,
                                    fichier,
                                    code_client,
                                    comptes,
                                    position_id=0):
     """
     ouverture d'un csv comme string sans les données des comptes d'un client donné
     :param dossier_source: Une instance de la classe dossier.DossierSource
     :param fichier: nom du fichier csv
     :param code_client: code du client à ignorer
     :param comptes: comptes importés
     :param position_id: position colonne du compte id dans le csv
     :return: donnees du csv modifiées en tant que string
     """
     donnees_csv = []
     try:
         fichier_reader = dossier_source.reader(fichier)
         for ligne in fichier_reader:
             if ligne == -1:
                 continue
             id_compte = ligne[position_id]
             if id_compte not in comptes.donnees or comptes.donnees[
                     id_compte]['code_client'] != code_client:
                 donnees_csv.append(ligne)
     except IOError as e:
         Outils.fatal(e, "impossible d'ouvrir le fichier : " + fichier)
     return donnees_csv
示例#4
0
    def livraisons_pour_projet_par_categorie(self, num_projet, id_compte, code_client, prestations):
        """
        retourne les livraisons pour un projet donné, pour une catégorie de prestations donnée
        :param num_projet: lenuméro de projet
        :param id_compte: l'id du compte
        :param code_client: le code du client
        :param prestations: prestations importées et vérifiées
        :return: les livraisons pour le projet donné, pour une catégorie de prestations donnée
        """

        if prestations.verifie_coherence == 0:
            info = self.libelle + ". vous devez vérifier la cohérence des prestations avant de pouvvoir sélectionner " \
                                  "les livraisons par catégorie"
            print(info)
            Outils.affiche_message(info)
            return {}

        donnees_dico = {}
        for donnee in self.donnees:
            if (donnee['id_compte'] == id_compte) and (donnee['code_client'] == code_client) \
                    and (donnee['num_projet'] == num_projet):
                categorie = prestations.donnees[donnee['id_prestation']]['categorie']
                if categorie not in donnees_dico:
                    donnees_dico[categorie] = []
                liste = donnees_dico[categorie]
                liste.append(donnee)
        return donnees_dico
示例#5
0
    def creer_latex_pdf(nom_fichier, contenu):
        """
        création d'un pdf à partir d'un contenu latex
        :param nom_fichier: nom du pdf final
        :param contenu: contenu latex
        """
        with open(nom_fichier + ".tex", 'w') as f:
            f.write(contenu)

        proc = subprocess.Popen(['pdflatex', nom_fichier + ".tex"])
        proc.communicate()

        # 2 fois pour que les longtable soient réguliers (courant de relancer latex)

        proc = subprocess.Popen(['pdflatex', nom_fichier + ".tex"])
        proc.communicate()

        try:
            os.unlink(nom_fichier + '.tex')
            os.unlink(nom_fichier + '.log')
            os.unlink(nom_fichier + '.aux')

        except OSError as err:
            Outils.affiche_message("OSError: {0}".format(err))
        except IOError as err:
            Outils.affiche_message("IOError: {0}".format(err))
示例#6
0
    def creer_latex_pdf(nom_fichier, contenu, nom_dossier=""):
        """
        création d'un pdf à partir d'un contenu latex
        :param nom_fichier: nom du pdf final
        :param contenu: contenu latex
        :param nom_dossier: nom du dossier dans lequel enregistrer le pdf
        """
        with open(nom_fichier + ".tex", 'w') as f:
            f.write(contenu)

        proc = subprocess.Popen(['pdflatex', nom_fichier + ".tex"])
        proc.communicate()

        # 2 fois pour que les longtable soient réguliers (courant de relancer latex)

        proc = subprocess.Popen(['pdflatex', nom_fichier + ".tex"])
        proc.communicate()

        os.unlink(nom_fichier + '.tex')
        os.unlink(nom_fichier + '.log')
        os.unlink(nom_fichier + '.aux')

        if nom_dossier != '':
            try:
                shutil.copy(nom_fichier + ".pdf", nom_dossier)
                os.unlink(nom_fichier + '.pdf')
            except IOError:
                Outils.affiche_message(
                    "Le pdf " + nom_fichier +
                    " est resté ouvert et ne sera pas mis à jour")
示例#7
0
    def mise_a_jour(edition, clients, dossier_source, dossier_destination, maj, f_html_sections):
        """
        modification des résumés mensuels au niveau du client dont la facture est modifiée 
        :param edition: paramètres d'édition
        :param clients: clients importés
        :param dossier_source: Une instance de la classe dossier.DossierSource
        :param dossier_destination: Une instance de la classe dossier.DossierDestination
        :param maj: données modifiées pour le client pour les différents fichiers
        :param f_html_sections: section html modifiée pour le client
        """
        if len(maj) != len(Resumes.fichiers):
            info = "Résumés : erreur taille tableau"
            Outils.affiche_message(info)
            return

        for i in range(len(Resumes.fichiers)):
            fichier_complet = Resumes.fichiers[i] + "_" + str(edition.annee) + "_" + \
                              Outils.mois_string(edition.mois) + ".csv"
            donnees_csv = Resumes.ouvrir_csv_sans_client(
                dossier_source, fichier_complet, edition.client_unique, Resumes.positions[i])
            with dossier_destination.writer(fichier_complet) as fichier_writer:
                for ligne in donnees_csv:
                    fichier_writer.writerow(ligne)
                for ligne in maj[i]:
                    fichier_writer.writerow(ligne)

        ticket_complet = "ticket_" + str(edition.annee) + "_" + Outils.mois_string(edition.mois) + ".html"
        section = list(f_html_sections.values())[0]
        nom_client = clients.donnees[edition.client_unique]['abrev_labo'] + " (" + edition.client_unique + ")"
        Resumes.maj_ticket(dossier_source, dossier_destination, ticket_complet, section, edition.client_unique,
                           nom_client)
示例#8
0
    def verification_date(self, annee, mois):
        """
        vérifie que le mois et l'année présents sur la ligne sont bien ceux espérés
        :param annee: année selon paramètres d'édition
        :param mois: mois selon paramètres d'édition
        :return: 0 si ok, 1 sinon
        """
        if self.verifie_date == 1:
            print(self.libelle + ": date déjà vérifiée")
            return 0

        msg = ""
        position = 1
        for donnee in self.donnees:
            try:
                if (int(donnee['mois']) != mois) or (int(donnee['annee']) != annee):
                    msg += "date incorrect ligne " + str(position) + "\n"
            except ValueError:
                msg += "année ou mois n'est pas valable" + str(position) + "\n"
            position += 1

        del self.donnees[0]
        self.verifie_date = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            print("msg : " + msg)
            Outils.affiche_message(msg)
            return 1
        return 0
示例#9
0
    def __init__(self, dossier_source, nom_fichier, annee, mois):
        """
        initialisation et importation des données

        :param dossier_source: Une instance de la classe dossier.DossierSource
        :param nom_fichier: nom du fichier à importer
        :param annee: année selon paramètres d'édition
        :param mois: mois selon paramètres d'édition
        """
        self.nom = nom_fichier
        self.mois = mois
        self.annee = annee
        try:
            fichier_reader = dossier_source.reader(nom_fichier)
            donnees_csv = []
            for ligne in fichier_reader:
                donnees_csv.append(ligne)
            self.cles = {}
            i = 0
            for cle in donnees_csv[0]:
                self.cles[cle] = i
                i += 1
            self.donnees = donnees_csv[1:]
            self.verifie_date = 0
        except IOError as e:
            Outils.fatal(e, "impossible d'ouvrir le fichier : "+nom_fichier)
示例#10
0
 def pdfs_pour_client(self, client, type_annexe):
     """
     retourne les pdfs à ajouter en fin d'annexe pour le client
     :return: pdfs selon position
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les codes"
         Outils.affiche_message(info)
         return []
     pdfs = {}
     for donnee in self.donnees:
         if donnee['code'] != "" and donnee['code'] != client['code']:
             continue
         if donnee['nature'] != "" and donnee['nature'] != client['nature']:
             continue
         if donnee[type_annexe] == 'NON':
             continue
         if not donnee['position'] in pdfs:
             pdfs[donnee['position']] = [{
                 'chemin': donnee['chemin'],
                 'nom': donnee['nom']
             }]
         else:
             pdfs[donnee['position']].append({
                 'chemin': donnee['chemin'],
                 'nom': donnee['nom']
             })
     return pdfs
示例#11
0
    def generer(self, trans_vals, paramtexte, dossier_destination, par_plate):
        """
        génération du fichier des usages de labos à partir des transactions
        :param trans_vals: valeurs des transactions générées
        :param paramtexte: paramètres textuels
        :param dossier_destination: Une instance de la classe dossier.DossierDestination
        :param par_plate: tri des transactions par plateforme, par utilisateur, par client, par jour
        """
        ii = 0
        for id_plate in par_plate.keys():
            par_user = par_plate[id_plate]['users']
            for id_user in par_user.keys():
                par_client = par_user[id_user]
                for code in par_client.keys():
                    par_jour = par_client[code]
                    for jour in par_jour.keys():
                        key = par_jour[jour]
                        trans = trans_vals[key]
                        date, info = Outils.est_une_date(trans['transac-date'], "la date de transaction")
                        if info != "":
                            Outils.affiche_message(info)
                        donnee = []
                        for cle in range(2, len(self.cles)):
                            if self.cles[cle] == 'day':
                                donnee.append(date.day)
                            elif self.cles[cle] == 'week-nbr':
                                donnee.append(date.isocalendar()[1])
                            else:
                                donnee.append(trans[self.cles[cle]])
                        self.ajouter_valeur(donnee, ii)
                        ii += 1

        self.csv(dossier_destination, paramtexte)
示例#12
0
    def creation_lignes(subedition, subgeneraux, consolidation):
        """
        génération des lignes de données du bilan
        :param subedition: paramètres d'édition
        :param subgeneraux: paramètres généraux
        :param consolidation: classe de consolidation des données des bilans
        :return: lignes de données du bilan
        """
        lignes = []
        for code_client, client in sorted(consolidation.clients.items()):

            numbers = {}
            for id_compte, compte in client['comptes'].items():
                numbers[id_compte] = compte['num_compte']

            for id_compte, num_compte in sorted(numbers.items(), key=lambda x: x[1]):
                compte = client['comptes'][id_compte]
                if compte['subs'] > 0:
                    ligne = [subedition.annee_fin_general, subedition.mois_fin_general, code_client, client['sap'],
                             client['abrev'], client['nom'], client['type'], client['nature'], id_compte,
                             num_compte, compte['intitule'], compte['type'], compte['t3'],
                             Outils.format_2_dec(compte['s-mt'])]
                    for categorie in subgeneraux.codes_d3():
                        ligne.append(Outils.format_2_dec(compte['s-' + categorie + 't']))
                    ligne += [Outils.format_2_dec(compte['subs'])]
                    lignes.append(ligne)
        return lignes
示例#13
0
    def livraisons_pour_compte_par_categorie(self, id_compte, code_client,
                                             prestations):
        """
        retourne les livraisons pour un compte donné, pour une catégorie de prestations donnée
        :param id_compte: l'id du compte
        :param code_client: le code du client
        :param prestations: prestations importées et vérifiées
        :return: les livraisons pour le projet donné, pour une catégorie de prestations donnée
        """

        if prestations.verifie_coherence == 0:
            info = self.libelle + ". vous devez vérifier la cohérence des prestations avant de pouvvoir sélectionner " \
                                  "les livraisons par catégorie"
            Outils.affiche_message(info)
            return {}

        donnees_dico = {}
        for donnee in self.donnees:
            if (donnee['id_compte'] == id_compte) and (donnee['code_client']
                                                       == code_client):
                categorie = prestations.donnees[
                    donnee['id_prestation']]['categorie']
                if categorie not in donnees_dico:
                    donnees_dico[categorie] = []
                liste = donnees_dico[categorie]
                liste.append(donnee)
        return donnees_dico
示例#14
0
    def __init__(self, dossier_source):
        """
        initialisation et importation des données

        :param dossier_source: Une instance de la classe dossier.DossierSource
        """
        self._chemin = dossier_source.chemin
        try:
            fichier_reader = dossier_source.reader(self.nom_fichier)
            donnees_csv = []
            for ligne in fichier_reader:
                donnees_ligne = self.extraction_ligne(ligne)
                if donnees_ligne == -1:
                    continue
                donnees_csv.append(donnees_ligne)
            self.donnees = donnees_csv
        except IOError as e:
            Outils.fatal(
                e, "impossible d'ouvrir le fichier : " + self.nom_fichier)
        del self.donnees[0]

        for donnee in self.donnees:
            if donnee['nom'] in self.dossiers_annexes:
                donnee['dossier'] = self.dossiers_annexes[donnee['nom']]
            else:
                info = self.libelle + ": nom non-attendu : " + donnee[
                    'nom'] + ", pas de nom de dossier "
                Outils.affiche_message(info)
                sys.exit("Erreur de consistance")
示例#15
0
    def calcul_montants(self, prestations, coefprests, comptes, clients, verification):
        """
        calcule le 'montant' et le 'rabais_r' et les ajoute aux données
        :param prestations: prestations importées et vérifiées
        :param coefprests: coefficients prestations importés et vérifiés
        :param comptes: comptes importés et vérifiés
        :param clients: clients importés et vérifiés
        :param verification: pour vérifier si les dates et les cohérences sont correctes
        """
        if verification.a_verifier != 0:
            info = self.libelle + ". vous devez faire les vérifications avant de calculer les montants"
            print(info)
            Outils.affiche_message(info)
            return

        donnees_list = []
        for donnee in self.donnees:
            prestation = prestations.donnees[donnee['id_prestation']]
            compte = comptes.donnees[donnee['id_compte']]
            client = clients.donnees[compte['code_client']]
            coefprest = coefprests.donnees[client['id_classe_tarif'] + prestation['categorie']]
            donnee['prix_unit_client'] = round(prestation['prix_unit'] * coefprest['coefficient'], 2)
            donnee['montant'] = round(donnee['quantite'] * donnee['prix_unit_client'], 2)
            donnee['rabais_r'] = round(donnee['rabais'], 2)
            donnees_list.append(donnee)
        self.donnees = donnees_list
示例#16
0
    def __init__(self, dossier_source):
        """
        initialisation et importation des données

        :param dossier_source: Une instance de la classe dossier.DossierSource
        """
        donnees_csv = []
        try:
            for ligne in dossier_source.reader(self.nom_fichier):
                donnees_csv.append(ligne)
        except IOError as e:
            Outils.fatal(e, "impossible d'ouvrir le fichier : "+SuppressionFacture.nom_fichier)

        num = 4
        if len(donnees_csv) != num:
            Outils.fatal(ErreurConsistance(),
                         SuppressionFacture.libelle + ": nombre de lignes incorrect : " +
                         str(len(donnees_csv)) + ", attendu : " + str(num))
        try:
            self.annee = int(donnees_csv[0][1])
            self.mois = int(donnees_csv[1][1])
        except ValueError as e:
            Outils.fatal(e, SuppressionFacture.libelle +
                         "\nle mois et l'année doivent être des nombres entiers")
        try:
            self.version = int(donnees_csv[2][1])
        except ValueError as e:
            Outils.fatal(e, SuppressionFacture.libelle +
                         "\nla version doit être un nombre entier")
        if self.version < 0:
            Outils.fatal(ErreurConsistance(),
                         SuppressionFacture.libelle + ": la version doit être positive ")

        self.client_unique = donnees_csv[3][1]
示例#17
0
    def verification_date(self):
        """
        vérifie que le mois et l'année présents sur la ligne sont bien ceux espérés
        :return: 0 si ok, 1 sinon
        """
        if self.verifie_date == 1:
            print(self.nom + ": date déjà vérifiée")
            return 0

        msg = ""
        position = 1
        for donnee in self.donnees:
            try:
                if int(donnee[self.cles['mois']]) != self.mois or int(donnee[self.cles['année']]) != self.annee:
                    msg += "date incorrect ligne " + str(position) + "\n"
            except ValueError:
                msg += "année ou mois n'est pas valable" + str(position) + "\n"
            position += 1

        self.verifie_date = 1

        if msg != "":
            msg = "L’année et le mois ne correspondent pas à ceux attendus dans " + self.nom
            Outils.affiche_message(msg)
            return 1
        return 0
示例#18
0
    def calcul_montants(self, prestations, coefprests, comptes, clients,
                        verification):
        """
        calcule le 'montant' et le 'rabais_r' et les ajoute aux données
        :param prestations: prestations importées et vérifiées
        :param coefprests: coefficients prestations importés et vérifiés
        :param comptes: comptes importés et vérifiés
        :param clients: clients importés et vérifiés
        :param verification: pour vérifier si les dates et les cohérences sont correctes
        """
        if verification.a_verifier != 0:
            info = self.libelle + ". vous devez faire les vérifications avant de calculer les montants"
            print(info)
            Outils.affiche_message(info)
            return

        donnees_list = []
        for donnee in self.donnees:
            prestation = prestations.donnees[donnee['id_prestation']]
            compte = comptes.donnees[donnee['id_compte']]
            client = clients.donnees[compte['code_client']]
            coefprest = coefprests.donnees[client['id_classe_tarif'] +
                                           prestation['categorie']]
            donnee['prix_unit_client'] = round(
                prestation['prix_unit'] * coefprest['coefficient'], 2)
            donnee['montant'] = round(
                donnee['quantite'] * donnee['prix_unit_client'], 2)
            donnee['rabais_r'] = round(donnee['rabais'], 2)
            donnees_list.append(donnee)
        self.donnees = donnees_list
示例#19
0
    def verification_date(self, annee, mois):
        """
        vérifie que le mois et l'année présents sur la ligne sont bien ceux espérés
        :param annee: année selon paramètres d'édition
        :param mois: mois selon paramètres d'édition
        :return: 0 si ok, 1 sinon
        """
        if self.verifie_date == 1:
            print(self.libelle + ": date déjà vérifiée")
            return 0

        msg = ""
        position = 1
        for donnee in self.donnees:
            donnee['mois'], info = Outils.est_un_entier(
                donnee['mois'], "le mois ", position, 1, 12)
            msg += info
            donnee['annee'], info = Outils.est_un_entier(
                donnee['annee'], "l'annee ", position, 2000, 2099)
            msg += info
            if donnee['mois'] != mois or donnee['annee'] != annee:
                msg += "date incorrect ligne " + str(position) + "\n"
            position += 1

        del self.donnees[0]
        self.verifie_date = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            Outils.affiche_message(msg)
            return 1
        return 0
示例#20
0
    def somme_par_categorie(self, comptes):
        """
        calcule les sommes par catégories sous forme de dictionnaire : client->catégorie->clés_sommes
        :param comptes: comptes importés et vérifiés
        """

        if self.verification.a_verifier != 0:
            info = "Sommes :  vous devez faire les vérifications avant de calculer les sommes"
            print(info)
            Outils.affiche_message(info)
            return

        if self.sco != 0:
            spca = {}
            for code_client, spco_cl in self.sommes_comptes.items():
                if code_client not in spca:
                    spca[code_client] = {}
                spca_cl = spca[code_client]
                for id_compte, spco_co in spco_cl.items():
                    cat = comptes.donnees[id_compte]['categorie']
                    if cat not in spca_cl:
                        spca_cl[cat] = self.nouveau_somme(Sommes.cles_somme_categorie)
                    somme = spca_cl[cat]

                    somme['somme_k_ai'] += spco_co['somme_j_ai']
                    somme['somme_k_bi'] += spco_co['somme_j_bi']
                    somme['somme_k_ci'] += spco_co['somme_j_ci']
                    somme['somme_k_oi'] += spco_co['somme_j_oi']
                    somme['somme_k_mai'] += spco_co['somme_j_mai']
                    somme['somme_k_moi'] += spco_co['somme_j_moi']
                    somme['somme_k_dsi'] += spco_co['somme_j_dsi']
                    somme['somme_k_dhi'] += spco_co['somme_j_dhi']
                    somme['somme_k_mm'] += spco_co['somme_j_mm']
                    somme['somme_k_mr'] += spco_co['somme_j_mr']
                    somme['mk'] += spco_co['mj']

                    for categorie in self.categories:
                        somme['sommes_cat_m'][categorie] += spco_co['sommes_cat_m'][categorie]
                        somme['sommes_cat_r'][categorie] += spco_co['sommes_cat_r'][categorie]
                        somme['tot_cat'][categorie] += spco_co['tot_cat'][categorie]

            # print("")
            # print("spca")
            # for code in spca:
            #     if code != "220208":
            #         continue
            #     print(code)
            #     spca_cl = spca[code]
            #     for cat in spca_cl:
            #         somme = spca_cl[cat]
            #         print("   ", cat, somme['somme_k_mai'])

            self.sca = 1
            self.sommes_categories = spca

        else:
            info = "Vous devez d'abord faire la somme par compte, avant la somme par catégorie"
            print(info)
            Outils.affiche_message(info)
示例#21
0
    def est_coherent(self, subsides, generaux):
        """
        vérifie que les données du fichier importé sont cohérentes
        :param subsides: subsides importés
        :param generaux: paramètres généraux
        :return: 1 s'il y a une erreur, 0 sinon
        """

        if self.verifie_coherence == 1:
            print(self.libelle + ": cohérence déjà vérifiée")
            return 0

        msg = ""
        ligne = 1
        donnees_dict = {}
        couples = []

        del self.donnees[0]
        for donnee in self.donnees:
            if donnee['type'] == "":
                msg += "le type de la ligne " + str(
                    ligne) + " ne peut être vide\n"
            elif subsides.contient_type(donnee['type']) == 0:
                msg += "le type '" + donnee['type'] + "' de la ligne " + str(ligne) \
                       + " n'est pas référencé\n"
            if donnee['code_d'] == "":
                msg += "la code D de la ligne " + str(
                    ligne) + " ne peut être vide\n"
            elif donnee['code_d'] not in generaux.obtenir_code_d():
                msg += "la code D de la ligne " + str(
                    ligne) + " n'existe pas dans les codes D\n"

            couple = [donnee['type'], donnee['code_d']]
            if couple not in couples:
                couples.append(couple)
            else:
                msg += "Couple type '" + donnee['type'] + "' et code D '" + \
                       donnee['code_d'] + "' de la ligne " + str(ligne) + " pas unique\n"

            donnee['max_mois'], info = Outils.est_un_nombre(
                donnee['max_mois'], "le max mensuel", ligne, 2, 0)
            msg += info

            donnee['max_compte'], info = Outils.est_un_nombre(
                donnee['max_compte'], "le max compte", ligne, 2, 0)
            msg += info

            donnees_dict[donnee['type'] + donnee['code_d']] = donnee
            ligne += 1

        self.donnees = donnees_dict
        self.verifie_coherence = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            Outils.affiche_message(msg)
            return 1
        return 0
示例#22
0
    def calcul_montants(self, machines, coefmachines, comptes, clients, verification):
        """
        calcule les montants 'pv' et 'qv' et les ajoute aux données
        :param machines: machines importées et vérifiées
        :param coefmachines: coefficients machines importés et vérifiés
        :param comptes: comptes importés et vérifiés
        :param clients: clients importés et vérifiés
        :param verification: pour vérifier si les dates et les cohérences sont correctes
        """
        if verification.a_verifier != 0:
            info = self.libelle + ". vous devez faire les vérifications avant de calculer les montants"
            print(info)
            Outils.affiche_message(info)
            return

        donnees_list = []
        for donnee in self.donnees:

            id_compte = donnee['id_compte']
            compte = comptes.donnees[id_compte]
            code_client = compte['code_client']
            id_machine = donnee['id_machine']
            machine = machines.donnees[id_machine]
            client = clients.donnees[code_client]
            coefmachine = coefmachines.donnees[client['id_classe_tarif'] + machine['categorie']]
            duree_fact_hp, duree_fact_hc = Rabais.rabais_reservation(machine['delai_sans_frais'],
                                                                     donnee['duree_ouvree'],
                                                                     donnee['duree_hp'],
                                                                     donnee['duree_hc'])

            if code_client not in self.sommes:
                self.sommes[code_client] = {'comptes': {}, 'machines': {}}
            scl = self.sommes[code_client]
            if id_compte not in scl['comptes']:
                scl['comptes'][id_compte] = {}
            sco = scl['comptes'][id_compte]
            if id_machine not in sco:
                sco[id_machine] = {'res_hp': 0, 'ann_hp': 0,
                                'res_hc': 0, 'ann_hc': 0}

            if donnee['si_supprime'] == 'OUI':
                sco[id_machine]['ann_hp'] += duree_fact_hp
                sco[id_machine]['ann_hc'] += duree_fact_hc
            else:
                sco[id_machine]['res_hp'] += duree_fact_hp
                sco[id_machine]['res_hc'] += duree_fact_hc

            if id_machine not in scl['machines']:
                pu_hp = round(coefmachine['coef_r'] * machine['t_h_reservation_hp'], 2)
                pu_hc = round(coefmachine['coef_r'] * machine['t_h_reservation_hc'], 2)
                scl['machines'][id_machine] = {'pu_hp': pu_hp, 'pu_hc': pu_hc}

            donnee['duree_fact_hp'] = duree_fact_hp
            donnee['duree_fact_hc'] = duree_fact_hc

            donnees_list.append(donnee)

        self.donnees = donnees_list
示例#23
0
    def creation_annexes(sommes, clients, edition, livraisons, acces, machines, reservations, prestations, comptes,
                         dossier_annexe, plateforme, prefixe, coefprests, coefmachines, generaux, garde):
        """
        création des annexes techniques
        :param sommes: sommes calculées
        :param clients: clients importés
        :param edition: paramètres d'édition
        :param livraisons: livraisons importées
        :param acces: accès importés
        :param machines: machines importées
        :param reservations: réservations importées
        :param prestations: prestations importées
        :param comptes: comptes importés
        :param dossier_annexe: nom du dossier dans lequel enregistrer les annexes
        :param plateforme: OS utilisé
        :param prefixe: prefixe de nom des annexes
        :param coefprests: coefficients prestations importés
        :param coefmachines: coefficients machines importés
        :param generaux: paramètres généraux
        :param garde: titre page de garde
        """

        if sommes.calculees == 0:
            info = "Vous devez d'abord faire toutes les sommes avant de pouvoir créer les annexes"
            print(info)
            Outils.affiche_message(info)
            return

        for code_client in sommes.sommes_clients.keys():
            contenu = Latex.entete(plateforme)
            contenu += r'''\usepackage[margin=10mm, includefoot]{geometry}
                \usepackage{multirow}
                \usepackage{longtable}
                \usepackage{dcolumn}
                \usepackage{changepage}
                \usepackage[scriptsize]{caption}

                \begin{document}
                \renewcommand{\arraystretch}{1.5}
                '''
            contenu += r'''
                \vspace*{8cm}
                \begin{adjustwidth}{5cm}{}
                \Large\textsc{''' + garde + r'''}\newline\newline'''
            nom = Latex.echappe_caracteres(clients.donnees[code_client]['abrev_labo'])
            code_sap = clients.donnees[code_client]['code_sap']

            contenu += code_client + " - " + code_sap + " - " + nom + r'''\newpage
                \end{adjustwidth}'''
            contenu += Annexes.contenu_client(sommes, clients, code_client, edition, livraisons, acces, machines,
                                              reservations, prestations, comptes, coefprests, coefmachines, generaux)
            contenu += r'''\end{document}'''

            nom = prefixe + str(edition.annee) + "_" + Outils.mois_string(edition.mois) + "_" + \
                  str(edition.version) + "_" + code_client

            Latex.creer_latex_pdf(nom, contenu, dossier_annexe)
示例#24
0
    def table_points_xbmu(code_client, scl, sommes_acces, machines, users):
        """
        Points XB/M/U - Table Client Récap Bonus/MAchine/User
        :param code_client: code du client concerné
        :param scl: sommes client calculées
        :param sommes_acces: sommes des accès importés
        :param machines: machines importées
        :param users: users importés
        :return: table au format latex
        """
        if scl['somme_t_mb'] > 0:
            structure = r'''{|l|c|r|r|}'''
            legende = r'''Récapitulatif des bonus d’utilisation en heures creuses'''

            contenu = r'''
                \cline{3-4}
                \multicolumn{2}{l|}{} & \multicolumn{1}{c|}{Temps Mach.} & \multicolumn{1}{c|}{Points Bonus} \\
                \hline
                '''

            somme = sommes_acces[code_client]['machines']
            machines_utilisees = Outils.machines_in_somme(somme, machines)

            for id_categorie, mics in sorted(machines_utilisees.items()):
                for nom_machine, id_machine in sorted(mics.items()):
                    if somme[id_machine]['dhm'] > 0:
                        dico_machine = {'machine': Latex.echappe_caracteres(nom_machine),
                                        'hc': Outils.format_heure(somme[id_machine]['duree_hc']),
                                        'dhm': somme[id_machine]['dhm']}
                        contenu += r'''
                            \hspace{2mm} %(machine)s & HC & %(hc)s & %(dhm)s \\
                            \hline
                            ''' % dico_machine

                        utilisateurs = Outils.utilisateurs_in_somme(somme[id_machine]['users'], users)

                        for nom, upi in sorted(utilisateurs.items()):
                            for prenom, ids in sorted(upi.items()):
                                for id_user in sorted(ids):
                                    smu = somme[id_machine]['users'][id_user]
                                    if smu['duree_hc'] > 0:
                                        dico_user = {'user': Latex.echappe_caracteres(nom + " " + prenom),
                                                     'hc': Outils.format_heure(smu['duree_hc'])}
                                        contenu += r'''
                                            \hspace{5mm} %(user)s & HC & %(hc)s \hspace{5mm} & \\
                                            \hline
                                        ''' % dico_user

            dico = {'bht': scl['somme_t_mb']}
            contenu += r'''
                \multicolumn{3}{|r|}{\textbf{Total points de bonus}} & %(bht)s \\
                \hline
                ''' % dico

            return Latex.long_tableau(contenu, structure, legende)
        else:
            return ""
示例#25
0
    def verification_coherence(self, generaux, edition, acces, clients,
                               emoluments, coefprests, comptes, users,
                               livraisons, machines, prestations, reservations,
                               categories, categprix, docpdf):
        """
        vérifie la cohérence des données importées
        :param generaux: paramètres généraux
        :param edition: paramètres d'édition
        :param acces: accès importés
        :param clients: clients importés
        :param emoluments: émoluments importés
        :param coefprests: coefficients prestations importés
        :param comptes: comptes importés
        :param users: users importés
        :param livraisons: livraisons importées
        :param machines: machines importées
        :param prestations: prestations importées
        :param reservations: réservations importées
        :param categories: catégories importées
        :param categprix: catégories prix importées
        :param docpdf: paramètres d'ajout de document pdf
        :return: 0 si ok, sinon le nombre d'échecs à la vérification
        """
        verif = 0
        verif += acces.est_coherent(comptes, machines, users)
        verif += livraisons.est_coherent(comptes, prestations, users)
        verif += categories.est_coherent()
        verif += users.est_coherent()
        verif += machines.est_coherent(categories)
        verif += prestations.est_coherent(generaux, coefprests)
        verif += emoluments.est_coherent(generaux)
        verif += categprix.est_coherent(generaux, categories)
        verif += coefprests.est_coherent(generaux)
        verif += clients.est_coherent(emoluments, generaux)
        verif += reservations.est_coherent(comptes, machines, users)
        verif += docpdf.est_coherent(generaux, clients)
        verif += comptes.est_coherent(clients, generaux)

        if verif > 0:
            return verif

        comptes_actifs = Verification.obtenir_comptes_actifs(acces, livraisons)
        clients_actifs = Verification.obtenir_clients_actifs(
            comptes_actifs, comptes)

        if edition.version > 0 and len(clients_actifs) > 0:
            if len(clients_actifs) > 1:
                Outils.affiche_message(
                    "Si version différente de 0, un seul client autorisé")
                sys.exit("Trop de clients pour version > 0")
            if edition.client_unique != clients_actifs[0]:
                Outils.affiche_message(
                    "Le client unique des paramètres d'édition n'est pas le même que celui présent dans "
                    "les transactions")
                sys.exit("clients non-correspondants pour version > 0")
        self.a_verifier = 0
        return verif
示例#26
0
    def est_coherent(self, subcomptes):
        """
        vérifie que les données du fichier importé sont cohérentes 
        :param subcomptes: comptes subsides importés
        :return: 1 s'il y a une erreur, 0 sinon
        """

        if self.verifie_coherence == 1:
            print(self.libelle + ": cohérence déjà vérifiée")
            return 0

        msg = ""
        ligne = 1
        donnees_dict = {}
        ids = []

        for donnee in self.donnees:

            if donnee['id_compte'] == "":
                msg += "le compte id de la ligne " + str(
                    ligne) + " ne peut être vide\n"
            elif donnee['id_compte'] not in ids:
                ids.append(donnee['id_compte'])
            else:
                msg += "le compte id '" + donnee['id_compte'] + "' de la ligne " + str(ligne) +\
                       " n'est pas unique\n"

            if donnee['id_compte'] not in subcomptes.obtenir_ids():
                msg += "le compte id '" + donnee['id_compte'] + "' de la ligne " + str(ligne) +\
                       " n'est pas référencée dans les comptes subisdes\n"

            donnee['m_mois'], info = Outils.est_un_nombre(
                donnee['m_mois'], "le maximum m mois", ligne)
            msg += info

            donnee['m_compte'], info = Outils.est_un_nombre(
                donnee['m_compte'], "le maximum m compte", ligne)
            msg += info

            donnees_dict[donnee['id_compte']] = donnee

            ligne += 1

        for id_compte in subcomptes.obtenir_ids():
            if id_compte not in ids:
                msg += "Le compte id '" + id_compte + "' dans les comptes subsides n'est pas présente dans " \
                                               "les plafonds machines\n"

        self.donnees = donnees_dict
        self.verifie_coherence = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            Outils.affiche_message(msg)
            return 1
        return 0
示例#27
0
    def creation_lignes(edition, sommes, clients, generaux, acces, livraisons, comptes, categories, prestations):
        """
        génération des lignes de données du détail
        :param edition: paramètres d'édition
        :param sommes: sommes calculées
        :param clients: clients importés
        :param generaux: paramètres généraux
        :param acces: accès importés
        :param livraisons: livraisons importées
        :param comptes: comptes importés
        :param categories: catégories importées
        :param prestations: prestations importées
        :return: lignes de données du détail
        """
        if sommes.calculees == 0:
            info = "Vous devez d'abord faire toutes les sommes avant de pouvoir créer le détail des coûts"
            Outils.affiche_message(info)
            return None

        lignes = []

        for code_client in sorted(sommes.sommes_clients.keys()):
            client = clients.donnees[code_client]

            if code_client in sommes.sommes_comptes:
                sclo = sommes.sommes_comptes[code_client]
                comptes_utilises = Outils.comptes_in_somme(sclo, comptes)
                base_client = [edition.annee, edition.mois, code_client, client['code_sap'], client['abrev_labo'],
                               'U', client['nature']]

                for id_compte, num_compte in sorted(comptes_utilises.items(), key=lambda x: x[1]):
                    compte = comptes.donnees[id_compte]
                    base_compte = base_client + [id_compte, num_compte, compte['intitule'], compte['type_subside']]

                    if code_client in acces.sommes and id_compte in acces.sommes[code_client]['categories']:
                        som_cats = acces.sommes[code_client]['categories'][id_compte]['machine']
                        for id_categorie, som_cat in sorted(som_cats.items()):
                            duree = som_cat['duree_hp'] + som_cat['duree_hc']
                            ligne = base_compte + ['M', id_categorie, categories.donnees[id_categorie]['intitule'], duree,
                                                   som_cat['mo'], 0, 0, 0, 0, "", "", "", "", "", "", ""]
                            lignes.append(ligne)

                    if code_client in livraisons.sommes and id_compte in livraisons.sommes[code_client]:
                        somme = livraisons.sommes[code_client][id_compte]

                        for article in generaux.articles_d3:
                            if article.code_d in somme:
                                for no_prestation, sip in sorted(somme[article.code_d].items()):
                                    prestation = prestations.prestation_de_num(no_prestation)
                                    ligne = base_compte + [article.code_d, "", "", "", "", "", "", "", "",
                                                           article.intitule_court, no_prestation, sip['nom'],
                                                           Outils.format_2_dec(sip['montantx']),
                                                           Outils.format_2_dec(sip['rabais']), prestation['categ_stock'], prestation['affiliation']]
                                    lignes.append(ligne)

        return lignes
示例#28
0
 def obtenir_comptes(self):
     """
     retourne la liste de tous les comptes clients
     :return: liste des comptes clients présents dans les données livraisons importées
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les comptes"
         Outils.affiche_message(info)
         return []
     return self.comptes
示例#29
0
 def obtenir_codes(self):
     """
     retourne les codes de tous les clients
     :return: codes de tous les clients
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les codes"
         Outils.affiche_message(info)
         return []
     return self.codes
示例#30
0
    def est_coherent(self, clients, generaux):
        """
        vérifie que les données du fichier importé sont cohérentes (code client dans clients,
        id compte unique), et efface les colonnes mois et année
        :param clients: clients importés
        :param generaux: paramètres généraux
        :return: 1 s'il y a une erreur, 0 sinon
        """
        if self.verifie_date == 0:
            info = self.libelle + ". vous devez vérifier la date avant de vérifier la cohérence"
            Outils.affiche_message(info)
            return 1

        if self.verifie_coherence == 1:
            print(self.libelle + ": cohérence déjà vérifiée")
            return 0

        msg = ""
        ligne = 1
        ids = []
        donnees_dict = {}

        for donnee in self.donnees:
            if donnee['code_client'] == "":
                msg += "le code client de la ligne " + str(
                    ligne) + " ne peut être vide\n"
            elif donnee['code_client'] not in clients.donnees:
                msg += "le code client " + donnee['code_client'] + " de la ligne " + str(ligne) + \
                       " n'est pas référencé\n"

            if donnee['id_compte'] == "":
                msg += "le compte id de la ligne " + str(
                    ligne) + " ne peut être vide\n"
            elif donnee['id_compte'] not in ids:
                ids.append(donnee['id_compte'])
            else:
                msg += "l'id compte '" + donnee['id_compte'] + "' de la ligne " + str(ligne) +\
                       " n'est pas unique\n"
            if donnee['type_tarif'] != generaux.code_t:
                msg += "le type de tarif de la ligne " + str(
                    ligne) + " n'est pas correct\n"

            del donnee['annee']
            del donnee['mois']
            donnees_dict[donnee['id_compte']] = donnee
            ligne += 1

        self.donnees = donnees_dict
        self.verifie_coherence = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            Outils.affiche_message(msg)
            return 1
        return 0
示例#31
0
    def table_prix_lvr_jd(code_client, id_compte, intitule_compte, sco, sommes_livraisons, generaux):
        """
        Prix LVR J/D - Table Compte Récap Prestations livrées/code D
        :param code_client: code du client concerné
        :param id_compte: id du compte concerné
        :param intitule_compte: intitulé du compte concerné
        :param sco: sommes compte calculées
        :param sommes_livraisons: sommes des livraisons importées
        :param generaux: paramètres généraux
        :return: table au format latex
        """

        if code_client in sommes_livraisons and id_compte in sommes_livraisons[code_client]:
            somme = sommes_livraisons[code_client][id_compte]
            structure = r'''{|l|r|c|r|r|r|}'''
            legende = r'''Consommables et autres prestations'''
            contenu_prests = ""
            for article in generaux.articles_d3:
                if article.code_d in somme and sco['sommes_cat_m'][article.code_d] > 0:
                    if contenu_prests != "":
                        contenu_prests += r'''
                            \multicolumn{6}{c}{} \\
                            '''

                    contenu_prests += r'''
                        \hline
                        \multicolumn{1}{|l|}{
                        \textbf{''' + intitule_compte + " - " + Latex.echappe_caracteres(article.intitule_long) + r'''
                        }} & \multicolumn{1}{c|}{Quantité} & Unité & \multicolumn{1}{c|}{P.U.}
                        & \multicolumn{1}{c|}{Montant} & \multicolumn{1}{c|}{Rabais} \\
                        \hline
                        '''
                    for no_prestation, sip in sorted(somme[article.code_d].items()):
                        if sip['montant'] > 0:
                            dico_prestations = {'nom': Latex.echappe_caracteres(sip['nom']),
                                                'num': no_prestation,
                                                'quantite': "%.1f" % sip['quantite'],
                                                'unite': Latex.echappe_caracteres(sip['unite']),
                                                'pn': Outils.format_2_dec(sip['pn']),
                                                'montant': Outils.format_2_dec(sip['montant']),
                                                'rabais': Outils.format_2_dec(sip['rabais'])}
                            contenu_prests += r'''
                                %(num)s - %(nom)s & \hspace{5mm} %(quantite)s & %(unite)s & %(pn)s & %(montant)s
                                & %(rabais)s  \\
                                \hline
                                ''' % dico_prestations
                    dico_prestations = {'montant': Outils.format_2_dec(sco['sommes_cat_m'][article.code_d]),
                                        'rabais': Outils.format_2_dec(sco['sommes_cat_r'][article.code_d])}
                    contenu_prests += r'''
                        \multicolumn{4}{|r|}{Total} & %(montant)s & %(rabais)s  \\
                        \hline
                        ''' % dico_prestations
            return Latex.tableau(contenu_prests, structure, legende)
        else:
            return ""
示例#32
0
    def somme_par_compte(self, comptes):
        """
        calcule les sommes par comptes sous forme de dictionnaire : client->compte->clés_sommes
        :param comptes: comptes importés et vérifiés
        """

        if self.sp != 0:
            spc = {}
            for code_client, client in self.sommes_projets.items():
                if code_client not in spc:
                    spc[code_client] = {}
                cl = spc[code_client]
                for id_compte, compte in client.items():
                    cc = comptes.donnees[id_compte]
                    cl[id_compte] = self.nouveau_somme(Sommes.cles_somme_compte)
                    somme = cl[id_compte]
                    for num_projet, projet in compte.items():
                        somme["somme_j_pu"] += projet["somme_p_pu"]
                        somme["somme_j_pv"] += projet["somme_p_pv"]
                        somme["somme_j_pm"] += projet["somme_p_pm"]
                        somme["somme_j_qu"] += projet["somme_p_qu"]
                        somme["somme_j_qv"] += projet["somme_p_qv"]
                        somme["somme_j_qm"] += projet["somme_p_qm"]
                        somme["somme_j_om"] += projet["somme_p_om"]
                        somme["somme_j_nm"] += projet["somme_p_nm"]

                        for categorie in self.categories:
                            somme["sommes_cat_m"][categorie] += projet["sommes_cat_m"][categorie]
                            somme["sommes_cat_r"][categorie] += projet["sommes_cat_r"][categorie]
                            somme["tot_cat"][categorie] += projet["tot_cat"][categorie]

                    somme["prj"], somme["qrj"], somme["orj"] = Rabais.rabais_plafonnement(
                        somme["somme_j_pm"], cc["seuil"], cc["pourcent"]
                    )

                    somme["pj"] = somme["somme_j_pm"] - somme["prj"]
                    somme["qj"] = somme["somme_j_qm"] - somme["qrj"]
                    somme["oj"] = somme["somme_j_om"] - somme["orj"]

                    somme["nrj"] = somme["qrj"] + somme["orj"]
                    somme["nj"] = somme["somme_j_nm"] - somme["nrj"]

                    tot = somme["somme_j_pm"] + somme["somme_j_qm"] + somme["somme_j_om"]
                    for categorie in self.categories:
                        tot += somme["sommes_cat_m"][categorie]
                    if tot > 0:
                        somme["si_facture"] = 1

                    self.sco = 1
                    self.sommes_comptes = spc

        else:
            info = "Vous devez d'abord faire la somme par projet, avant la somme par compte"
            print(info)
            Outils.affiche_message(info)
示例#33
0
 def obtenir_ids(self):
     """
     retourne les ids de tous les comptes
     :return: ids de tous les comptes
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les ids"
         print(info)
         Outils.affiche_message(info)
         return []
     return self._ids
示例#34
0
 def obtenir_classes(self):
     """
     retourne toutes les classes de tarif présentes
     :return: toutes les classes de tarif présentes
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les classes"
         print(info)
         Outils.affiche_message(info)
         return []
     return self.classes
示例#35
0
 def obtenir_codes(self):
     """
     retourne les codes de tous les clients
     :return: codes de tous les clients
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les codes"
         print(info)
         Outils.affiche_message(info)
         return []
     return self.codes
示例#36
0
    def somme_par_categorie(self, comptes):
        """
        calcule les sommes par catégories sous forme de dictionnaire : client->catégorie->clés_sommes
        :param comptes: comptes importés et vérifiés
        """

        if self.verification.a_verifier != 0:
            info = "Sommes :  vous devez faire les vérifications avant de calculer les sommes"
            print(info)
            Outils.affiche_message(info)
            return

        if self.sco != 0:
            spc = {}
            for code_client, client in self.sommes_comptes.items():
                if code_client not in spc:
                    spc[code_client] = {}
                cl = spc[code_client]
                for id_compte, compte in client.items():
                    co = comptes.donnees[id_compte]
                    cat = co["categorie"]
                    if cat not in cl:
                        cl[cat] = self.nouveau_somme(Sommes.cles_somme_categorie)
                    somme = cl[cat]

                    somme["somme_k_pu"] += compte["somme_j_pu"]
                    somme["somme_k_pv"] += compte["somme_j_pv"]
                    somme["somme_k_pm"] += compte["somme_j_pm"]
                    somme["somme_k_prj"] += compte["prj"]
                    somme["pk"] += compte["pj"]
                    somme["somme_k_qu"] += compte["somme_j_qu"]
                    somme["somme_k_qv"] += compte["somme_j_qv"]
                    somme["somme_k_qm"] += compte["somme_j_qm"]
                    somme["somme_k_qrj"] += compte["qrj"]
                    somme["qk"] += compte["qj"]
                    somme["somme_k_om"] += compte["somme_j_om"]
                    somme["somme_k_orj"] += compte["orj"]
                    somme["ok"] += compte["oj"]
                    somme["somme_k_nm"] += compte["somme_j_nm"]
                    somme["somme_k_nrj"] += compte["nrj"]
                    somme["nk"] += compte["nj"]

                    for categorie in self.categories:
                        somme["sommes_cat_m"][categorie] += compte["sommes_cat_m"][categorie]
                        somme["sommes_cat_r"][categorie] += compte["sommes_cat_r"][categorie]
                        somme["tot_cat"][categorie] += compte["tot_cat"][categorie]

                    self.sca = 1
                    self.sommes_categories = spc

        else:
            info = "Vous devez d'abord faire la somme par compte, avant la somme par catégorie"
            print(info)
            Outils.affiche_message(info)
示例#37
0
 def obtenir_comptes(self):
     """
     retourne la liste de tous les comptes clients
     :return: liste des comptes clients présents dans les données livraisons importées
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les comptes"
         print(info)
         Outils.affiche_message(info)
         return []
     return self.comptes
示例#38
0
    def table_prix_cae_jk(code_client, id_compte, intitule_compte, sco, sommes_acces, categories):
        """
        Prix CAE J/K - Table Compte Récap Procédés/Catégorie Machine
        :param code_client: code du client concerné
        :param id_compte: id du compte concerné
        :param intitule_compte: intitulé du compte concerné
        :param sco: sommes compte calculées
        :param sommes_acces: sommes des accès importés
        :param categories: catégories importées
        :return: table au format latex
        """

        if code_client in sommes_acces and id_compte in sommes_acces[code_client]['comptes'] and sco['somme_j_mk'] > 0:

            structure = r'''{|l|c|c|r|r|}'''
            legende = r'''Services'''
            contenu = r'''
                \hline
                \textbf{''' + intitule_compte + r'''} & Unité & Quantité & \multicolumn{1}{c|}{PU} &
                 \multicolumn{1}{c|}{Montant}   \\
                \hline
                '''

            for cat, som_cat in sorted(sommes_acces[code_client]['categories'][id_compte].items()):

                for id_categorie, cats in sorted(som_cat.items()):
                    montant = cats['mk']
                    unite = categories.donnees[id_categorie]['unite']
                    if unite == 'hh_mm':
                        quantite = Outils.format_heure(cats['quantite'])
                    else:
                        quantite = cats['quantite']
                    if montant > 0:
                        dico_cat = {'intitule': Latex.echappe_caracteres(categories.donnees[id_categorie]['intitule']),
                                    'pk': Outils.format_2_dec(cats['pk']),
                                    'unite': Latex.echappe_caracteres(unite),
                                    'quantite': quantite,
                                    'mk': Outils.format_2_dec(montant)}
                        contenu += r'''
                            %(intitule)s & %(unite)s & %(quantite)s & %(pk)s & %(mk)s  \\
                            \hline
                            ''' % dico_cat

            dico_cat = {'mkj': Outils.format_2_dec(sco['somme_j_mk'])}

            contenu += r'''
                \multicolumn{4}{|r|}{Total} & %(mkj)s \\
                \hline
                ''' % dico_cat

            return Latex.tableau(contenu, structure, legende)
        else:
            return ""
示例#39
0
    def appel_des_outils(self):
        """
            Méthode qui permet de lancer la fenêtre qui contient les outils
        """

        # Création d'une instance de la classe Outils
        self._outils = Outils(self._instance_fenetre_principale)

        # Lancement de l'instance
        self._outils.exec_()

        self.accept()
示例#40
0
    def annuler(suffixe, client_unique, mois, annee, dossier_source,
                dossier_destination, dossier_source_backup):
        """
        annulation de modification des résumés mensuels au niveau du client dont la facture est supprimée
        :param suffixe: suffixe dossier version
        :param client_unique: client concerné
        :param mois: mois concerné
        :param annee: année concernée
        :param dossier_source: Une instance de la classe dossier.DossierSource
        :param dossier_destination: Une instance de la classe dossier.DossierDestination
        :param dossier_source_backup: Une instance de la classe dossier.DossierSource pour récupérer les
                                        données à remettre
        """
        for i in range(len(Resumes.fichiers)):
            fichier_backup = Resumes.fichiers[i] + "_" + str(
                annee) + "_" + Outils.mois_string(mois) + suffixe + ".csv"
            donnees_backup = Resumes.ouvrir_csv_seulement_client(
                dossier_source_backup, fichier_backup, client_unique,
                Resumes.positions[i])

            fichier_complet = Resumes.fichiers[i] + "_" + str(
                annee) + "_" + Outils.mois_string(mois) + ".csv"
            donnees_csv = Resumes.ouvrir_csv_sans_client(
                dossier_source, fichier_complet, client_unique,
                Resumes.positions[i])
            with dossier_destination.writer(fichier_complet) as fichier_writer:
                for ligne in donnees_csv:
                    fichier_writer.writerow(ligne)
                for ligne in donnees_backup:
                    fichier_writer.writerow(ligne)

        ticket_backup = "ticket_" + str(annee) + "_" + Outils.mois_string(
            mois) + suffixe + ".html"
        ticket_backup_texte = dossier_source_backup.string_lire(ticket_backup)
        index1, index2 = Resumes.section_position(ticket_backup_texte,
                                                  client_unique)
        section = ""
        if index1 is not None:
            section = ticket_backup_texte[index1:index2]

        nom_client = ""
        index1, index2, clients_liste_backup = Resumes.select_clients(
            ticket_backup_texte)
        for nom in clients_liste_backup:
            if client_unique in nom:
                nom_client = nom
                break
        ticket_complet = "ticket_" + str(annee) + "_" + Outils.mois_string(
            mois) + ".html"

        Resumes.maj_ticket(dossier_source, dossier_destination, ticket_complet,
                           section, client_unique, nom_client)
示例#41
0
    def est_coherent(self, comptes_actifs):
        """
        vérifie que les données du fichier importé sont cohérentes (code client dans clients,
        ou alors absent des clients actifs, id compte unique), et efface les colonnes mois et année
        :param comptes_actifs: codes des clients présents dans accès, réservations et livraisons
        :return: 1 s'il y a une erreur, 0 sinon
        """
        if self.verifie_date == 0:
            info = self.libelle + ". vous devez vérifier la date avant de vérifier la cohérence"
            print(info)
            Outils.affiche_message(info)
            return 1

        if self.verifie_coherence == 1:
            print(self.libelle + ": cohérence déjà vérifiée")
            return 0

        msg = ""
        ligne = 1
        ids = []
        donnees_dict = {}

        for donnee in self.donnees:
            if donnee['code_client'] == "":
                if donnee['id_compte'] in comptes_actifs:
                    print("code client du compte vide")
                    msg += "le code client de la ligne " + str(ligne) + " ne peut être vide si le compte est utilisé\n"
                continue

            if donnee['id_compte'] == "":
                msg += "le compte id de la ligne " + str(ligne) + " ne peut être vide\n"
            elif donnee['id_compte'] not in ids:
                ids.append(donnee['id_compte'])
                del donnee['annee']
                del donnee['mois']
                donnees_dict[donnee['id_compte']] = donnee
            else:
                msg += "l'id compte '" + donnee['id_compte'] + "' de la ligne " + str(ligne) +\
                       " n'est pas unique\n"

            ligne += 1

        self.donnees = donnees_dict
        self.verifie_coherence = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            print("msg : " + msg)
            Outils.affiche_message(msg)
            return 1
        return 0
示例#42
0
 def obtenir_noms_categories(self, categorie):
     """
     retourne le nom lié à une catégorie
     :return: nom lié à une catégorie
     """
     if self.verifie_coherence == 0:
         info = self.libelle + ". vous devez vérifier la cohérence avant de pouvoir obtenir les catégories"
         print(info)
         Outils.affiche_message(info)
         return []
     if categorie not in self.noms_cat:
         return categorie
     else:
         return self.noms_cat[categorie]
示例#43
0
 def extraction_ligne(self, ligne):
     """
     extracte une ligne de données du csv
     :param ligne: ligne lue du fichier
     :return: tableau représentant la ligne, indexé par les clés
     """
     num = len(self.cles)
     if len(ligne) != num:
         info = self.libelle + ": nombre de colonnes incorrect : " + str(len(ligne)) + ", attendu : " + str(num)
         print(info)
         Outils.affiche_message(info)
         sys.exit("Erreur de consistance")
     donnees_ligne = {}
     for xx in range(0, num):
         donnees_ligne[self.cles[xx]] = ligne[xx]
     return donnees_ligne
示例#44
0
    def ligne_tableau(article, poste, net, rabais, consommateur, edition):
        """
        retourne une ligne de tableau html

        :param article: Une instance de la classe generaux.Article
        :param poste: indice de poste
        :param net: montant net
        :param rabais: rabais sur le montant
        :param consommateur: consommateur
        :param edition: paramètres d'édition
        :return: ligne de tableau html
        """
        montant = net - rabais
        date_livraison = str(edition.dernier_jour) + "." + Outils.mois_string(edition.mois) + "." + str(edition.annee)
        description = article.code_d + " : " + article.code_sap
        dico_tab = {'poste': poste, 'date': date_livraison, 'descr': description,
                    'texte': article.texte_sap, 'nom': Latex.echappe_caracteres(consommateur),
                    'unit': article.unite, 'quantity': article.quantite,
                    'unit_p': "%.2f" % net, 'discount': "%.2f" % rabais, 'net': "%.2f" % montant}
        ligne = r'''<tr>
            <td> %(poste)s </td><td> %(date)s </td><td> %(nom)s </td><td> %(descr)s <br /> %(texte)s </td>
            <td> %(unit)s </td><td id="toright"> %(quantity)s </td><td id="toright"> %(unit_p)s </td>
            <td id="toright"> %(discount)s </td><td id="toright"> %(net)s </td>
            </tr>
            ''' % dico_tab
        return ligne
示例#45
0
    def ligne_facture(generaux, article, poste, net, rabais, op_centre, consommateur, edition):
        """
        retourne une ligne de facturation formatée

        :param generaux: paramètres généraux
        :param article: Une instance de la classe generaux.Article
        :param poste: indice de poste
        :param net: montant net
        :param rabais: rabais sur le montant
        :param op_centre: centre d'opération
        :param consommateur: consommateur
        :param edition: paramètres d'édition
        :return: ligne de facturation formatée
        """
        net = "%.2f" % net
        rabais = "%.2f" % rabais
        if rabais == 0:
            rabais = ""
        code_op = generaux.code_t + op_centre + article.code_d
        date_livraison = str(edition.annee) + Outils.mois_string(edition.mois) + str(edition.dernier_jour)

        return [poste, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
                "", "", "", "", "", "", article.code_sap, "", article.quantite,
                article.unite, article.type_prix, net,
                article.type_rabais, rabais, date_livraison, generaux.centre_financier, "",
                generaux.fonds, "", "", code_op, "", "", "", article.texte_sap,
                consommateur]
示例#46
0
    def est_coherent(self, comptes, machines):
        """
        vérifie que les données du fichier importé sont cohérentes (id compte parmi comptes,
        id machine parmi machines), et efface les colonnes mois et année
        :param comptes: comptes importés
        :param machines: machines importées
        :return: 1 s'il y a une erreur, 0 sinon
        """
        if self.verifie_date == 0:
            info = self.libelle + ". vous devez vérifier la date avant de vérifier la cohérence"
            print(info)
            Outils.affiche_message(info)
            return 1

        if self.verifie_coherence == 1:
            print(self.libelle + ": cohérence déjà vérifiée")
            return 0

        msg = ""
        ligne = 1
        donnees_list = []

        for donnee in self.donnees:
            if donnee['id_compte'] == "":
                msg += "le compte id de la ligne " + str(ligne) + " ne peut être vide\n"
            elif comptes.contient_id(donnee['id_compte']) == 0:
                msg += "le compte id '" + donnee['id_compte'] + "' de la ligne " + str(ligne) + " n'est pas référencé\n"
            elif donnee['code_client'] not in self.comptes:
                self.comptes[donnee['code_client']] = [donnee['id_compte']]
            elif donnee['id_compte'] not in self.comptes[donnee['code_client']]:
                self.comptes[donnee['code_client']].append(donnee['id_compte'])

            if donnee['id_machine'] == "":
                msg += "le machine id de la ligne " + str(ligne) + " ne peut être vide\n"
            elif machines.contient_id(donnee['id_machine']) == 0:
                msg += "le machine id '" + donnee['id_machine'] + "' de la ligne " + str(ligne) \
                       + " n'est pas référencé\n"

            donnee['duree_hp'], info = Outils.est_un_nombre(donnee['duree_hp'], "la durée réservée HP", ligne)
            msg += info
            donnee['duree_hc'], info = Outils.est_un_nombre(donnee['duree_hc'], "la durée réservée HC", ligne)
            msg += info
            donnee['duree_ouvree'], info = Outils.est_un_nombre(donnee['duree_ouvree'], "la durée ouvrée", ligne)
            msg += info

            del donnee['annee']
            del donnee['mois']
            donnees_list.append(donnee)

            ligne += 1

        self.donnees = donnees_list
        self.verifie_coherence = 1

        if msg != "":
            msg = self.libelle + "\n" + msg
            print("msg : " + msg)
            Outils.affiche_message(msg)
            return 1
        return 0
示例#47
0
    def __init__(self, dossier_source):
        """
        initialisation et importation des données

        :param dossier_source: Une instance de la classe dossier.DossierSource
        """
        try:
            fichier_reader = dossier_source.reader(self.nom_fichier)
            donnees_csv = []
            for ligne in fichier_reader:
                donnees_ligne = self.extraction_ligne(ligne)
                if donnees_ligne == -1:
                    continue
                donnees_csv.append(donnees_ligne)
            self.donnees = donnees_csv
            self.verifie_date = 0
            self.verifie_coherence = 0
        except IOError as e:
            Outils.fatal(e, "impossible d'ouvrir le fichier : " + self.nom_fichier)
示例#48
0
    def calcul_montants(self, machines, coefmachines, comptes, clients, verification):
        """
        calcule les montants 'pu', 'qu' et 'mo' et les ajoute aux données
        :param machines: machines importées
        :param coefmachines: coefficients machines importés et vérifiés
        :param comptes: comptes importés et vérifiés
        :param clients: clients importés et vérifiés
        :param verification: pour vérifier si les dates et les cohérences sont correctes

        """
        if verification.a_verifier != 0:
            info = self.libelle + ". vous devez faire les vérifications avant de calculer les montants"
            print(info)
            Outils.affiche_message(info)
            return

        donnees_list = []
        for donnee in self.donnees:
            compte = comptes.donnees[donnee['id_compte']]
            machine = machines.donnees[donnee['id_machine']]
            client = clients.donnees[compte['code_client']]
            coefmachine = coefmachines.donnees[client['id_classe_tarif'] + machine['categorie']]

            donnee['pu'] = round(donnee['duree_machine_hp'] / 60 * round(machine['t_h_machine_hp_p'] *
                                                                         coefmachine['coef_p'], 2) +
                                 donnee['duree_machine_hc'] / 60 * round(machine['t_h_machine_hc_p'] *
                                                                         coefmachine['coef_p']), 2)

            donnee['qu'] = round(donnee['duree_machine_hp'] / 60 * round(machine['t_h_machine_hp_np'] *
                                                                         coefmachine['coef_np'], 2) +
                                 donnee['duree_machine_hc'] / 60 * round(machine['t_h_machine_hc_np'] *
                                                                         coefmachine['coef_np']), 2)

            donnee['om'] = round(donnee['duree_operateur_hp'] / 60 *
                                 round(machine['t_h_operateur_hp_mo'] * coefmachine['coef_mo'], 2) +
                                 donnee['duree_operateur_hc'] / 60 *
                                 round(machine['t_h_operateur_hc_mo'] * coefmachine['coef_mo']), 2)

            donnees_list.append(donnee)
        self.donnees = donnees_list
示例#49
0
    def __init__(self, dossier_source):
        """
        initialisation et importation des données

        :param dossier_source: Une instance de la classe dossier.DossierSource
        """
        donnees_csv = []
        try:
            for ligne in dossier_source.reader(self.nom_fichier):
                donnees_csv.append(ligne)
        except IOError as e:
            Outils.fatal(e, "impossible d'ouvrir le fichier : " + Edition.nom_fichier)

        num = 3
        if len(donnees_csv) != num:
            Outils.fatal(
                ErreurConsistance(),
                Edition.libelle + ": nombre de lignes incorrect : " + str(len(donnees_csv)) + ", attendu : " + str(num),
            )
        try:
            self.annee = int(donnees_csv[0][1])
            self.mois = int(donnees_csv[1][1])
        except ValueError as e:
            Outils.fatal(e, Edition.libelle + "\nle mois et l'année doivent être des nombres")

        self.version = donnees_csv[2][1]
        self.client_unique = ""

        jours = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        if self.mois != 2:
            jour = jours[self.mois - 1]
        else:
            if self.annee % 4 == 0:
                if self.annee % 100 == 0:
                    if self.annee % 400 == 0:
                        jour = 29
                    else:
                        jour = 28
                else:
                    jour = 29
            else:
                jour = 28
        self.dernier_jour = jour

        mois_fr = [
            "janvier",
            "février",
            "mars",
            "avril",
            "mai",
            "juin",
            "juillet",
            "août",
            "septembre",
            "octobre",
            "novembre",
            "décembre",
        ]
        self.mois_txt = mois_fr[self.mois - 1]
示例#50
0
    def calcul_montants(self, machines, coefmachines, comptes, clients, verification):
        """
        calcule les montants 'pv' et 'qv' et les ajoute aux données
        :param machines: machines importées et vérifiées
        :param coefmachines: coefficients machines importés et vérifiés
        :param comptes: comptes importés et vérifiés
        :param clients: clients importés et vérifiés
        :param verification: pour vérifier si les dates et les cohérences sont correctes
        """
        if verification.a_verifier != 0:
            info = self.libelle + ". vous devez faire les vérifications avant de calculer les montants"
            print(info)
            Outils.affiche_message(info)
            return

        donnees_list = []
        for donnee in self.donnees:
            compte = comptes.donnees[donnee['id_compte']]
            machine = machines.donnees[donnee['id_machine']]
            client = clients.donnees[compte['code_client']]
            coefmachine = coefmachines.donnees[client['id_classe_tarif'] + machine['categorie']]
            duree_fact_hp, duree_fact_hc = Rabais.rabais_reservation(machine['delai_sans_frais'],
                                                                     donnee['duree_ouvree'],
                                                                     donnee['duree_hp'],
                                                                     donnee['duree_hc'])

            donnee['pv'] = round(duree_fact_hp / 60 * round(machine['t_h_reservation_hp_p'] *
                                                            coefmachine['coef_p'], 2) + duree_fact_hc / 60 *
                                 round(machine['t_h_reservation_hc_p'] * coefmachine['coef_p']), 2)

            donnee['qv'] = round(duree_fact_hp / 60 * round(machine['t_h_reservation_hp_np'] *
                                                            coefmachine['coef_np'], 2) + duree_fact_hc / 60 *
                                 round(machine['t_h_reservation_hc_np'] * coefmachine['coef_np']), 2)

            donnee['duree_fact_hp'] = duree_fact_hp
            donnee['duree_fact_hc'] = duree_fact_hc
            donnees_list.append(donnee)
        self.donnees = donnees_list
示例#51
0
    def verification_cohérence(self, generaux, edition, acces, clients, coefmachines, coefprests, comptes, livraisons,
                               machines, prestations, reservations):
        """
        vérifie la cohérence des données importées
        :param generaux: paramètres généraux
        :param edition: paramètres d'édition
        :param acces: accès importés
        :param clients: clients importés
        :param coefmachines: coefficients machines importés
        :param coefprests: coefficients prestations importés
        :param comptes: comptes importés
        :param livraisons: livraisons importées
        :param machines: machines importées
        :param prestations: prestations importées
        :param reservations: réservations importées
        :return: 0 si ok, sinon le nombre d'échecs à la vérification
        """
        verif = 0
        verif += acces.est_coherent(comptes, machines)
        verif += reservations.est_coherent(comptes, machines)
        verif += livraisons.est_coherent(comptes, prestations)
        verif += machines.est_coherent(coefmachines)
        verif += prestations.est_coherent(generaux, coefprests)
        verif += coefmachines.est_coherent()
        verif += coefprests.est_coherent(generaux)
        verif += clients.est_coherent(coefmachines, coefprests, generaux)

        comptes_actifs, clients_actifs = Verification.obtenir_comptes_clients_actifs(acces, reservations, livraisons)

        if (edition.version != '0') and (len(clients_actifs) > 1):
            Outils.affiche_message("Si version différente de 0, un seul client autorisé")
            sys.exit("Trop de clients pour version > 0")

        verif += comptes.est_coherent(comptes_actifs)
        self.a_verifier = 0
        if len(clients_actifs) == 1:
            edition.client_unique = clients_actifs[0]
        return verif
示例#52
0
 def ligne_tableau(self, article, poste, net, rabais, consommateur, edition):
     montant = net - rabais
     date_livraison = str(edition.dernier_jour) + "." + Outils.mois_string(edition.mois) + "." + str(edition.annee)
     description = article.code_d + " : " + article.code_sap
     dico_tab = {'poste': poste, 'date': date_livraison, 'descr': description,
                 'texte': article.texte_sap, 'nom': Latex.echappe_caracteres(consommateur),
                 'unit': article.unite, 'quantity': article.quantite,
                 'unit_p': "%.2f" % net, 'discount': "%.2f" % rabais, 'net': "%.2f" % montant}
     ligne = r'''<tr>
         <td> %(poste)s </td><td> %(date)s </td><td> %(nom)s </td><td> %(descr)s <br /> %(texte)s </td>
         <td> %(unit)s </td><td id="toright"> %(quantity)s </td><td id="toright"> %(unit_p)s </td>
         <td id="toright"> %(discount)s </td><td id="toright"> %(net)s </td>
         </tr>
         ''' % dico_tab
     return ligne
示例#53
0
    def somme_par_client(self, clients, reservations):
        """
        calcule les sommes par clients sous forme de dictionnaire : client->clés_sommes
        :param clients: clients importés et vérifiés
        :param reservations: réservations importées et vérifiées
        """

        if self.verification.a_verifier != 0:
            info = "Sommes :  vous devez faire les vérifications avant de calculer les sommes"
            print(info)
            Outils.affiche_message(info)
            return

        if self.sca != 0:
            spcl = {}
            for code_client, spca_cl in self.sommes_categories.items():
                spcl[code_client] = self.nouveau_somme(Sommes.cles_somme_client)
                somme = spcl[code_client]
                for cat, som_cat in spca_cl.items():

                    somme['somme_t_ai'] += som_cat['somme_k_ai']
                    somme['somme_t_bi'] += som_cat['somme_k_bi']
                    somme['somme_t_ci'] += som_cat['somme_k_ci']
                    somme['somme_t_oi'] += som_cat['somme_k_oi']
                    somme['mat'] += som_cat['somme_k_mai']
                    somme['mot'] += som_cat['somme_k_moi']
                    somme['dst'] += som_cat['somme_k_dsi']
                    somme['dht'] += som_cat['somme_k_dhi']
                    somme['somme_t_mm'] += som_cat['somme_k_mm']
                    somme['somme_t_mr'] += som_cat['somme_k_mr']
                    somme['mt'] += som_cat['mk']

                    for categorie in self.categories:
                        somme['sommes_cat_m'][categorie] += som_cat['sommes_cat_m'][categorie]
                        somme['sommes_cat_r'][categorie] += som_cat['sommes_cat_r'][categorie]
                        somme['tot_cat'][categorie] += som_cat['tot_cat'][categorie]

                spco_cl = self.sommes_comptes[code_client]
                somme['res'] = {}
                somme['rm'] = 0
                for id_co, spco_co in spco_cl.items():
                    for id_mach, mach in spco_co['res'].items():
                        if id_mach not in somme['res']:
                            somme['res'][id_mach] = {'pen_hp': 0, 'pen_hc': 0, 'm_hp': 0, 'm_hc': 0}
                        som_m = somme['res'][id_mach]
                        som_m['pen_hp'] += mach['pen_hp']
                        som_m['pen_hc'] += mach['pen_hc']

                for id_mach, som_m in somme['res'].items():
                    if som_m['pen_hp'] > 0:
                        som_m['m_hp'] += som_m['pen_hp'] * reservations.sommes[code_client]['machines'][id_mach]['pu_hp']
                        somme['rm'] += som_m['m_hp']
                    if som_m['pen_hc'] > 0:
                        som_m['m_hc'] += som_m['pen_hc'] * reservations.sommes[code_client]['machines'][id_mach]['pu_hc']
                        somme['rm'] += som_m['m_hc']

                somme['rr'] = Rabais.rabais_reservation_petit_montant(somme['rm'], self.min_fact_rese)
                somme['r'] = somme['rm'] - somme['rr']

                client = clients.donnees[code_client]

                somme['somme_eq'], somme['somme_t'], somme['em'], somme['er0'], somme['er'] = \
                    Rabais.rabais_emolument(somme['r'], somme['mt'], somme['mot'], somme['tot_cat'],
                                            client['emol_base_mens'], client['emol_fixe'], client['coef'],
                                            client['emol_sans_activite'])
                somme['e'] = somme['em'] - somme['er']

            # print("")
            # print("spcl")
            # for code in spcl:
            #     if code != "220208":
            #         continue
            #     somme = spcl[code]
            #     print(code, somme['mat'])

            self.calculees = 1
            self.sommes_clients = spcl

        else:
            info = "Vous devez d'abord faire la somme par catégorie, avant la somme par client"
            print(info)
            Outils.affiche_message(info)
示例#54
0
import sys
from docopt import docopt

from importes import Client, Acces, CoefMachine, CoefPrest, Compte, Livraison, Machine, Prestation, Reservation, DossierSource, DossierDestination
from outils import Outils
from parametres import Edition, Generaux
from traitement import Annexes, BilanMensuel, Facture, Sommes, Verification
from prod2qual import Prod2Qual
from latex import Latex

arguments = docopt(__doc__)

plateforme = sys.platform

if arguments["--sansgraphiques"]:
    Outils.interface_graphique(False)

if arguments["--entrees"] :
  dossier_data = arguments["--entrees"]
else:
  dossier_data = Outils.choisir_dossier(plateforme)
dossier_source = DossierSource(dossier_data)

edition = Edition(dossier_source)

acces = Acces(dossier_source)
clients = Client(dossier_source)
coefmachines = CoefMachine(dossier_source)
coefprests = CoefPrest(dossier_source)
comptes = Compte(dossier_source)
livraisons = Livraison(dossier_source)
示例#55
0
    def sommes_par_projet(self, livraisons, acces, prestations, comptes):
        """
        calcule les sommes par projets sous forme de dictionnaire : client->compte->projet->clés_sommes
        :param livraisons: livraisons importées et vérifiées
        :param acces: accès machines importés et vérifiés
        :param prestations: prestations importées et vérifiées
        :param comptes: comptes importés et vérifiés
        """

        if self.verification.a_verifier != 0:
            info = "Sommes :  vous devez faire les vérifications avant de calculer les sommes"
            print(info)
            Outils.affiche_message(info)
            return

        spp = {}
        for acce in acces.donnees:
            id_compte = acce['id_compte']
            code_client = comptes.donnees[id_compte]['code_client']
            if code_client not in spp:
                spp[code_client] = {}
            spp_cl = spp[code_client]
            if id_compte not in spp_cl:
                spp_cl[id_compte] = {}
            num_projet = acce['num_projet']
            spp_co = spp_cl[id_compte]
            if num_projet not in spp_co:
                spp_co[num_projet] = self.nouveau_somme(Sommes.cles_somme_projet)
                projet = spp_co[num_projet]
                projet['intitule'] = acce['intitule_projet']
            else:
                projet = spp_co[num_projet]
            projet['somme_p_ai'] += acce['ai']
            projet['somme_p_bi'] += acce['bi']
            projet['somme_p_ci'] += acce['ci']
            projet['somme_p_oi'] += acce['oi']
            projet['somme_p_mai'] += acce['mai']
            projet['somme_p_moi'] += acce['moi']
            projet['somme_p_dsi'] += acce['dsi']
            projet['somme_p_dhi'] += acce['dhi']
            projet['somme_p_mm'] += acce['mm']
            projet['somme_p_mr'] += acce['mr']
            projet['mp'] += acce['m']

        for livraison in livraisons.donnees:
            id_compte = livraison['id_compte']
            code_client = comptes.donnees[id_compte]['code_client']
            if code_client not in spp:
                spp[code_client] = {}
            spp_cl = spp[code_client]
            if id_compte not in spp_cl:
                spp_cl[id_compte] = {}
            num_projet = livraison['num_projet']
            spp_co = spp_cl[id_compte]
            if num_projet not in spp_co:
                spp_co[num_projet] = self.nouveau_somme(Sommes.cles_somme_projet)
                projet = spp_co[num_projet]
                projet['intitule'] = livraison['intitule_projet']
            else:
                projet = spp_co[num_projet]

            id_prestation = livraison['id_prestation']
            prestation = prestations.donnees[id_prestation]

            projet['sommes_cat_m'][prestation['categorie']] += livraison['montant']
            projet['sommes_cat_r'][prestation['categorie']] += livraison['rabais_r']
            projet['tot_cat'][prestation['categorie']] += livraison['montant'] - livraison['rabais_r']

        # print("spp")
        # for code in spp:
        #     if code != "220208":
        #         continue
        #     print(code)
        #     spp_cl = spp[code]
        #     for id in spp_cl:
        #         print("   ", id)
        #         spp_co = spp_cl[id]
        #         for num in spp_co:
        #             projet = spp_co[num]
        #             print("   ", "   ", num, projet['somme_p_mai'])

        self.sp = 1
        self.sommes_projets = spp
示例#56
0
    def __init__(self, dossier_source, prod2qual=None):
        """
        initialisation et importation des données

        :param dossier_source: Une instance de la classe dossier.DossierSource
        :param prod2qual: Une instance de la classe Prod2Qual si on souhaite éditer
                          des factures et annexes avec les codes d'articles de
                          qualification
        """
        self._donnees = {}
        try:
            for ligne in dossier_source.reader(self.nom_fichier):
                cle = ligne.pop(0)
                if cle not in self.cles_autorisees:
                    Outils.fatal(ErreurConsistance(),
                                 "Clé inconnue dans %s: %s" % (self.nom_fichier, cle))
                if cle != "texte_sap":
                    while "" in ligne:
                        ligne.remove("")
                self._donnees[cle] = ligne
        except IOError as e:
            Outils.fatal(e, "impossible d'ouvrir le fichier : "+Generaux.nom_fichier)
        if prod2qual and 'code_sap_qas' in self._donnees:
            self._donnees['code_sap'] = self._donnees['code_sap_qas']

        erreurs = ""
        for cle in self.cles_obligatoires:
            if cle not in self._donnees:
                erreurs += "\nClé manquante dans %s: %s" % (self.nom_fichier, cle)

        try:
            for quantite in self._donnees['quantite'][1:]:
                int(quantite)
        except ValueError:
            erreurs += "les quantités doivent être des nombres entiers\n"
        codes_n = []
        for nn in self._donnees['code_n'][1:]:
            if nn not in codes_n:
                codes_n.append(nn)
            else:
                erreurs += "le code N '" + nn + "' n'est pas unique\n"
        codes_d = []
        for dd in self._donnees['code_d'][1:]:
            if dd not in codes_d:
                codes_d.append(dd)
            else:
                erreurs += "le code D '" + dd + "' n'est pas unique\n"

        if len(self._donnees['code_n']) != len(self._donnees['nature_client']):
            erreurs += "le nombre de colonees doit être le même pour le code N et pour la nature du client\n"

        if (len(self._donnees['code_d']) != len(self._donnees['code_sap'])) or (len(self._donnees['code_d']) !=
                len(self._donnees['quantite'])) or (len(self._donnees['code_d']) !=
                len(self._donnees['unite'])) or (len(self._donnees['code_d']) !=
                len(self._donnees['type_prix'])) or (len(self._donnees['code_d']) !=
                len(self._donnees['type_rabais'])) or (len(self._donnees['code_d']) != len(self._donnees['texte_sap'])):
            erreurs += "le nombre de colonees doit être le même pour le code D, le code SAP, la quantité, l'unité, " \
                   "le type de prix, le type de rabais et le texte SAP\n"

        if erreurs != "":
            Outils.fatal(ErreurConsistance(), self.libelle + "\n" + erreurs)
示例#57
0
    def somme_par_client(self, clients):
        """
        calcule les sommes par clients sous forme de dictionnaire : client->clés_sommes
        :param clients: clients importés et vérifiés
        """

        if self.verification.a_verifier != 0:
            info = "Sommes :  vous devez faire les vérifications avant de calculer les sommes"
            print(info)
            Outils.affiche_message(info)
            return

        if self.sca != 0:
            spc = {}
            for code_client, client in self.sommes_categories.items():
                spc[code_client] = self.nouveau_somme(Sommes.cles_somme_client)
                somme = spc[code_client]
                for cat, som_cat in client.items():
                    somme["somme_t_pu"] += som_cat["somme_k_pu"]
                    somme["somme_t_pv"] += som_cat["somme_k_pv"]
                    somme["somme_t_pm"] += som_cat["somme_k_pm"]
                    somme["somme_t_prj"] += som_cat["somme_k_prj"]
                    somme["pt"] += som_cat["pk"]
                    somme["somme_t_qu"] += som_cat["somme_k_qu"]
                    somme["somme_t_qv"] += som_cat["somme_k_qv"]
                    somme["somme_t_qm"] += som_cat["somme_k_qm"]
                    somme["somme_t_qrj"] += som_cat["somme_k_qrj"]
                    somme["qt"] += som_cat["qk"]
                    somme["somme_t_om"] += som_cat["somme_k_om"]
                    somme["somme_t_orj"] += som_cat["somme_k_orj"]
                    somme["ot"] += som_cat["ok"]
                    somme["somme_t_nm"] += som_cat["somme_k_nm"]
                    somme["somme_t_nrj"] += som_cat["somme_k_nrj"]
                    somme["nt"] += som_cat["nk"]

                    for categorie in self.categories:
                        somme["sommes_cat_m"][categorie] += som_cat["sommes_cat_m"][categorie]
                        somme["sommes_cat_r"][categorie] += som_cat["sommes_cat_r"][categorie]
                        somme["tot_cat"][categorie] += som_cat["tot_cat"][categorie]

                cl = clients.donnees[code_client]

                somme["somme_eq"], somme["somme_sb"], somme["somme_t"], somme["em"], somme["er0"], somme[
                    "er"
                ] = Rabais.rabais_emolument(
                    somme["pt"],
                    somme["qt"],
                    somme["ot"],
                    somme["tot_cat"],
                    cl["emol_base_mens"],
                    cl["emol_fixe"],
                    cl["coef"],
                    cl["emol_sans_activite"],
                )
                somme["e"] = somme["em"] - somme["er"]
                self.calculees = 1
                self.sommes_clients = spc

        else:
            info = "Vous devez d'abord faire la somme par catégorie, avant la somme par client"
            print(info)
            Outils.affiche_message(info)
示例#58
0
    def bilan(dossier_destination, edition, sommes, clients, generaux, acces, reservations, livraisons,
              comptes):
        """
        création du bilan

        :param dossier_destination: Une instance de la classe dossier.DossierDestination
        :param edition: paramètres d'édition
        :param sommes: sommes calculées
        :param clients: clients importés
        :param generaux: paramètres généraux
        :param acces: accès importés
        :param reservations: réservations importés
        :param livraisons: livraisons importées
        :param comptes: comptes importés
        """

        if sommes.calculees == 0:
            info = "Vous devez d'abord faire toutes les sommes avant de pouvoir créer le bilan mensuel"
            print(info)
            Outils.affiche_message(info)
            return

        nom = "bilan_" + str(edition.annee) + "_" + Outils.mois_string(edition.mois) + "_" + \
              str(edition.version) + ".csv"

        with dossier_destination.writer(nom) as fichier_writer:

            ligne = ["année", "mois", "référence", "code client", "code client sap", "abrév. labo", "nom labo",
                     "type client", "nature client", "Em base", "somme EQ", "rabais Em", "règle", "nb utilisateurs",
                     "nb tot comptes", "nb comptes cat 1", "nb comptes cat 2", "nb comptes cat 3", "nb comptes cat 4",
                     "total M cat 1", "total M cat 2", "total M cat 3", "total M cat 4", "MAt", "MOt", "DSt", "DHt",
                     "Et", "Rt", "Mt"]
            for categorie in generaux.codes_d3():
                ligne.append(categorie + "t")
            ligne.append("total facturé HT")
            fichier_writer.writerow(ligne)

            for code_client in sorted(sommes.sommes_clients.keys()):
                scl = sommes.sommes_clients[code_client]
                sca = sommes.sommes_categories[code_client]
                client = clients.donnees[code_client]
                nature = generaux.nature_client_par_code_n(client['type_labo'])
                reference = nature + str(edition.annee)[2:] + Outils.mois_string(edition.mois) + "." + code_client
                nb_u = len(BilanMensuel.utilisateurs(acces, livraisons, reservations, code_client))
                cptes = BilanMensuel.comptes(acces, livraisons, reservations, code_client)
                cat = {'1': 0, '2': 0, '3': 0, '4': 0}
                nb_c = 0
                for cpte in cptes:
                    nb_c += 1
                    cat[comptes.donnees[cpte]['categorie']] += 1

                mk = {'1': 0, '2': 0, '3': 0, '4': 0}
                for num in mk.keys():
                    if num in sca:
                        mk[num] = sca[num]['mk']

                total = scl['somme_t'] + scl['e']

                ligne = [edition.annee, edition.mois, reference, code_client, client['code_sap'], client['abrev_labo'],
                         client['nom_labo'], 'U', client['type_labo'], scl['em'], "%.2f" % scl['somme_eq'], scl['er'],
                         client['emol_sans_activite'], nb_u, nb_c, cat['1'], cat['2'], cat['3'], cat['4'],
                         "%.2f" % mk['1'], "%.2f" % mk['2'], "%.2f" % mk['3'], "%.2f" % mk['4'], "%.2f" % scl['mat'],
                         scl['mot'], scl['dst'], scl['dht'], scl['e'], scl['r'], "%.2f" % scl['mt']]
                for categorie in generaux.codes_d3():
                    ligne.append(scl['tot_cat'][categorie])
                ligne.append("%.2f" % total)
                fichier_writer.writerow(ligne)
示例#59
0
    def est_coherent(self, coefmachines, coefprests, generaux):
        """
        vérifie que les données du fichier importé sont cohérentes (code client unique,
        classe tarif présente dans coefficients, type de labo dans paramètres), et efface les colonnes mois et année
        :param coefmachines: coefficients machines importés
        :param coefprests: coefficients prestations importés
        :param generaux: paramètres généraux
        :return: 1 s'il y a une erreur, 0 sinon
        """
        if self.verifie_date == 0:
            info = self.libelle + ". vous devez vérifier la date avant de vérifier la cohérence"
            print(info)
            Outils.affiche_message(info)
            return 1

        if self.verifie_coherence == 1:
            print(self.libelle + ": cohérence déjà vérifiée")
            return 0

        msg = ""
        ligne = 1
        classes = []
        donnees_dict = {}

        for donnee in self.donnees:
            if donnee['id_classe_tarif'] == "":
                msg += "la classe de tarif de la ligne " + str(ligne) + " ne peut être vide\n"
            elif donnee['id_classe_tarif'] not in classes:
                classes.append(donnee['id_classe_tarif'])

            if donnee['code_sap'] == "":
                msg += "le code sap de la ligne " + str(ligne) + " ne peut être vide\n"

            if donnee['code'] == "":
                msg += "le code client de la ligne " + str(ligne) + " ne peut être vide\n"
            elif donnee['code'] not in self.codes:
                self.codes.append(donnee['code'])
                del donnee['annee']
                del donnee['mois']
                donnees_dict[donnee['code']] = donnee
            else:
                msg += "le code client '" + donnee['code'] + "' de la ligne " + str(ligne) +\
                       " n'est pas unique\n"

            if donnee['type_labo'] == "":
                msg += "le type de labo de la ligne " + str(ligne) + " ne peut être vide\n"
            elif donnee['type_labo'] not in generaux.obtenir_code_n():
                msg += "le type de labo '" + donnee['type_labo'] + "' de la ligne " + str(ligne) +\
                    " n'existe pas dans les types N\n"

            if (donnee['mode'] != "") and (donnee['mode'] not in generaux.obtenir_modes_envoi()):
                msg += "le mode d'envoi '" + donnee['mode'] + "' de la ligne " + str(ligne) +\
                    " n'existe pas dans les modes d'envoi généraux\n"

            if (donnee['email'] != "") and (not re.match("[^@]+@[^@]+\.[^@]+", donnee['email'])):
                msg += "le format de l'e-mail '" + donnee['email'] + "' de la ligne " + str(ligne) +\
                    " n'est pas correct\n"

            if not((donnee['emol_sans_activite'] == "NON") or (donnee['emol_sans_activite'] == "ZERO") or
                    (donnee['emol_sans_activite'] == "OUI")):
                msg += "l'émolument à payer même sans activité de la ligne " + str(ligne) + " doit valoir ZERO, NON ou OUI\n"

            donnee['emol_base_mens'], info = Outils.est_un_nombre(donnee['emol_base_mens'], "l'émolument de base",
                                                                  ligne)
            msg += info
            donnee['emol_fixe'], info = Outils.est_un_nombre(donnee['emol_fixe'], "l'émolument fixe", ligne)
            msg += info
            donnee['coef'], info = Outils.est_un_nombre(donnee['coef'], "le coefficient a", ligne)
            msg += info

            ligne += 1

        self.donnees = donnees_dict
        self.verifie_coherence = 1

        for classe in classes:
            if classe not in coefmachines.obtenir_classes():
                msg += "la classe de tarif '" + classe + "' n'est pas présente dans les coefficients machines\n"
            if classe not in coefprests.obtenir_classes():
                msg += "la classe de tarif '" + classe + "' n'est pas présente dans les coefficients prestations\n"

        if msg != "":
            msg = self.libelle + "\n" + msg
            print("msg : " + msg)
            Outils.affiche_message(msg)
            return 1
        return 0
示例#60
0
    def sommes_par_projet(self, livraisons, reservations, acces, prestations, comptes):
        """
        calcule les sommes par projets sous forme de dictionnaire : client->compte->projet->clés_sommes
        :param livraisons: livraisons importées et vérifiées
        :param reservations: réservations importées et vérifiées
        :param acces: accès machines importés et vérifiés
        :param prestations: prestations importées et vérifiées
        :param comptes: comptes importés et vérifiés
        """

        if self.verification.a_verifier != 0:
            info = "Sommes :  vous devez faire les vérifications avant de calculer les sommes"
            print(info)
            Outils.affiche_message(info)
            return

        spp = {}
        for acce in acces.donnees:
            id_compte = acce["id_compte"]
            co = comptes.donnees[id_compte]
            code_client = co["code_client"]
            if code_client not in spp:
                spp[code_client] = {}
            client = spp[code_client]
            if id_compte not in client:
                client[id_compte] = {}
            num_projet = acce["num_projet"]
            compte = client[id_compte]
            if num_projet not in compte:
                compte[num_projet] = self.nouveau_somme(Sommes.cles_somme_projet)
                projet = compte[num_projet]
                projet["intitule"] = acce["intitule_projet"]
            else:
                projet = compte[num_projet]
            projet["somme_p_pu"] += acce["pu"]
            projet["somme_p_pm"] += acce["pu"]
            projet["somme_p_qu"] += acce["qu"]
            projet["somme_p_qm"] += acce["qu"]
            projet["somme_p_om"] += acce["om"]
            projet["somme_p_nm"] += acce["om"]
            projet["somme_p_nm"] += acce["qu"]

        for reservation in reservations.donnees:
            id_compte = reservation["id_compte"]
            co = comptes.donnees[id_compte]
            code_client = co["code_client"]
            if code_client not in spp:
                spp[code_client] = {}
            client = spp[code_client]
            if id_compte not in client:
                client[id_compte] = {}
            num_projet = reservation["num_projet"]
            compte = client[id_compte]
            if num_projet not in compte:
                compte[num_projet] = self.nouveau_somme(Sommes.cles_somme_projet)
                projet = compte[num_projet]
                projet["intitule"] = reservation["intitule_projet"]
            else:
                projet = compte[num_projet]
            projet["somme_p_pv"] += reservation["pv"]
            projet["somme_p_pm"] += reservation["pv"]
            projet["somme_p_qv"] += reservation["qv"]
            projet["somme_p_qm"] += reservation["qv"]
            projet["somme_p_nm"] += reservation["qv"]

        for livraison in livraisons.donnees:
            id_compte = livraison["id_compte"]
            co = comptes.donnees[id_compte]
            code_client = co["code_client"]
            if code_client not in spp:
                spp[code_client] = {}
            client = spp[code_client]
            if id_compte not in client:
                client[id_compte] = {}
            num_projet = livraison["num_projet"]
            compte = client[id_compte]
            if num_projet not in compte:
                compte[num_projet] = self.nouveau_somme(Sommes.cles_somme_projet)
                projet = compte[num_projet]
                projet["intitule"] = livraison["intitule_projet"]
            else:
                projet = compte[num_projet]

            id_prestation = livraison["id_prestation"]
            prestation = prestations.donnees[id_prestation]

            projet["sommes_cat_m"][prestation["categorie"]] += livraison["montant"]
            projet["sommes_cat_r"][prestation["categorie"]] += livraison["rabais_r"]
            projet["tot_cat"][prestation["categorie"]] += livraison["montant"] - livraison["rabais_r"]

        self.sp = 1
        self.sommes_projets = spp