From 47f03f78df2d80c4b32d0699d1566c9c08d843a8 Mon Sep 17 00:00:00 2001 From: Phuoc CAO Date: Tue, 9 Mar 2021 14:26:40 +0100 Subject: [PATCH] =?UTF-8?q?ajout=20stats=20sur=20les=20d=C3=A9lais=20de=20?= =?UTF-8?q?traitements=20dossier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mondumas/models/parametres.py | 14 ++ mondumas/models/utils.py | 107 +++++++++++++ mondumas/routes.py | 1 + mondumas/templates/default/home.pt | 5 + mondumas/templates/parametres/stats_delais.pt | 53 ++++++ mondumas/views/parametres.py | 40 +++++ mondumas/views/utils.py | 151 ++++++++++++++---- 7 files changed, 340 insertions(+), 31 deletions(-) create mode 100644 mondumas/templates/parametres/stats_delais.pt diff --git a/mondumas/models/parametres.py b/mondumas/models/parametres.py index abed1c0..f6b0243 100644 --- a/mondumas/models/parametres.py +++ b/mondumas/models/parametres.py @@ -198,3 +198,17 @@ def delete_expert(request, code_cab, code_exp): query = "DELETE FROM p_experts WHERE code_cab = :code_cab AND code_exp = :code_exp;" execute_query(request, query, {'code_cab': code_cab, 'code_exp': code_exp}) +def get_stats_delai_groupe(request, societe, datedeb, datefin): + query = """SELECT group2, group2_lib FROM stats_delais + WHERE societe=:societe AND id='delai_contact' AND group1 >= :datedeb AND group1 < :datefin GROUP BY group2 ORDER BY group2_lib;""" + results = request.dbsession.execute(query, {'societe': societe, 'datedeb': datedeb.strftime("%Y%m"), 'datefin': datefin.strftime("%Y%m")}) + return results.fetchall() + +def get_stats_delais(request, societe, datedeb, datefin, groupe): + # lire les examens sur 12 mois glissants par moniteur + query = """SELECT * FROM stats_delais + WHERE societe=:societe AND id='delai_contact' AND group1 >= :datedeb AND group1 < :datefin AND group2=:groupe order by group1;""" + results = request.dbsession.execute(query, {'societe': societe, 'datedeb': datedeb.strftime("%Y%m"), + 'datefin': datefin.strftime("%Y%m"), 'groupe': groupe}) + return results.fetchall() + diff --git a/mondumas/models/utils.py b/mondumas/models/utils.py index 353d957..53b4165 100644 --- a/mondumas/models/utils.py +++ b/mondumas/models/utils.py @@ -75,6 +75,14 @@ def get_all_chantiers(request,societe): results = request.dbsession.execute(query, {'societe': societe}).fetchall() return results +def get_chantiers_month(request, societe, date_sel): + # provisoire : toute l'année -> AND MONTH(date)=MONTH(:date_sel) + query = """SELECT * FROM dem_devis WHERE societe = :societe AND YEAR(date)=YEAR(:date_sel) + AND delai_facture = 0 AND nomcli NOT IN ('DUMAS JEAN MICHEL','DUMAS MENUISERIE','DUMAS PEINTURE'); + """ + results = request.dbsession.execute(query, {'societe': societe, 'date_sel': date_sel}).fetchall() + return results + def get_last_facture(request, societe, nochantier): query = "SELECT * FROM facture WHERE societe = :societe AND nochantier = :nochantier order by date DESC LIMIT 1;" results = request.dbsession.execute(query, {'societe': societe, 'nochantier': nochantier}).first() @@ -89,3 +97,102 @@ def update_chantier_status(request, societe, no_id, status): query = "UPDATE dem_devis SET status = :status, DATEMAJ = DATEMAJ WHERE societe = :societe AND no_id = :no_id AND status <> :status;" execute_query(request, query, {'societe': societe, 'no_id': no_id, 'status': status}) +def update_chantier_delais(request, societe, no_id, delai_contact, delai_rdv, delai_devis, delai_facture): + query = """UPDATE dem_devis SET delai_contact = :delai_contact, delai_rdv = :delai_rdv, delai_devis = :delai_devis, + delai_facture = :delai_facture, DATEMAJ = DATEMAJ + WHERE societe = :societe AND no_id = :no_id;""" + execute_query(request, query, {'societe': societe, 'no_id': no_id, 'delai_contact': delai_contact, 'delai_rdv': delai_rdv, + 'delai_devis': delai_devis, 'delai_facture': delai_facture}) + +def get_chantiers_dates(request, societe, nochantier): + # lire 1er contact du chantier + query = "SELECT date, datevi FROM dem_lig WHERE societe = :societe AND no_id = :nochantier AND datevi IS NOT NULL;" + results = request.dbsession.execute(query, {'societe': societe, 'nochantier': nochantier}).first() + if results: + date_contact = results.date + date_rdv = results.datevi + else: + date_contact = None + date_rdv = None + + # lire 1er devis du chantier + query = "SELECT date FROM devis WHERE societe = :societe AND nochantier = :nochantier order by date LIMIT 1;" + results = request.dbsession.execute(query, {'societe': societe, 'nochantier': nochantier}).first() + if results: + date_devis = results.date + else: + date_devis = None + + # lire 1ere facture du chantier + query = "SELECT date FROM facture WHERE societe = :societe AND nochantier = :nochantier order by date LIMIT 1;" + results = request.dbsession.execute(query, {'societe': societe, 'nochantier': nochantier}).first() + if results: + date_facture = results.date + else: + date_facture = None + return date_contact, date_rdv, date_devis, date_facture + +def purge_annuelle(request): + + # ----- Purger les DEVIS dont la facture est réglée de plus 10 ans + query = """DELETE devis.* FROM devis INNER JOIN facture ON devis.societe = facture.societe and devis.no_id = facture.nodevis + WHERE YEAR(facture.date) < YEAR(CURRENT_DATE()) - 10 AND ABS(facture.totalttc - facture.mtregl) < 1;""" + execute_query(request, query, {}) + + # ----- Purger les FACTURES réglées de plus 10 ans + query = """DELETE FROM facture WHERE YEAR(facture.date) < YEAR(CURRENT_DATE()) - 10 AND ABS(facture.totalttc - facture.mtregl) < 1;""" + execute_query(request, query, {}) + + # ----- Purger les DEVIS de + de 10 ans n'ayant pas de facture + query = """DELETE FROM devis WHERE YEAR(date) < YEAR(CURRENT_DATE()) - 10 AND nofact=0;""" + execute_query(request, query, {}) + + # -- RAZ les liens FACTURE et DEVIS + query = "UPDATE dem_devis SET nodevis = 0, nofact = 0, datemaj=datemaj WHERE YEAR(date) < YEAR(CURRENT_DATE()) - 10;" + execute_query(request, query, {}) + # -- recreer les lien DEVIS + query = """UPDATE dem_devis INNER JOIN facture ON dem_devis.societe = facture.societe and dem_devis.no_id = facture.nochantier + SET dem_devis.nofact = facture.no_id, datemaj=datemaj WHERE YEAR(dem_devis.date) < YEAR(CURRENT_DATE()) - 10;""" + execute_query(request, query, {}) + # -- recreer les lien factures + query = """UPDATE dem_devis INNER JOIN devis ON dem_devis.societe = devis.societe and dem_devis.no_id = devis.nochantier + SET dem_devis.nodevis = devis.no_id, datemaj=datemaj WHERE YEAR(dem_devis.date) < YEAR(CURRENT_DATE()) - 10;""" + execute_query(request, query, {}) + # ---- Purger les DEM_DEVIS n'ayant aucun DEVIS ni FACTURE + query = "DELETE FROM dem_devis WHERE YEAR(dem_devis.date) < YEAR(CURRENT_DATE()) - 10 AND nodevis = 0 AND nofact = 0;" + execute_query(request, query, {}) + + +def get_all_clients(request): + query = "SELECT * FROM clients;" + results = request.dbsession.execute(query, {}).fetchall() + return results + +def get_last_facture_client(request, societe, cd_cli): + query = "SELECT * FROM facture WHERE societe = :societe AND cd_cli = :cd_cli order by date DESC LIMIT 1;" + results = request.dbsession.execute(query, {'societe': societe, 'cd_cli': cd_cli}).first() + return results + +def get_last_devis_client(request, societe, cd_cli): + query = "SELECT * FROM devis WHERE societe = :societe AND cd_cli = :cd_cli order by date DESC LIMIT 1;" + results = request.dbsession.execute(query, {'societe': societe, 'cd_cli': cd_cli}).first() + return results + +def get_last_chantier_client(request, societe, cd_cli): + query = "SELECT * FROM dem_devis WHERE societe = :societe AND cd_cli = :cd_cli order by date DESC LIMIT 1;" + results = request.dbsession.execute(query, {'societe': societe, 'cd_cli': cd_cli}).first() + return results + +def update_client_dern_operation(request, societe, cd_cli, dern_operation): + if dern_operation != None: + d_operation = dern_operation.strftime('%Y/%m/%d') + query = "UPDATE clients SET dern_operation = :dern_operation, modif_le = modif_le WHERE societe=:societe AND cd_cli=:cd_cli;" + execute_query(request, query, {'societe': societe, 'cd_cli': cd_cli, 'dern_operation': d_operation}) + else: + query = "UPDATE clients SET dern_operation = NULL, modif_le = modif_le WHERE societe=:societe AND cd_cli=:cd_cli;" + execute_query(request, query, {'societe': societe, 'cd_cli': cd_cli}) + +def delete_client_unused(request): + query = "DELETE FROM clients WHERE cd_cli <> 1 AND dern_operation IS NULL AND YEAR(cree_le) < YEAR(CURRENT_DATE()) - 2;" + execute_query(request, query, {}) + diff --git a/mondumas/routes.py b/mondumas/routes.py index d6f358c..31f1039 100644 --- a/mondumas/routes.py +++ b/mondumas/routes.py @@ -59,6 +59,7 @@ def includeme(config): config.add_route('expert_edit', '/expert_edit/{code_cab}/{code_exp}') config.add_route('infrastructure', '/infrastructure') config.add_route('stats_dd', '/stats_dd/{societe}') + config.add_route('stats_delais', '/stats_delais/{societe}') config.add_route('rappels_rdv', '/rappels_rdv') config.add_route('rdf_cause_edit', '/rdf_cause_edit/{code}') config.add_route('rdf_causes', '/rdf_causes') diff --git a/mondumas/templates/default/home.pt b/mondumas/templates/default/home.pt index 0c20943..1380b19 100644 --- a/mondumas/templates/default/home.pt +++ b/mondumas/templates/default/home.pt @@ -44,6 +44,11 @@

PDF DOSSIERS

+
+ + +

PERFORMANCES

+


diff --git a/mondumas/templates/parametres/stats_delais.pt b/mondumas/templates/parametres/stats_delais.pt new file mode 100644 index 0000000..3bfe867 --- /dev/null +++ b/mondumas/templates/parametres/stats_delais.pt @@ -0,0 +1,53 @@ + +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+ + + + + +
+
+ + diff --git a/mondumas/views/parametres.py b/mondumas/views/parametres.py index 9d34648..2831831 100644 --- a/mondumas/views/parametres.py +++ b/mondumas/views/parametres.py @@ -13,6 +13,7 @@ from pyramid.httpexceptions import ( from pyramid_mailer.message import Message, Attachment from datetime import * +from dateutil.relativedelta import * from docutils.core import publish_parts import hashlib @@ -645,3 +646,42 @@ def expert_edit(request): 'message': message, } +@view_config(route_name='stats_delais', renderer='../templates/parametres/stats_delais.pt', permission='view') +def stats_delais(request): + + societe = request.matchdict['societe'] + url = request.route_url('stats_delais', societe = societe) + + datefin = date.today() + # debut = aujourd'hui - 12 mois + datedeb = datefin + relativedelta(months=-12) + + # lire les groupes + groupes = get_stats_delai_groupe(request, societe, datedeb, datefin) + # mémoriser le 1er de la liste + groupe = groupes[0].group2 + + # si groupe a été changé par le user + if 'groupe' in request.params: + groupe = request.params["groupe"] + + # lire les délais CONTACT du groupe + items = get_stats_delais(request, societe, datedeb, datefin, groupe) + barChart_annee=[] + barChart_annee.append(('Mois', groupe, {'role': 'annotation'}, 'Moyenne')) + title = '' + for item in items: + # construire la liste pour donut cible + title = '%s - %s' % (item.group2_lib, item.group2) + d = (item.group1_lib[:4], round(item.moyenne), str(item.moyenne)+'j ('+str(item.population)+')', round(item.moy_ref)) + barChart_annee.append(d) + + + return { + 'page_title': "Délais par groupe", + 'url': url, + 'barChart_annee': json.dumps(barChart_annee), + 'title': title, + 'groupes': groupes, + 'groupe': groupe, + } diff --git a/mondumas/views/utils.py b/mondumas/views/utils.py index fd60fa3..47f213b 100644 --- a/mondumas/views/utils.py +++ b/mondumas/views/utils.py @@ -32,10 +32,13 @@ def batch_nuit(request): truncate_log(request) # ----- PURGE des données obsolètes LE SAMEDI + insert_log(request, 'PURGE','- Début PURGE DES DONNEES OBSOLETES') TODAY = date.today() - if TODAY.weekday == 5 : + if TODAY.weekday() == 5 : + # purge_annuelle(request) + # purge_clients(request) delete_orphan_attached_files(request) - + # ----- RAPPELS DES RENDEZ-VOUS update_rappels(request) # attendre 5 secondes @@ -171,8 +174,10 @@ def batch_test(request): if par != 'Sansa5tark': return Response('Erreur : paramètre incorrect') - update_chantiers_status(request) - + # à revoir + # update_chantiers_status(request) + update_chantiers_delais(request, '2020/12/01') + return Response('Batch nuit terminé OK') def delete_orphan_attached_files(request): @@ -216,33 +221,117 @@ def update_chantiers_status(request): societes = ['PE','ME','PL','PO','CD'] for ste in societes: - # lire tous les chantiers - chantiers = get_all_chantiers(request, ste) - for item in chantiers: - # si le chantier est annulé, ne rien faire - if item.STATUS != 'Annulé': - status = '' - # lire la dernière facture du chantier - facture = get_last_facture(request, ste, item.NO_ID) - if facture : - # remonte le status de la facture ('','Régl part.', 'Réglée') - status = facture.STATUS - if status == '': - status = 'Facturé' + # lire tous les chantiers + chantiers = get_all_chantiers(request, ste) + for item in chantiers: + # si le chantier est annulé, ne rien faire + if item.STATUS != 'Annulé': + status = '' + # lire la dernière facture du chantier + facture = get_last_facture(request, ste, item.NO_ID) + if facture : + # remonte le status de la facture ('','Régl part.', 'Réglée') + status = facture.STATUS + if status == '': + status = 'Facturé' + else: + # lire le dernier devis du chantier ('','Commandé, 'Facturé') + devis = get_last_devis(request, ste, item.NO_ID) + if devis: + # remonte le status de la facture + status = devis.STATUS + if status == '' or status == '0': + status = 'Devis' else: - # lire le dernier devis du chantier ('','Commandé, 'Facturé') - devis = get_last_devis(request, ste, item.NO_ID) - if devis: - # remonte le status de la facture - status = devis.STATUS - if status == '' or status == '0': - status = 'Devis' - else: - if item.HUMIDITE != 0: - status = 'Humidité' - - # maj le status du chantier - update_chantier_status(request, ste, item.NO_ID, status) + if item.HUMIDITE != 0: + status = 'Humidité' + + # maj le status du chantier + update_chantier_status(request, ste, item.NO_ID, status) - +def update_chantiers_delais(request, date): + """ + Ce traitement calcul les delais : + - delai_contact : le nombre de jours entre la réception de la DD et la création d'un 1er RDV + - delai_rdv : le nombre de jours entre la réception de la DD et la date d'un 1er RDV + - delai_devis : le nombre de jours entre la réception de la DD et la date d'un 1er devis + - delai_facture : le nombre de jours entre la réception de la DD et la date d'une 1ere facture + + """ + societes = ['PE','ME','PL','PO','CD'] + + for societe in societes: + # lire tous les chantiers + chantiers = get_chantiers_month(request, societe, date) + for item in chantiers: + dt_dossier = datetime.combine(item.DATE, datetime.min.time()) + + # lire les dates 1er contact, 1er rdv, 1er devis, 1er facture du chantiers + date_contact, date_rdv, date_devis, date_facture = get_chantiers_dates(request, societe, item.NO_ID) + + # calculer le delai contact en jours + if date_contact == None: + delai_contact = 0 + else: + dt = datetime.combine(date_contact, datetime.min.time()) + delai_contact = (dt - dt_dossier).days + 1 + # delai négatif, ignorer + if delai_contact < 0: + delai_contact = 0 + # calculer le delai rdv en jours + if date_rdv == None: + delai_rdv = 0 + else: + dt = datetime.combine(date_rdv, datetime.min.time()) + delai_rdv = (dt - dt_dossier).days + 1 + # delai négatif, ignorer + if delai_rdv < 0: + delai_rdv = 0 + # calculer le delai contact en jours + if date_devis == None: + delai_devis = 0 + else: + dt = datetime.combine(date_devis, datetime.min.time()) + delai_devis = (dt - dt_dossier).days + 1 + # delai négatif, ignorer + if delai_devis < 0: + delai_devis = 0 + # calculer le delai facture en jours + if date_facture == None: + delai_facture = 0 + else: + dt = datetime.combine(date_facture, datetime.min.time()) + delai_facture = (dt - dt_dossier).days + 1 + # delai négatif, ignorer + if delai_facture < 0: + delai_facture = 0 + + update_chantier_delais(request, societe, item.NO_ID, delai_contact, delai_rdv, delai_devis, delai_facture) +def purge_clients(request): + # lire tous les clients + clients = get_all_clients(request) + for client in clients: + dern_operation = None + # lire la facture la + récente + facture = get_last_facture_client(request, client.societe, client.CD_CLI) + if facture: + dern_operation = facture.DATE + else: + # lire le devis le + récent + devis = get_last_devis_client(request, client.societe, client.CD_CLI) + if devis: + dern_operation = devis.DATE + else: + # lire le chantier le + récent + chantier = get_last_chantier_client(request, client.societe, client.CD_CLI) + if chantier: + dern_operation = chantier.DATE + + # mémoriser dernière opération + update_client_dern_operation(request, client.societe, client.CD_CLI, dern_operation) + + # supprimer clients ayant aucun dossier + delete_client_unused(request) + + return \ No newline at end of file