diff --git a/.gitignore b/.gitignore index f581bfe..fce6cc6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /odtkit -/exported_tickets config.py \ No newline at end of file diff --git a/__pycache__/menu_handlers.cpython-312.pyc b/__pycache__/menu_handlers.cpython-312.pyc index 4b6e9da..29f03a3 100644 Binary files a/__pycache__/menu_handlers.cpython-312.pyc and b/__pycache__/menu_handlers.cpython-312.pyc differ diff --git a/__pycache__/ticket_manager.cpython-312.pyc b/__pycache__/ticket_manager.cpython-312.pyc index c5f9951..5cb316a 100644 Binary files a/__pycache__/ticket_manager.cpython-312.pyc and b/__pycache__/ticket_manager.cpython-312.pyc differ diff --git a/__pycache__/utils.cpython-312.pyc b/__pycache__/utils.cpython-312.pyc index f3cad0f..bb04955 100644 Binary files a/__pycache__/utils.cpython-312.pyc and b/__pycache__/utils.cpython-312.pyc differ diff --git a/data_filter.py b/data_filter.py index 6de835d..e69de29 100644 --- a/data_filter.py +++ b/data_filter.py @@ -1,38 +0,0 @@ -import re -import html -from bs4 import BeautifulSoup - -def clean_html(content): - """Nettoie le contenu HTML en supprimant les balises.""" - if not content: - return "" - soup = BeautifulSoup(content, 'html.parser') - return soup.get_text(separator='\n', strip=True) - -def filter_ticket_data(ticket_data): - """Filtre les données d'un ticket pour ne garder que les informations essentielles.""" - - # Vérifier que ticket_data est bien une liste et extraire le premier élément - if isinstance(ticket_data, list) and len(ticket_data) > 0: - ticket_data = ticket_data[0] - else: - return {"Erreur": "Format de ticket invalide"} - - filtered_ticket = { - "ID du Ticket": ticket_data.get("id", "ID non disponible"), - "Nom": ticket_data.get("name", "Nom inconnu"), - "Code": ticket_data.get("code", "N/A"), - "Date Limite": ticket_data.get("date_deadline", "Non définie"), - "Projet": { - "ID": ticket_data.get("project_id", [None, "Projet inconnu"])[0], - "Nom": ticket_data.get("project_id", [None, "Projet inconnu"])[1] - }, - "Étape": { - "ID": ticket_data.get("stage_id", [None, "Étape inconnue"])[0], - "Nom": ticket_data.get("stage_id", [None, "Étape inconnue"])[1] - }, - "Description": clean_html(ticket_data.get("description", "")), - "Discussions": ticket_data.get("message_ids", []) - } - - return filtered_ticket diff --git a/exported_tickets/ticket_10157_raw.json b/exported_tickets/ticket_10157_raw.json deleted file mode 100644 index 3ac2224..0000000 --- a/exported_tickets/ticket_10157_raw.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "id": 10157, - "active": true, - "name": "L'arrondi au 1/10 ne se fait pas sur la granulométrie du contrôle de conformité", - "description": "

L'arrondi au 1/10 ne se fait pas sur la granulométrie du contrôle de conformité sur le granulat 0.5




", - "sequence": 3, - "stage_id": [ - 46, - "Tickets existants" - ], - "kanban_state": "normal", - "create_date": "2024-10-14 14:46:55", - "write_date": "2025-03-18 15:49:16", - "date_start": "2024-10-14 14:46:55", - "date_end": false, - "date_assign": false, - "date_deadline": false, - "date_last_stage_update": "2024-10-15 08:40:18", - "project_id": [ - 4, - "Tickets" - ], - "notes": false, - "planned_hours": 0.0, - "user_id": false, - "partner_id": [ - 28644, - "GROLLEMUND LABOROUTES GRAND EST, Marion NICOD" - ], - "company_id": [ - 1, - "CBAO S.A.R.L." - ], - "color": 0, - "displayed_image_id": false, - "parent_id": false, - "child_ids": [], - "email_from": "m.nicod@laboroutes.com", - "email_cc": false, - "working_hours_open": 0.0, - "working_hours_close": 0.0, - "working_days_open": 0.0, - "working_days_close": 0.0, - "website_message_ids": [ - 205371 - ], - "remaining_hours": 0.0, - "effective_hours": 0.0, - "total_hours_spent": 0.0, - "progress": 0.0, - "subtask_effective_hours": 0.0, - "timesheet_ids": [], - "priority": "0", - "code": "T10178", - "milestone_id": false, - "sale_line_id": false, - "sale_order_id": false, - "billable_type": "no", - "activity_ids": [], - "message_follower_ids": [ - 81962, - 81963 - ], - "message_ids": [ - 205371, - 205370, - 205302 - ], - "message_main_attachment_id": false, - "failed_message_ids": [], - "rating_ids": [], - "rating_last_value": 0.0, - "access_token": false, - "create_uid": [ - 32, - "Romuald GRUSON" - ], - "write_uid": [ - 22, - "Fabien LAFAY" - ], - "x_CBAO_windows_maj_ID": false, - "x_CBAO_version_signalement": false, - "x_CBAO_version_correction": false, - "x_CBAO_DateCorrection": false, - "x_CBAO_Scoring_Facilite": 0, - "x_CBAO_Scoring_Importance": 2, - "x_CBAO_Scoring_Urgence": 2, - "x_CBAO_Scoring_Incidence": 2, - "x_CBAO_Scoring_Resultat": 6, - "x_CBAO_InformationsSup": false, - "kanban_state_label": "En cours", - "subtask_planned_hours": 0.0, - "manager_id": [ - 8, - "Quentin FAIVRE" - ], - "user_email": false, - "attachment_ids": [], - "legend_blocked": "Bloqué", - "legend_done": "Prêt pour la prochaine étape", - "legend_normal": "En cours", - "subtask_project_id": [ - 4, - "Tickets" - ], - "subtask_count": 0, - "analytic_account_active": true, - "allow_timesheets": true, - "use_milestones": false, - "show_time_control": "start", - "is_project_map_empty": true, - "activity_state": false, - "activity_user_id": false, - "activity_type_id": false, - "activity_date_deadline": false, - "activity_summary": false, - "message_is_follower": false, - "message_unread": false, - "message_unread_counter": 0, - "message_needaction": false, - "message_needaction_counter": 0, - "message_has_error": false, - "message_has_error_counter": 0, - "message_attachment_count": 0, - "rating_last_feedback": false, - "rating_last_image": false, - "rating_count": 0, - "access_url": "/my/task/10157", - "access_warning": "", - "display_name": "[T10178] L'arrondi au 1/10 ne se fait pas sur la granulométrie du contrôle de conformité", - "__last_update": "2025-03-18 15:49:16", - "stage_id_value": "Tickets existants", - "project_id_value": "Tickets", - "partner_id_value": "GROLLEMUND LABOROUTES GRAND EST, Marion NICOD", - "manager_id_value": "Quentin FAIVRE", - "company_id_value": "CBAO S.A.R.L.", - "subtask_project_id_value": "Tickets", - "create_uid_value": "Romuald GRUSON", - "write_uid_value": "Fabien LAFAY" -} \ No newline at end of file diff --git a/exported_tickets/ticket_T10178_raw.json b/exported_tickets/ticket_T10178_raw.json deleted file mode 100644 index 80bbc25..0000000 --- a/exported_tickets/ticket_T10178_raw.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - 10157 -] \ No newline at end of file diff --git a/menu_handlers.py b/menu_handlers.py index d44e421..d46f947 100644 --- a/menu_handlers.py +++ b/menu_handlers.py @@ -1,5 +1,5 @@ from ticket_manager import TicketManager -from utils import get_user_choice, print_error +from utils import print_error # Initialisation de l'objet ticket_manager = TicketManager() diff --git a/old_functions.py b/old_functions.py deleted file mode 100644 index 2316bee..0000000 --- a/old_functions.py +++ /dev/null @@ -1,66 +0,0 @@ -def handle_list_models(): - """Gère l'affichage de la liste des modèles""" - ticket_manager.list_models() - - - -def handle_list_model_fields(): - """Gère l'affichage des champs d'un modèle""" - model_name = input("\nEntrez le nom du modèle: ") - if not model_name: - print("Aucun nom de modèle fourni.") - return - ticket_manager.list_model_fields(model_name) - - -def handle_export_model_fields_to_json(): - """Gère l'exportation des informations des champs d'un modèle en JSON""" - model_name = input("\nEntrez le nom du modèle: ") - if not model_name: - print("Aucun nom de modèle fourni.") - return - filename = input("Entrez le nom du fichier pour l'exportation: ") - if not filename: - print("Aucun nom de fichier fourni.") - return - ticket_manager.export_model_fields_to_json(model_name, filename) - - ///partie ticket_manager.py - def list_models(self): - """Affiche la liste des modèles disponibles dans Odoo""" - models = self._safe_execute('ir.model', 'search_read', [], ['model', 'name']) - if not models: - print_error("Aucun modèle disponible.") - return [] - - print("\nListe des modèles disponibles:") - for model in models: - print(f"Modèle: {model['name']} (ID: {model['model']})") - return models - - def list_model_fields(self, model_name): - """Affiche les champs d'un modèle donné""" - fields_info = self._safe_execute(model_name, 'fields_get') - if not fields_info: - print_error(f"Aucun champ trouvé pour le modèle {model_name}.") - return [] - - print(f"\nChamps du modèle {model_name}:") - for field_name, field_data in fields_info.items(): - print(f"Champ: {field_name} - Type: {field_data['type']}") - return fields_info - - def export_model_fields_to_json(self, model_name, filename): - """Exporte les champs d'un modèle dans un fichier JSON""" - fields_info = self._safe_execute(model_name, 'fields_get') - if not fields_info: - print_error(f"Aucun champ trouvé pour le modèle {model_name}.") - return - - data = {field_name: field_data['type'] for field_name, field_data in fields_info.items()} - filepath = os.path.join(EXPORT_DIR, filename) - - if save_json(filepath, data): - print(f"Champs du modèle {model_name} exportés dans {filepath}") - else: - print_error(f"Erreur lors de l'exportation des champs du modèle {model_name} dans {filepath}") \ No newline at end of file diff --git a/ticket_manager.py b/ticket_manager.py index 2bb0eb0..b882542 100644 --- a/ticket_manager.py +++ b/ticket_manager.py @@ -1,11 +1,8 @@ from odoo_connection import OdooConnection import os import json -import re -from utils import save_json, ensure_export_directory, print_error +from utils import print_error from config import EXPORT_DIR -from data_filter import filter_ticket_data -import odoorpc class TicketManager: """Gestionnaire de tickets simplifié avec seulement les fonctionnalités essentielles""" @@ -151,7 +148,7 @@ class TicketManager: # Récupérer les tickets du projet domain = [('project_id', '=', project_id)] - ticket_ids = self._safe_execute(self.model_name, 'search', domain, 0, 1000) + ticket_ids = self._safe_execute(self.model_name, 'search', domain, 0, 10) if not ticket_ids: print_error(f"Aucun ticket trouvé pour le projet {project_id}.") return diff --git a/utils.py b/utils.py index 54baa54..de76502 100644 --- a/utils.py +++ b/utils.py @@ -1,41 +1,2 @@ -import os -import json -from config import EXPORT_DIR - -def ensure_export_directory(subdir=None): - """Assure que le répertoire d'export existe""" - if subdir: - directory = os.path.join(EXPORT_DIR, subdir) - else: - directory = EXPORT_DIR - os.makedirs(directory, exist_ok=True) - return directory - -def save_json(filename, data): - """Sauvegarde des données au format JSON""" - try: - with open(filename, 'w', encoding='utf-8') as f: - json.dump(data, f, ensure_ascii=False, indent=4) - return True - except Exception as e: - print(f"Erreur lors de la sauvegarde du fichier {filename}: {e}") - return False - -def get_user_choice(prompt, options): - """Obtient un choix utilisateur parmi une liste d'options""" - while True: - print(prompt) - for i, option in enumerate(options, 1): - print(f"{i}. {option}") - - try: - choice = int(input("Votre choix: ")) - if 1 <= choice <= len(options): - return choice - else: - print("Choix invalide. Veuillez réessayer.") - except ValueError: - print("Veuillez entrer un nombre valide.") - def print_error(message): print(f" Erreur: {message}") \ No newline at end of file