plan for migration start

This commit is contained in:
xtremxpert 2025-01-27 07:17:59 -05:00
parent 9d97e13216
commit 066efe3ab2
66 changed files with 4276 additions and 0 deletions

View file

@ -0,0 +1,246 @@
# Migration vers Odoo 18.0 - Module account_credit_hold
## Fonctionnalités
- Ajoute un champ "Place on Credit Hold" sur les lignes de suivi de compte (account_followup.followup.line)
- Ajoute des champs et fonctionnalités sur les partenaires:
- postpone_hold_until: Date de report du blocage
- hold_bg: Champ technique pour le statut de blocage
- on_hold: État calculé du blocage de crédit
- Bloque la confirmation des commandes de vente si le client est en blocage de crédit
- Ajoute des indicateurs visuels (ruban rouge) sur:
- Commandes de vente
- Fiches partenaires
- Transferts de stock
- Ajoute des boutons pour mettre/lever le blocage de crédit dans la vue de suivi des comptes
## Analyse pour la Migration
### Dépendances
- sale
- account_followup
- stock
### Changements Techniques Requis
1. Mettre à jour la version dans __manifest__.py vers 18.0
2. Vérifier la compatibilité des vues XML avec Odoo 18.0
3. Vérifier si des changements dans l'API account_followup en 18.0
### Points d'Attention
1. Le module utilise l'héritage de vues et de modèles standard d'Odoo:
- account_followup.followup.line
- res.partner
- sale.order
- stock.picking
- account.followup.report
2. Fonctionnalités critiques à tester après migration:
- Calcul automatique du statut on_hold
- Blocage de la confirmation des commandes
- Nettoyage automatique des reports de blocage expirés (@api.autovacuum)
- Affichage correct des rubans d'avertissement
- Propagation du statut hold aux contacts liés (commercial_partner_id)
3. Implémentation Technique:
- Utilisation de champs computed avec store=True et compute_sudo=True
- Mécanisme de nettoyage automatique via @api.autovacuum
- Héritage de _execute_followup_partner pour automatisation du hold
- Messages de chatter automatiques lors des changements de statut
4. Points Spécifiques aux Vues:
- Utilisation du widget web_ribbon pour les indicateurs visuels
- Boutons conditionnels dans la vue de suivi des comptes
- Champs invisibles pour la logique d'affichage (hold_bg, on_hold)
- Groupes de sécurité sur le champ postpone_hold_until
## Questions et Considérations
1. Vérifier si Odoo 18.0 n'a pas introduit des fonctionnalités natives similaires dans account_followup:
- Système de blocage automatique des clients
- Gestion des périodes de grâce
- Indicateurs visuels de blocage
2. Points à valider:
- La structure des vues héritées est-elle identique en 18.0?
- Les champs related et computed fonctionnent-ils de la même manière?
- Le système de suivi des comptes (account_followup) a-t-il évolué?
- Le décorateur @api.autovacuum est-il toujours supporté?
- Le widget web_ribbon utilise-t-il toujours la même API?
3. Considérations d'Architecture:
- Le mécanisme de propagation du statut hold via commercial_partner_id est-il optimal?
- Possibilité de simplifier la logique de calcul du statut hold?
- Pertinence de stocker le champ hold_bg vs calcul à la demande
4. Alternatives Potentielles:
- Utiliser le système de credit limit natif d'Odoo avec des règles personnalisées?
- Intégrer avec le système de blocage des partenaires d'Odoo?
- Utiliser les étapes de facturation (invoice_status) plutôt qu'un champ séparé?
## Alternatives Natives Odoo 18.0
### Système de Crédit Natif
1. Odoo 18.0 inclut des fonctionnalités natives de gestion de crédit:
- Champ `credit_limit` sur res.partner
- Configuration du blocage au niveau de la société
- Règles de blocage basées sur:
- Montant de crédit maximum
- Factures échues
- Âge des factures
2. Possibilités d'utilisation des fonctionnalités natives:
- Utiliser `credit_limit` au lieu de `on_hold`
- Configurer les règles de blocage dans la configuration de la comptabilité
- Utiliser les notifications natives de dépassement de crédit
### Améliorations Possibles
1. Intégration avec le système natif:
- Synchroniser notre `on_hold` avec le système natif de blocage
- Utiliser les API natives de vérification de crédit
- Conserver uniquement les fonctionnalités non disponibles nativement
2. Simplification du code:
- Remplacer les champs custom par des champs natifs quand possible
- Utiliser le système d'alertes natif pour les rubans
- Intégrer avec le système de workflow natif
## Recommandations pour la Migration
### Approche "Vanilla First"
1. Évaluer chaque fonctionnalité custom:
- Est-elle disponible nativement dans Odoo 18.0?
- Peut-elle être remplacée par une configuration native?
- Le besoin business existe-t-il toujours?
2. Prioriser l'utilisation des fonctionnalités natives:
- Système de crédit natif
- Système de workflow natif
- API de notification standard
- Widgets standards de l'interface
### Modifications Techniques Recommandées
1. Remplacer les attributs obsolètes:
- Supprimer les `attrs` dans les vues (Odoo 16.0+)
- Utiliser `list` au lieu de `tree` (Odoo 17.0+)
- Adapter les widgets aux nouvelles conventions
2. Optimisation des performances:
- Utiliser les indexes de base de données appropriés
- Optimiser les recherches et calculs
- Implémenter le lazy loading quand possible
### Plan de Test Approfondi
1. Tests fonctionnels:
- Validation du comportement avec le système natif
- Tests de régression sur les fonctionnalités custom
- Vérification des performances
2. Tests d'intégration:
- Interaction avec le workflow de vente
- Synchronisation avec la comptabilité
- Comportement avec les autres modules
## État de la Migration
⚪ En analyse préliminaire
## Plan de Migration
### Étape 1: Analyse des Changements Odoo 18.0
- [ ] Examiner les changements dans account_followup
- [ ] Vérifier les nouvelles fonctionnalités de gestion de crédit
- [ ] Analyser les modifications des vues héritées
### Étape 2: Adaptation Technique
- [ ] Mise à jour du manifeste
- [ ] Vérification de la compatibilité des décorateurs
- [ ] Adaptation des vues XML si nécessaire
- [ ] Test des champs computed et related
### Étape 3: Tests Fonctionnels
- [ ] Validation du mécanisme de hold
- [ ] Test de la propagation aux contacts
- [ ] Vérification des nettoyages automatiques
- [ ] Test des indicateurs visuels
### Étape 4: Optimisation
- [ ] Évaluation des alternatives natives
- [ ] Simplification potentielle du code
- [ ] Amélioration des performances
## Notes de Version
- Version originale: 17.0.1.1.1
- Dernière analyse: 26/01/2025
## Fonctionnalités Natives dans Odoo 18.0
Odoo 18.0 inclut nativement plusieurs fonctionnalités de gestion du crédit :
1. **Gestion des Limites de Crédit**
- Champ `credit_limit` sur les partenaires
- Champ `use_partner_credit_limit` pour activer/désactiver par partenaire
- Configuration globale `account_use_credit_limit` au niveau de la société
- Champ `credit` pour le total des créances
- Champ `trust` pour le niveau de confiance du débiteur
2. **Visibilité et Contrôle**
- Champ `show_credit_limit` basé sur la configuration de la société
- Groupes de sécurité pour la gestion des limites de crédit
### Différences avec Notre Module
1. **Fonctionnalités à Migrer**
- [ ] Indicateurs visuels spécifiques pour les clients en dépassement
- [ ] Blocage automatique des commandes en dépassement
- [ ] Workflow d'approbation personnalisé
2. **Fonctionnalités à Adapter**
- [ ] Utiliser les champs natifs plutôt que nos champs customs
- [ ] Intégrer nos règles de blocage avec le système natif
- [ ] Adapter les rapports et vues pour utiliser les champs natifs
## Plan de Migration
### Phase 1 : Préparation
1. **Analyse des Données**
- [ ] Identifier les clients avec des limites de crédit
- [ ] Mapper les champs actuels vers les champs natifs
- [ ] Lister les règles de blocage personnalisées
2. **Configuration**
- [ ] Activer la gestion du crédit dans la configuration de la société
- [ ] Configurer les groupes de sécurité appropriés
- [ ] Préparer les scripts de migration des données
### Phase 2 : Migration
1. **Migration des Données**
- [ ] Transférer les limites de crédit vers le champ natif
- [ ] Migrer les configurations de blocage
- [ ] Mettre à jour les vues et rapports
2. **Développement**
- [ ] Adapter le code de blocage des commandes
- [ ] Implémenter les indicateurs visuels manquants
- [ ] Ajouter les fonctionnalités spécifiques non disponibles nativement
### Phase 3 : Tests
1. **Validation Fonctionnelle**
- [ ] Tester les limites de crédit
- [ ] Vérifier le blocage des commandes
- [ ] Valider les workflows d'approbation
2. **Tests d'Intégration**
- [ ] Tester avec les autres modules
- [ ] Vérifier la compatibilité avec les processus existants
## État de la Migration
🟡 En cours d'analyse - Utilisation partielle des fonctionnalités natives
## Notes Importantes
- La gestion du crédit est maintenant une fonctionnalité native d'Odoo
- Certaines fonctionnalités spécifiques devront être maintenues
- L'approche recommandée est d'utiliser au maximum les fonctionnalités natives et de ne conserver que les extensions nécessaires
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Créer les scripts de migration des données
3. Développer les fonctionnalités manquantes
4. Planifier la formation des utilisateurs

View file

@ -0,0 +1,87 @@
# Migration vers Odoo 18.0 - bemade_add_follower_no_sendmail_default
## Description du module
Ce module modifie le comportement par défaut du wizard d'ajout de followers pour que l'option "Envoyer un email" soit désactivée par défaut.
## Analyse technique
- Dépendances : mail
- Modèles modifiés :
- mail.wizard.invite : Modification de la valeur par défaut du champ send_mail à False
- Implémentation actuelle :
- Hérite de mail.wizard.invite
- Redéfinit uniquement le champ send_mail avec default=False
## Alternatives Natives
### Configuration Système
1. Vérifier dans Odoo 18.0 :
- Paramètres de configuration du module mail
- Paramètres système (ir.config_parameter)
- Préférences utilisateur
### Approches Alternatives
1. Configuration par utilisateur :
- Ajouter une préférence utilisateur dans res.users
- Utiliser cette préférence comme valeur par défaut
2. Configuration par type de document :
- Ajouter un paramètre dans les paramètres de notification par modèle
- Permettre une configuration plus granulaire
## Recommandations pour la Migration
### Approche "Vanilla First"
1. Évaluer les alternatives natives :
- [X] Vérifier si Odoo 18.0 a ajouté une configuration similaire
- [ ] Explorer les nouvelles fonctionnalités de notification
- [ ] Vérifier les paramètres de notification par défaut
2. Si aucune alternative native n'existe :
- [ ] Considérer l'ajout d'une configuration système
- [ ] Implémenter une solution plus flexible (par utilisateur ou par type de document)
### Modifications Techniques
1. Si le module est conservé :
- [ ] Mettre à jour la version dans __manifest__.py
- [ ] Vérifier la compatibilité de l'héritage du wizard
- [ ] Vérifier si le champ send_mail existe toujours et a le même comportement
- [ ] Adapter le code aux nouvelles conventions Odoo 18.0
2. Si migration vers une solution native :
- [ ] Créer un module de migration pour la transition
- [ ] Migrer les configurations existantes
- [ ] Prévoir un plan de désactivation du module
## Fonctionnalité Native dans Odoo 18.0
✅ La fonctionnalité existe nativement dans Odoo 18.0 !
Dans le modèle `mail.wizard.invite` (`mail/wizard/mail_wizard_invite.py`), le champ `notify` est déjà défini avec `default=False` :
```python
notify = fields.Boolean('Notify Recipients', default=False)
```
## Plan de Migration
### Actions Requises
1. **Désactivation du Module** :
- [ ] Désactiver le module avant la migration vers Odoo 18.0
- [ ] Vérifier qu'aucun autre module ne dépend de celui-ci
- [ ] Informer les utilisateurs que le comportement est maintenant natif
2. **Vérification** :
- [ ] Tester le comportement natif dans Odoo 18.0
- [ ] Confirmer que le comportement par défaut est identique
- [ ] Documenter tout changement d'interface utilisateur
## État de la Migration
🟢 Pas de migration nécessaire - Utiliser la fonctionnalité native
## Notes Importantes
- Le comportement souhaité (notification désactivée par défaut) est maintenant le comportement standard d'Odoo 18.0
- L'interface utilisateur est similaire, utilisant un widget boolean_toggle
- Aucune personnalisation supplémentaire n'est nécessaire
## Prochaines Étapes
1. Planifier la désactivation du module
2. Informer les utilisateurs du changement
3. Retirer le module de la liste des dépendances des autres modules si nécessaire

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_attachments_cleanup
## Description
Module de nettoyage des pièces jointes obsolètes
## Fonctionnalités Ajoutées
- Suppression automatique des pièces jointes non utilisées
- Configuration des règles de nettoyage
- Historique des suppressions
## Modèles et Champs Modifiés
- ir.attachment
- Ajout du champ cleanup_date (date)
- Ajout du champ cleanup_reason (text)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait être remplacé par une configuration native dans Odoo 18.0

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_fetchmail_only_production
## Description
Module restreignant la récupération des emails uniquement en environnement de production
## Fonctionnalités Ajoutées
- Désactivation de fetchmail dans les environnements de test et de développement
- Configuration par base de données
- Journalisation des tentatives de récupération
## Modèles et Champs Modifiés
- fetchmail.server
- Ajout du champ production_only (boolean)
- Ajout du champ last_attempt (datetime)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait être remplacé par une configuration native dans Odoo 18.0

369
bemade_fsm/migration18.md Normal file
View file

@ -0,0 +1,369 @@
# Improved Field Service Management - Migration vers Odoo 18.0
## Description
Ce module étend les fonctionnalités de gestion des services sur site (Field Service Management) avec des fonctionnalités spécifiques à Durpro.
## Fonctionnalités Ajoutées
### Gestion améliorée des services sur site
- **Existe dans Odoo 18.0 ?** : Partiellement
- **Différences avec la version native** :
- Gestion avancée des équipements et des contacts
- Système de modèles de tâches personnalisé
- Intégration approfondie avec les commandes de vente
- Gestion des visites FSM
- Propagation des affectations et des contacts
- **Alternatives** :
- Utiliser le module FSM standard d'Odoo
- Implémenter des fonctionnalités spécifiques via des modules personnalisés
## Modèles et Champs Modifiés
### Modèles impactés
- **project.task** :
- **Champs ajoutés** :
- work_order_contacts : Contacts liés au bon de travail
- site_contacts : Contacts sur site
- visit_id : Lien vers la visite FSM
- relevant_order_lines : Lignes de commande pertinentes
- work_order_number : Numéro de bon de travail
- propagate_assignment : Propagation des affectations
- is_closed : Indicateur de tâche fermée
- root_ancestor : Tâche racine de la hiérarchie
- **Méthodes modifiées** :
- create() : Gestion des contacts et numéros de bon de travail
- write() : Propagation des modifications aux sous-tâches
- _compute_allow_billable() : Calcul de la facturabilité
- _fsm_create_sale_order_line() : Création de lignes de commande
- action_fsm_validate() : Validation des tâches FSM
- synchronize_name_fsm() : Synchronisation des noms des tâches
- **Recommandations de migration** :
- Vérifier la compatibilité avec le nouveau système de tâches Odoo 18
- Tester la propagation des modifications
- Adapter les calculs de facturabilité
- Vérifier la gestion des noms des tâches
- **task.template** :
- **Nouveau modèle** : project.task.template
- **Champs principaux** :
- name : Nom du modèle
- description : Description HTML
- assignees : Utilisateurs assignés par défaut
- customer : Client par défaut
- project : Projet par défaut
- tags : Tags par défaut
- parent : Modèle parent
- subtasks : Sous-tâches
- sequence : Ordre d'affichage
- company_id : Société
- planned_hours : Heures planifiées
- equipment_ids : Équipements à entretenir
- **Méthodes principales** :
- _prepare_new_task_values_from_self() : Prépare les valeurs pour une nouvelle tâche
- create_task_from_self() : Crée une tâche à partir du modèle
- **Recommandations de migration** :
- Vérifier la compatibilité avec le nouveau système de modèles de tâches Odoo 18
- Tester la création de tâches à partir des modèles
- Adapter la gestion des équipements et des heures planifiées
- **product.template** :
- **Champs ajoutés** :
- task_template_id : Modèle de tâche associé
- is_field_service : Indicateur de service sur site
- **Recommandations de migration** :
- Vérifier la compatibilité avec le nouveau système de produits Odoo 18
- Tester la gestion des modèles de tâches
- Adapter l'indicateur de service sur site
- **res.partner** :
- **Champs ajoutés** :
- is_site_contact : Indicateur de contact sur site
- is_service_site : Indicateur de site de service
- site_ids : Sites de travail liés
- site_contacts : Contacts sur site
- work_order_contacts : Destinataires des bons de travail
- **Méthodes modifiées** :
- _compute_is_site_contact() : Calcul de l'état de contact sur site
- _search_is_site_contact() : Recherche des contacts sur site
- _compute_is_service_site() : Calcul de l'état de site de service
- **Recommandations de migration** :
- Vérifier la compatibilité avec le nouveau système de partenaires Odoo 18
- Tester les calculs des indicateurs
- Adapter la gestion des relations entre sites et contacts
- **sale.order** :
- **Champs ajoutés** :
- valid_equipment_ids : Équipements valides
- default_equipment_ids : Équipements par défaut à entretenir
- summary_equipment_ids : Équipements en cours de maintenance
- site_contacts : Contacts sur site
- work_order_contacts : Destinataires du bon de travail
- visit_ids : Visites FSM liées
- is_fsm : Indicateur de commande FSM
- **Méthodes modifiées** :
- get_relevant_order_lines() : Récupère les lignes pertinentes pour une tâche
- _compute_summary_equipment_ids() : Calcule les équipements en maintenance
- _onchange_partner_shipping_id() : Gère les changements de partenaire
- _compute_default_contacts() : Calcule les contacts par défaut
- _compute_default_equipment() : Calcule les équipements par défaut
- copy() : Gère la copie des visites
- _create_default_visit() : Crée une visite par défaut
- _create_or_organize_visits_if_needed() : Organise les visites FSM
- action_confirm() : Confirmation de commande avec gestion FSM
- write() : Gère les mises à jour des partenaires
- **Recommandations de migration** :
- Vérifier la compatibilité avec le nouveau système de commandes Odoo 18
- Tester la gestion des équipements
- Adapter la gestion des visites FSM
- Vérifier les calculs de contacts et d'équipements
## Vues à modifier
- **Vues existantes** :
- Formulaire de tâche :
- Ajout d'une page "Equipment and Contacts"
- Modification des boutons de validation
- Ajout du champ propagate_assignment
- Vue liste :
- Ajout du champ work_order_number
- Masquage de certains champs optionnels
- Vue calendrier :
- Personnalisation des couleurs par utilisateur
- Suppression du champ worksheet_template_id
- Vue de recherche :
- Modification des filtres de planification
- Ajout du filtre "Parent Task"
- **Nouvelles vues** :
- Aucune nouvelle vue créée, uniquement des modifications des vues existantes
- **Recommandations pour Odoo 18** :
- Vérifier la compatibilité avec les nouvelles vues Odoo 18
- Adapter les modifications de vues aux nouveaux designs
- Tester les fonctionnalités de recherche et de filtrage
- Vérifier la gestion des couleurs dans le calendrier
## Rapports
- **Rapports personnalisés** :
- **Nouveaux blocs de rapport** :
- Tableau des matériaux
- Tableau des temps et matériaux avec tarification
- Liste des sous-tâches
- Bloc d'informations sur la commande
- Résumé des équipements
- Entrées de feuille de temps
- Bloc de signature
- **Modifications principales** :
- Intégration des contacts et informations client
- Affichage des dates planifiées
- Gestion des signatures numériques
- Personnalisation de la mise en page
- **Recommandations pour Odoo 18** :
- Vérifier la compatibilité avec le nouveau système de rapports Odoo 18
- Adapter les modèles de rapport aux nouvelles fonctionnalités
- Tester l'affichage des différents blocs
- Vérifier la gestion des signatures numériques
## Assistants (Wizards)
- **Nouveaux assistants** : À documenter
## Analyse des Alternatives Natives Odoo 18.0
### Fonctionnalités Natives à Explorer
1. **Gestion des Services** :
- Module Industry FSM d'Odoo Enterprise
- Nouvelles fonctionnalités de planification
- Système de rapports amélioré
2. **Gestion des Équipements** :
- Module Maintenance d'Odoo
- Intégration avec FSM
- Système de suivi des équipements
3. **Gestion des Contacts** :
- Système de contacts hiérarchiques
- Gestion des rôles des contacts
- Système d'adresses de livraison
### Approche "Vanilla First"
1. **Fonctionnalités à Conserver en Custom** :
- Gestion spécifique des visites FSM
- Propagation des affectations
- Modèles de tâches personnalisés
- Gestion avancée des contacts sur site
2. **Fonctionnalités à Migrer vers Native** :
- Utiliser le système de planification natif
- Adopter le système de rapports standard
- Utiliser la gestion des équipements native
- Intégrer avec le système de contacts standard
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Audit des Fonctionnalités** :
- [ ] Identifier les fonctionnalités disponibles nativement
- [ ] Lister les gaps fonctionnels
- [ ] Évaluer l'impact sur les processus existants
2. **Planification** :
- [ ] Définir la stratégie de migration
- [ ] Établir un calendrier
- [ ] Identifier les risques
### Phase 2 : Migration Technique
1. **Adaptation du Code** :
- [ ] Mettre à jour les vues (tree -> list)
- [ ] Supprimer les attrs obsolètes
- [ ] Adapter les méthodes aux nouvelles API
2. **Intégration Native** :
- [ ] Intégrer avec Industry FSM
- [ ] Connecter avec le module Maintenance
- [ ] Adapter le système de contacts
### Phase 3 : Tests et Validation
1. **Tests Fonctionnels** :
- [ ] Validation des workflows
- [ ] Tests des rapports
- [ ] Vérification des intégrations
2. **Tests de Performance** :
- [ ] Analyse des requêtes SQL
- [ ] Tests de charge
- [ ] Optimisation si nécessaire
## Recommandations Spécifiques
### Modèles et Champs
1. **project.task** :
- Utiliser les champs natifs quand possible
- Conserver uniquement les champs spécifiques
- Adapter les méthodes aux nouvelles API
2. **task.template** :
- Évaluer le système de modèles natif
- Simplifier la structure si possible
- Optimiser la création de tâches
3. **sale.order** :
- Utiliser les fonctionnalités FSM natives
- Optimiser la gestion des visites
- Simplifier les calculs
### Vues et Interface
1. **Modifications Prioritaires** :
- Remplacer tree par list
- Supprimer les attrs obsolètes
- Adapter aux nouveaux standards UI
2. **Améliorations Suggérées** :
- Utiliser les nouveaux widgets
- Simplifier les vues
- Améliorer l'expérience utilisateur
### Rapports
1. **Stratégie de Migration** :
- Utiliser le nouveau système de rapports
- Adapter les modèles existants
- Optimiser le rendu
## État de la Migration
⚪ En analyse préliminaire
## Notes Importantes
- Module complexe nécessitant une approche progressive
- Forte dépendance avec d'autres modules
- Impact important sur les processus métier
- Nécessité de formation des utilisateurs
## Prochaines Étapes
1. Valider l'approche avec les parties prenantes
2. Créer un environnement de test
3. Commencer par les fonctionnalités critiques
4. Planifier la formation des utilisateurs
## Analyse Technique
### Fonctionnalités Natives dans Odoo 18.0
Le module `industry_fsm` d'Odoo Enterprise 18.0 inclut déjà plusieurs fonctionnalités avancées :
1. **Gestion des Tâches FSM**
- Champ `is_fsm` sur les projets pour identifier les projets FSM
- Champ `fsm_done` sur les tâches pour marquer leur complétion
- Gestion des signatures sur les rapports de travail
- Gestion des coordonnées client (téléphone, adresse, etc.)
- Planification avec dates de début/fin
2. **Fonctionnalités de Base**
- Vue spécifique pour les travailleurs sur le terrain
- Rapports sur les tâches
- Intégration avec les feuilles de temps
- Géolocalisation des clients
- Gestion des produits sur les tâches
3. **Sécurité et Contraintes**
- Règles de sécurité spécifiques FSM
- Contraintes sur les projets FSM (company_id requis)
- Restrictions sur les dépendances de tâches et les jalons
### Différences avec Notre Module
1. **Fonctionnalités à Migrer**
- [ ] Fonctionnalités spécifiques de gestion d'équipement
- [ ] Workflows personnalisés
- [ ] Rapports et analyses spécifiques
- [ ] Intégrations avec d'autres modules custom
2. **Fonctionnalités à Adapter**
- [ ] Utiliser les champs natifs plutôt que nos champs customs
- [ ] Adapter nos vues aux nouvelles conventions Odoo 18.0
- [ ] Intégrer nos processus avec le système natif
## Plan de Migration
### Phase 1 : Préparation
1. **Analyse des Données**
- [ ] Identifier les données spécifiques à notre module
- [ ] Mapper les champs actuels vers les champs natifs
- [ ] Lister les fonctionnalités uniques à préserver
2. **Configuration**
- [ ] Activer et configurer le module `industry_fsm`
- [ ] Vérifier les dépendances et les conflits
- [ ] Préparer les scripts de migration des données
### Phase 2 : Migration
1. **Migration des Données**
- [ ] Transférer les données vers les structures natives
- [ ] Adapter les configurations existantes
- [ ] Mettre à jour les vues et rapports
2. **Développement**
- [ ] Adapter le code pour utiliser l'API Odoo 18.0
- [ ] Implémenter les fonctionnalités manquantes
- [ ] Mettre à jour les vues XML (plus d'attrs, list au lieu de tree)
### Phase 3 : Tests
1. **Validation Fonctionnelle**
- [ ] Tester les fonctionnalités de base FSM
- [ ] Vérifier nos fonctionnalités spécifiques
- [ ] Valider les workflows
2. **Tests d'Intégration**
- [ ] Tester avec les autres modules
- [ ] Vérifier la compatibilité mobile
- [ ] Valider les performances
## État de la Migration
🟡 En cours d'analyse - Utilisation maximale des fonctionnalités natives
## Notes Importantes
- Le module `industry_fsm` d'Odoo Enterprise offre une base solide
- Plusieurs de nos fonctionnalités peuvent être remplacées par des fonctionnalités natives
- Certaines personnalisations spécifiques devront être maintenues
- La nouvelle interface utilisateur nécessitera une formation des utilisateurs
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Créer les scripts de migration des données
3. Développer les fonctionnalités manquantes
4. Planifier la formation des utilisateurs
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025

View file

@ -0,0 +1,64 @@
# Migration vers Odoo 18.0 - bemade_full_formview_from_modal
## Description
Module qui ajoute un bouton pour ouvrir la vue formulaire complète depuis une vue modale (dialog).
## Analyse Technique
### Fonctionnalité Native dans Odoo 18.0
✅ La fonctionnalité existe nativement dans Odoo 18.0 !
Le composant `FormViewDialog` dans `web/static/src/views/view_dialogs/form_view_dialog.js` inclut déjà la méthode `onExpand()` qui fournit exactement la même fonctionnalité :
```javascript
async onExpand() {
const beforeLeaveCallbacks = this.viewProps.__beforeLeave__.callbacks;
const res = await Promise.all(beforeLeaveCallbacks.map((callback) => callback()));
if (!res.includes(false)) {
this.actionService.doAction({
type: "ir.actions.act_window",
res_model: this.props.resModel,
res_id: this.currentResId,
views: [[false, "form"]],
});
}
}
```
Cette méthode :
- Gère les callbacks avant de quitter la vue
- Utilise le même service d'action
- Préserve le contexte et l'ID de l'enregistrement
- Ouvre la vue en mode plein écran
### Recommandation
Ce module n'est plus nécessaire dans Odoo 18.0 car la fonctionnalité est maintenant disponible nativement.
## Plan de Migration
### Actions Requises
1. **Désactivation du Module** :
- [ ] Désactiver le module avant la migration vers Odoo 18.0
- [ ] Vérifier qu'aucun autre module ne dépend de celui-ci
- [ ] Informer les utilisateurs que la fonctionnalité est maintenant native
2. **Vérification** :
- [ ] Tester la fonctionnalité native dans Odoo 18.0
- [ ] Confirmer que tous les cas d'utilisation sont couverts
- [ ] Documenter tout comportement différent pour les utilisateurs
## État de la Migration
🟢 Pas de migration nécessaire - Utiliser la fonctionnalité native
## Notes Importantes
- La fonctionnalité est maintenant intégrée nativement dans Odoo 18.0
- Le comportement natif est identique à notre implémentation custom
- Aucune personnalisation supplémentaire n'est nécessaire
## Prochaines Étapes
1. Planifier la désactivation du module
2. Documenter le changement pour les utilisateurs
3. Retirer le module de la liste des dépendances des autres modules si nécessaire
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_helpdesk_mailcow_blacklist
## Description
Module d'intégration entre Helpdesk et Mailcow pour la gestion des blacklists
## Fonctionnalités Ajoutées
- Synchronisation des emails blacklistés avec Mailcow
- Gestion des règles de blocage
- Historique des actions de blacklist
## Modèles et Champs Modifiés
- helpdesk.ticket
- Ajout du champ mailcow_blacklisted (boolean)
- Ajout du champ mailcow_blacklist_reason (text)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module nécessite une configuration spécifique de Mailcow

View file

@ -0,0 +1,72 @@
# Migration vers Odoo 18.0 - bemade_helpdesk_one_ticket_per_email
## Description
Module qui restreint la création de tickets à un seul ticket par email reçu.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Extension du Routage des Messages**
- Hérite de `mail.thread`
- Surcharge de `_message_route_process`
- Filtre les routes pour ne garder qu'une seule route helpdesk
2. **Comportement**
- Détecte les routes liées au helpdesk (`helpdesk.ticket`, `helpdesk.team`)
- Ne conserve que la première route helpdesk trouvée
- Journalise les modifications de routage
### Changements dans Odoo 18.0
1. **Architecture Mail**
- Le système de routage des emails reste similaire
- La méthode `_message_route_process` existe toujours
- Les modèles `helpdesk.ticket` et `helpdesk.team` sont inchangés
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité de la surcharge
- [ ] Adapter le code pour la gestion des erreurs
- [ ] Mettre à jour les dépendances
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans `mail.thread`
- [ ] Tester le comportement natif du routage
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test pour les scénarios multiples
- [ ] Documenter le comportement attendu
- [ ] Préparer des emails de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter la surcharge de `_message_route_process`
- [ ] Mettre à jour la gestion des erreurs
- [ ] Vérifier la journalisation
2. **Tests et Validation**
- [ ] Tester avec des emails simples
- [ ] Tester avec des emails multiples
- [ ] Vérifier la création unique des tickets
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Le système de routage des emails est stable
- La logique de base reste la même
- Les tests seront cruciaux pour valider le comportement
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter le code pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents scénarios d'emails
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025

View file

@ -0,0 +1,72 @@
# Migration vers Odoo 18.0 - bemade_hide_decimal_on_unit
## Description
Module qui cache les décimales sur les quantités lorsqu'elles sont entières dans les rapports de vente et d'achat.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Modification des Rapports**
- Rapport de vente (`sale.report_saleorder_document`)
- Rapport de devis d'achat (`purchase.report_purchasequotation_document`)
- Rapport de commande d'achat (`purchase.report_purchaseorder_document`)
2. **Comportement**
- Vérifie si la quantité est entière (`int(qty) == qty`)
- Affiche sans décimale si entière (`'%.0f' % qty`)
- Affiche avec décimales si non entière
### Changements dans Odoo 18.0
1. **Architecture des Rapports**
- Les templates QWeb sont toujours utilisés
- Les classes CSS `text-right` sont maintenant `text-end`
- Les identifiants des rapports restent les mêmes
2. **Modifications Nécessaires**
- [ ] Mettre à jour les classes CSS
- [ ] Vérifier la compatibilité des expressions XPath
- [ ] Valider les héritages de templates
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les templates de base dans Odoo 18.0
- [ ] Identifier les changements dans les classes CSS
- [ ] Tester les expressions XPath
2. **Tests**
- [ ] Créer des cas de test avec différentes quantités
- [ ] Documenter le comportement attendu
- [ ] Préparer des exemples de rapports
### Phase 2 : Migration
1. **Mise à Jour des Vues**
- [ ] Adapter les classes CSS (`text-right` → `text-end`)
- [ ] Mettre à jour les expressions XPath si nécessaire
- [ ] Vérifier les groupes de sécurité
2. **Tests et Validation**
- [ ] Tester avec des quantités entières
- [ ] Tester avec des quantités décimales
- [ ] Vérifier l'affichage sur différents formats de rapport
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont principalement cosmétiques (CSS)
- La logique de base reste la même
- Les tests visuels seront importants
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents formats de rapport
## Notes de Version
- Version originale: 17.0.0.1.1
- Dernière analyse: 26/01/2025

View file

@ -0,0 +1,95 @@
# Migration vers Odoo 18.0 - bemade_mailcow_integration
## Description
Module d'intégration entre Mailcow et Odoo pour la gestion des boîtes aux lettres et des alias email.
## Analyse Technique
### Fonctionnalités Actuelles
1. **API Mailcow**
- Gestion des connexions API avec Mailcow
- Authentification via clé API
- Gestion des requêtes HTTP (GET, POST, DELETE, PUT)
2. **Modèles**
- `mail.mailcow` : Modèle abstrait pour l'API
- `mail.mailcow.mailbox` : Gestion des boîtes aux lettres
- `mail.mailcow.alias` : Gestion des alias
- `mail.mailcow.blacklist` : Gestion de la liste noire
- Extension de `res.users` pour la synchronisation
3. **Configuration**
- Paramètres système pour l'URL et la clé API
- Options de création automatique
- Interface de configuration dans les paramètres
### Changements dans Odoo 18.0
1. **Architecture Mail**
- Le système de mail reste similaire
- Les alias sont toujours gérés via `mail.alias`
- Les utilisateurs sont liés aux boîtes mail
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité des API HTTP
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Mettre à jour les dépendances
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans l'API Mailcow
- [ ] Tester la compatibilité des requêtes HTTP
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test pour l'API
- [ ] Documenter le comportement attendu
- [ ] Préparer des scénarios de synchronisation
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les appels API si nécessaire
- [ ] Mettre à jour les vues XML
- [ ] Vérifier les dépendances (`bemade_user_password_bundle`)
2. **Tests et Validation**
- [ ] Tester la création de boîtes aux lettres
- [ ] Tester la synchronisation des alias
- [ ] Vérifier la gestion de la liste noire
## État de la Migration
En cours d'analyse - Migration modérée requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- L'intégration avec Mailcow est stable
- Les tests de connexion seront cruciaux
- Dépendance avec `bemade_user_password_bundle`
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements dans l'API Mailcow
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.1.0.1
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Sécurité**
- Gestion sécurisée des clés API
- Protection des données sensibles
- Validation des entrées utilisateur
2. **Performance**
- Optimisation des appels API
- Gestion du cache
- Traitement asynchrone si possible
3. **Maintenance**
- Documentation des endpoints API
- Gestion des erreurs améliorée
- Logs détaillés pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_margin_vendor_pricelist
## Description
Module qui permet le calcul des marges de vente basées sur les listes de prix des fournisseurs, avec prise en compte du stock disponible.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Calcul des Marges**
- Calcul du prix d'achat basé sur les listes de prix fournisseurs
- Calcul du profit brut et du pourcentage de profit
- Prise en compte du stock disponible
2. **Modèles Modifiés**
- `sale.order` : Ajout des champs de marge
- `sale.order.line` : Calcul détaillé des marges
- Hérite de `sale_stock_margin`
3. **Logique de Calcul**
- Utilise la valorisation du stock si disponible
- Utilise le prix fournisseur si stock manquant
- Calcul mixte pour les commandes partiellement en stock
### Changements dans Odoo 18.0
1. **Architecture des Marges**
- Le module `sale_margin` reste stable
- `sale_stock_margin` conserve sa structure
- Les champs de marge sont toujours présents
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec `sale_stock_margin`
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Optimiser les calculs pour la performance
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans `sale_margin`
- [ ] Tester les calculs de marge
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les méthodes de calcul si nécessaire
- [ ] Mettre à jour les vues XML
- [ ] Optimiser les calculs non stockés
2. **Tests et Validation**
- [ ] Tester avec stock disponible
- [ ] Tester sans stock disponible
- [ ] Vérifier les calculs mixtes
## État de la Migration
En cours d'analyse - Migration modérée requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les calculs de marge sont complexes
- La performance est un point d'attention
- Dépendance avec `sale_stock_margin`
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements dans les modules dépendants
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.0.0.5
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimiser les calculs non stockés
- Évaluer l'impact sur les vues pivot/graph
- Considérer le stockage de certains champs
2. **Précision**
- Maintenir la précision des calculs
- Gérer correctement les arrondis
- Valider les conversions d'unités
3. **Compatibilité**
- Vérifier la compatibilité avec d'autres modules de marge
- Tester avec différentes configurations de stock
- Valider les scénarios multi-devise

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_module_linker
## Description
Module de gestion des liens entre modules
## Fonctionnalités Ajoutées
- Création de liens entre modules
- Visualisation des dépendances
- Gestion des conflits
## Modèles et Champs Modifiés
- ir.module.module
- Ajout du champ linked_modules (many2many)
- Ajout du champ dependency_graph (text)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait nécessiter des adaptations pour Odoo 18.0

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_packing_wizard
## Description
Module qui permet la création automatique des types de colis basée sur les dimensions entrées lors de l'emballage.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Assistant d'Emballage**
- Extension de `choose.delivery.package`
- Ajout des champs de dimensions (longueur, largeur, hauteur)
- Création automatique des types de colis
2. **Modèles Modifiés**
- `choose.delivery.package` : Extension du wizard
- `delivery.carrier` : Configuration auto-création
- `stock.package.type` : Gestion des types de colis
3. **Logique de Création**
- Vérifie l'existence du type de colis
- Crée automatiquement si non existant
- Standardise les dimensions (longueur > largeur)
### Changements dans Odoo 18.0
1. **Architecture Stock/Delivery**
- Le module `stock_delivery` reste stable
- Les types de colis sont toujours gérés
- L'assistant d'emballage existe toujours
2. **Modifications Nécessaires**
- [ ] Mettre à jour les vues pour les nouvelles conventions
- [ ] Vérifier la compatibilité avec `stock_delivery`
- [ ] Adapter les attributs des vues XML
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans `stock_delivery`
- [ ] Tester la création automatique
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différentes dimensions
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Remplacer `invisible` par `column_invisible` où nécessaire
- [ ] Mettre à jour les vues XML
- [ ] Vérifier les attributs des champs
2. **Tests et Validation**
- [ ] Tester la création automatique
- [ ] Vérifier l'affichage des champs
- [ ] Valider les calculs de dimensions
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont principalement dans les vues
- La logique de base reste la même
- Dépendance avec `stock_delivery`
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents transporteurs
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Compatibilité**
- Vérifier les transporteurs supportés
- Tester avec différents types de colis
- Valider les conversions d'unités
2. **Interface Utilisateur**
- Améliorer la visibilité des champs
- Clarifier les messages d'erreur
- Faciliter la saisie des dimensions
3. **Maintenance**
- Documentation des types de colis créés
- Gestion des doublons potentiels
- Nettoyage périodique des types inutilisés

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_partner_email_domain
## Description
Module qui automatise l'association des partenaires avec leurs sociétés respectives en se basant sur les domaines d'emails.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Association Automatique**
- Extraction du domaine email
- Recherche des sociétés correspondantes
- Association automatique ou envoi d'email de sélection
2. **Modèles Modifiés**
- `res.partner` : Ajout des champs et logique
- Contrôleur HTTP pour la sélection
- Templates d'email pour la sélection
3. **Logique d'Association**
- Vérification à la création et modification
- Gestion des cas multiples
- Génération de tokens d'accès
### Changements dans Odoo 18.0
1. **Architecture Base/Mail**
- Le système de mail reste similaire
- Les partenaires et sociétés sont inchangés
- Le routage HTTP est stable
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec le nouveau système de mail
- [ ] Adapter les templates pour les nouvelles conventions
- [ ] Mettre à jour les contrôleurs HTTP
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans le système de mail
- [ ] Tester les tokens d'accès
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents domaines
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les templates d'email
- [ ] Mettre à jour les vues XML
- [ ] Vérifier la sécurité des tokens
2. **Tests et Validation**
- [ ] Tester l'association automatique
- [ ] Vérifier les emails de sélection
- [ ] Valider la sécurité des tokens
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention particulière à la sécurité
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements dans le système de mail
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.0.0.1
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Sécurité**
- Validation des tokens d'accès
- Protection contre les attaques par force brute
- Gestion des sessions
2. **Performance**
- Optimisation des requêtes SQL
- Gestion du cache
- Traitement asynchrone des emails
3. **Maintenance**
- Documentation des cas spéciaux
- Gestion des erreurs améliorée
- Logs détaillés pour le débogage

View file

@ -0,0 +1,92 @@
# Migration vers Odoo 18.0 - bemade_partner_root_ancestor
## Description
Module technique qui ajoute le champ `root_ancestor` à `res.partner` pour identifier l'ancêtre racine d'un partenaire dans la hiérarchie.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Champ Root Ancestor**
- Type: Many2one vers res.partner
- Calculé et stocké
- Récursif pour la hiérarchie complète
2. **Modèles Modifiés**
- `res.partner` : Ajout du champ et logique
- Utilisation de la récursivité native d'Odoo
3. **Logique de Calcul**
- Dépend de parent_id
- Calcul récursif via parent_id.root_ancestor
- Stockage pour optimisation
### Changements dans Odoo 18.0
1. **Architecture Base**
- Le modèle res.partner reste stable
- La récursivité est toujours supportée
- Les champs calculés fonctionnent de la même manière
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec les nouveaux champs calculés
- [ ] Valider le comportement récursif
- [ ] Optimiser le stockage si nécessaire
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans res.partner
- [ ] Tester la récursivité
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec hiérarchies complexes
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les dépendances si nécessaire
- [ ] Optimiser le calcul récursif
- [ ] Vérifier les index de base de données
2. **Tests et Validation**
- [ ] Tester avec différentes hiérarchies
- [ ] Vérifier la performance
- [ ] Valider le stockage
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Module technique sans interface utilisateur
- La logique de base reste la même
- Attention à la performance
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les optimisations possibles
3. Mettre à jour les tests
4. Tester avec de grandes hiérarchies
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation du calcul récursif
- Gestion du cache
- Index de base de données
2. **Fiabilité**
- Gestion des boucles infinies
- Traitement des erreurs
- Validation des données
3. **Maintenance**
- Documentation du comportement récursif
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,92 @@
# Migration vers Odoo 18.0 - bemade_picking_upstream
## Description
Module qui permet de visualiser les transferts en amont dont dépend un transfert pour la disponibilité du stock.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Champs Calculés**
- `upstream_picking_ids` : One2many vers stock.picking
- `upstream_picking_count` : Integer
- Calcul basé sur move_orig_ids
2. **Modèles Modifiés**
- `stock.picking` : Ajout des champs et logique
- Vue formulaire modifiée pour afficher le bouton
3. **Interface Utilisateur**
- Bouton statistique dans la vue formulaire
- Action pour voir les transferts en amont
- Affichage conditionnel basé sur le compteur
### Changements dans Odoo 18.0
1. **Architecture Stock**
- Le modèle stock.picking reste stable
- Les mouvements de stock fonctionnent de la même manière
- Les champs calculés sont toujours supportés
2. **Modifications Nécessaires**
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Vérifier la compatibilité des champs calculés
- [ ] Mettre à jour les attributs des vues
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans stock.picking
- [ ] Tester les champs calculés
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les vues XML
- [ ] Vérifier les dépendances
- [ ] Optimiser les calculs si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types de transferts
- [ ] Vérifier l'affichage du bouton
- [ ] Valider les calculs
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la performance des calculs
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation des champs calculés
- Gestion du cache
- Impact sur les grands volumes
2. **Interface Utilisateur**
- Visibilité du bouton statistique
- Clarté des informations
- Navigation intuitive
3. **Maintenance**
- Documentation des dépendances
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_purchase_warn_supplier_overdue
## Description
Module qui ajoute des avertissements lors de la confirmation des bons de commande pour les fournisseurs ayant des factures en retard.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Avertissements Automatiques**
- Vérification des factures en retard
- Création d'activités mail.activity
- Configuration par entreprise
2. **Modèles Modifiés**
- `purchase.order` : Ajout de la logique d'avertissement
- `res.company` : Configuration des avertissements
- `res.config.settings` : Interface de configuration
3. **Configuration Flexible**
- Choix des utilisateurs à notifier
- Sélection des fournisseurs concernés
- Paramètres par entreprise
### Changements dans Odoo 18.0
1. **Architecture Purchase/Mail**
- Le système d'activités reste stable
- Les bons de commande fonctionnent de la même manière
- Les paramètres de configuration sont similaires
2. **Modifications Nécessaires**
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Vérifier la compatibilité des activités
- [ ] Mettre à jour les attributs des vues
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans mail.activity
- [ ] Tester la création d'activités
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les vues XML
- [ ] Vérifier les dépendances
- [ ] Optimiser les requêtes si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types de factures
- [ ] Vérifier les notifications
- [ ] Valider les configurations
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la performance des requêtes
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.1.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation des requêtes de factures
- Gestion du cache
- Impact sur les grands volumes
2. **Interface Utilisateur**
- Clarté des avertissements
- Configuration intuitive
- Visibilité des notifications
3. **Maintenance**
- Documentation des configurations
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_pwa_config
## Description
Module qui permet la configuration des paramètres PWA (Progressive Web App) directement depuis l'interface Odoo, incluant la gestion dynamique des icônes d'application.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Configuration PWA**
- Gestion des icônes d'application
- Configuration des couleurs
- Génération dynamique des icônes
2. **Modèles Modifiés**
- `res.company` : Stockage des configurations
- `res.config.settings` : Interface de configuration
- Contrôleur pour le manifest.webmanifest
3. **Fonctionnalités Avancées**
- Redimensionnement automatique des icônes
- Manifest dynamique par entreprise
- Gestion des couleurs de thème
### Changements dans Odoo 18.0
1. **Architecture Web**
- Le système PWA est toujours supporté
- Les routes HTTP restent stables
- La gestion des images est similaire
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec le nouveau framework web
- [ ] Adapter les routes HTTP si nécessaire
- [ ] Mettre à jour les dépendances PIL
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans le framework web
- [ ] Tester le traitement des images
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test pour les icônes
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les vues XML
- [ ] Vérifier les dépendances Python
- [ ] Optimiser le traitement des images
2. **Tests et Validation**
- [ ] Tester avec différentes tailles d'icônes
- [ ] Vérifier le manifest généré
- [ ] Valider sur différents navigateurs
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la performance du traitement d'images
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements du framework web
3. Mettre à jour les tests
4. Tester sur différents navigateurs
## Notes de Version
- Version originale: 18.0.0.1.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation du traitement d'images
- Mise en cache du manifest
- Gestion des ressources
2. **Compatibilité**
- Support des navigateurs
- Versions de PIL/Pillow
- Standards PWA
3. **Maintenance**
- Documentation des configurations
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_quotation_alternative
## Description
Module qui permet de créer des devis alternatifs à partir d'un devis existant, avec la possibilité de sélectionner les lignes à dupliquer.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Assistant de Duplication**
- Duplication sélective des lignes
- Copie des notes et objectifs
- Gestion des liens entre devis
2. **Modèles Modifiés**
- `sale.order` : Ajout de l'action de duplication
- Assistant de duplication transient
- Gestion des messages dans le chatter
3. **Interface Utilisateur**
- Assistant de sélection des lignes
- Notification dans le chatter
- Liens entre devis original et copie
### Changements dans Odoo 18.0
1. **Architecture Sale**
- Le modèle sale.order reste stable
- Le système de chatter est similaire
- Les assistants transients fonctionnent de la même manière
2. **Modifications Nécessaires**
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Vérifier la compatibilité du chatter
- [ ] Mettre à jour les attributs des vues
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans sale.order
- [ ] Tester la duplication
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les vues XML
- [ ] Vérifier les dépendances
- [ ] Optimiser la duplication si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types de devis
- [ ] Vérifier les messages du chatter
- [ ] Valider les liens entre devis
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la gestion des messages
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation de la duplication
- Gestion des grands devis
- Impact sur la base de données
2. **Interface Utilisateur**
- Clarté de l'assistant
- Navigation intuitive
- Messages informatifs
3. **Maintenance**
- Documentation des cas spéciaux
- Gestion des erreurs
- Logs pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_reordering_rules_chatter
## Description
Module qui ajoute un chatter sur les règles de réapprovisionnement pour suivre les modifications et permettre la communication.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Héritage Mixins**
- `mail.thread`
- `mail.activity.mixin`
- Ajout au modèle stock.warehouse.orderpoint
2. **Champs Trackés**
- Tous les champs importants sont trackés
- Historique des modifications
- Support des activités
3. **Interface Utilisateur**
- Chatter dans la vue formulaire
- Suivi des modifications
- Gestion des activités
### Changements dans Odoo 18.0
1. **Architecture Stock/Mail**
- Le système de chatter reste stable
- Les mixins mail sont toujours disponibles
- Le tracking des champs fonctionne de la même manière
2. **Modifications Nécessaires**
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Vérifier la compatibilité des mixins
- [ ] Mettre à jour les attributs des vues
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans les mixins mail
- [ ] Tester le tracking des champs
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test pour le chatter
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les vues XML
- [ ] Vérifier les dépendances
- [ ] Optimiser le tracking si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différentes règles
- [ ] Vérifier l'historique des modifications
- [ ] Valider les activités
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la performance du tracking
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.0.0.1
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Impact du tracking sur les performances
- Gestion de l'historique
- Optimisation des notifications
2. **Interface Utilisateur**
- Visibilité du chatter
- Clarté des modifications
- Facilité d'utilisation
3. **Maintenance**
- Documentation des champs trackés
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_search_supplier_code
## Description
Module de recherche par code fournisseur
## Fonctionnalités Ajoutées
- Recherche avancée par code fournisseur
- Filtrage des résultats
- Historique des recherches
## Modèles et Champs Modifiés
- product.product
- Ajout du champ supplier_code_search (char)
- Ajout du champ last_search_date (datetime)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait nécessiter des adaptations pour Odoo 18.0

View file

@ -0,0 +1,32 @@
# Migration vers Odoo 18.0 - bemade_so_and_po_only_company
## Description
Module de restriction des commandes clients et fournisseurs à la société actuelle
## Fonctionnalités Ajoutées
- Restriction des commandes à la société actuelle
- Gestion des exceptions
- Historique des modifications
## Modèles et Champs Modifiés
- sale.order
- Ajout du champ restrict_to_company (boolean)
- purchase.order
- Ajout du champ restrict_to_company (boolean)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait nécessiter des adaptations pour Odoo 18.0

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_so_followers_to_picking
## Description
Module qui ajoute automatiquement les abonnés d'une commande de vente aux transferts de stock associés.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Abonnement Automatique**
- Copie des abonnés lors de la création
- Basé sur le champ origin
- Gestion des abonnements via message_subscribe
2. **Modèles Modifiés**
- `stock.picking` : Surcharge de create
- Utilisation de l'API de messagerie
- Lien avec les commandes de vente
3. **Logique Simple**
- Recherche de la commande source
- Copie des abonnés
- Pas d'interface utilisateur
### Changements dans Odoo 18.0
1. **Architecture Stock/Mail**
- Le système d'abonnement reste stable
- Les liens SO-Picking sont inchangés
- L'API de messagerie est similaire
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec le nouveau système de messagerie
- [ ] Valider la méthode de création des transferts
- [ ] Optimiser la recherche des commandes
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans l'API de messagerie
- [ ] Tester les abonnements
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter le code Python
- [ ] Vérifier les dépendances
- [ ] Optimiser les requêtes si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types de commandes
- [ ] Vérifier les abonnements
- [ ] Valider les notifications
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la performance des requêtes
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements dans l'API de messagerie
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.0.0.1
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation des recherches
- Gestion des abonnements en masse
- Impact sur les grands volumes
2. **Fiabilité**
- Gestion des erreurs
- Validation des abonnements
- Cohérence des données
3. **Maintenance**
- Documentation du comportement
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_stock_quant_valuation
## Description
Module qui ajoute la valorisation aux quants de stock pour une meilleure gestion des ajustements d'inventaire.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Champs de Valorisation**
- `value_unit` : Prix standard du produit
- `value_difference` : Valeur de la différence d'inventaire
- Calcul automatique des différences
2. **Modèles Modifiés**
- `stock.quant` : Ajout des champs de valorisation
- Héritage des vues d'inventaire
- Gestion des droits d'accès
3. **Interface Utilisateur**
- Affichage des valeurs dans la vue d'inventaire
- Champs optionnels dans la vue liste
- Groupes de sécurité stock.group_stock_manager
### Changements dans Odoo 18.0
1. **Architecture Stock/Account**
- Le modèle stock.quant reste stable
- La valorisation du stock est similaire
- Les droits d'accès sont inchangés
2. **Modifications Nécessaires**
- [ ] Adapter les vues pour les nouvelles conventions
- [ ] Vérifier les calculs de valorisation
- [ ] Mettre à jour les attributs des vues
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans stock.quant
- [ ] Tester les calculs de valorisation
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter les vues XML
- [ ] Vérifier les dépendances
- [ ] Optimiser les calculs si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types de produits
- [ ] Vérifier les calculs de valorisation
- [ ] Valider les droits d'accès
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la précision des calculs
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Adapter les vues pour Odoo 18.0
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.1.0.0
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation des calculs
- Gestion des grands volumes
- Impact sur la base de données
2. **Précision**
- Précision des calculs monétaires
- Gestion des arrondis
- Cohérence des valeurs
3. **Maintenance**
- Documentation des calculs
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_time_off_follower
## Description
Module qui permet d'ajouter un abonné alternatif qui recevra une copie des communications pendant les congés d'un employé.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Gestion des Abonnés Alternatifs**
- Champ pour définir l'abonné alternatif
- Notification automatique pendant les congés
- Gestion des destinataires des messages
2. **Modèles Modifiés**
- `hr.leave` : Ajout du champ alternate_follower_id
- `mail.thread` : Surcharge de _notify_get_recipients
- Intégration avec le système de messagerie
3. **Logique de Notification**
- Vérification des congés en cours
- Ajout des abonnés alternatifs
- Gestion des doublons
### Changements dans Odoo 18.0
1. **Architecture Mail/HR**
- Le système de notification reste stable
- Les congés fonctionnent de la même manière
- L'API de messagerie est similaire
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec le nouveau système de messagerie
- [ ] Valider la méthode _notify_get_recipients
- [ ] Optimiser la recherche des congés
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans l'API de messagerie
- [ ] Tester les notifications
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter le code Python
- [ ] Vérifier les dépendances
- [ ] Optimiser les requêtes si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types de congés
- [ ] Vérifier les notifications
- [ ] Valider la gestion des abonnés
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la performance des requêtes
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements dans l'API de messagerie
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.0.0.3
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Performance**
- Optimisation des recherches
- Gestion des notifications en masse
- Impact sur les grands volumes
2. **Fiabilité**
- Gestion des erreurs
- Validation des abonnements
- Cohérence des données
3. **Maintenance**
- Documentation du comportement
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_update_validity_date_when_send_so
## Description
Module de mise à jour de la date de validité lors de l'envoi des commandes clients
## Fonctionnalités Ajoutées
- Mise à jour automatique de la date de validité
- Gestion des exceptions
- Historique des modifications
## Modèles et Champs Modifiés
- sale.order
- Ajout du champ auto_update_validity (boolean)
- Ajout du champ last_validity_update (datetime)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait nécessiter des adaptations pour Odoo 18.0

View file

@ -0,0 +1,93 @@
# Migration vers Odoo 18.0 - bemade_user_password_bundle
## Description
Module qui automatise la création de bundles de mots de passe pour les nouveaux utilisateurs et modifie la propriété par défaut du bundle admin.
## Analyse Technique
### Fonctionnalités Actuelles
1. **Création Automatique**
- Bundle créé à la création d'un employé
- Attribution des accès automatique
- Gestion des droits d'administration
2. **Modèles Modifiés**
- `hr.employee` : Surcharge de create
- `password.bundle` : Modification des accès par défaut
- Intégration avec odoo_password_manager
3. **Logique d'Accès**
- Accès admin par défaut au groupe system
- Accès complet pour le nouvel employé
- Notes automatiques dans le bundle
### Changements dans Odoo 18.0
1. **Architecture Password/HR**
- Le système de gestion des mots de passe reste stable
- Les employés fonctionnent de la même manière
- Les groupes de sécurité sont similaires
2. **Modifications Nécessaires**
- [ ] Vérifier la compatibilité avec odoo_password_manager
- [ ] Valider la méthode de création des bundles
- [ ] Optimiser la gestion des accès
## Plan de Migration
### Phase 1 : Analyse et Préparation
1. **Révision du Code**
- [ ] Vérifier les changements dans odoo_password_manager
- [ ] Tester la création des bundles
- [ ] Identifier les potentiels conflits
2. **Tests**
- [ ] Créer des cas de test avec différents scénarios
- [ ] Documenter le comportement attendu
- [ ] Préparer des données de test
### Phase 2 : Migration
1. **Mise à Jour du Code**
- [ ] Adapter le code Python
- [ ] Vérifier les dépendances
- [ ] Optimiser les requêtes si nécessaire
2. **Tests et Validation**
- [ ] Tester avec différents types d'employés
- [ ] Vérifier les accès
- [ ] Valider la sécurité
## État de la Migration
En cours d'analyse - Migration simple requise
## Notes Importantes
- La fonctionnalité reste pertinente dans Odoo 18.0
- Les changements sont mineurs
- La logique de base reste la même
- Attention à la sécurité des accès
## Prochaines Étapes
1. Valider l'approche avec l'équipe
2. Vérifier les changements dans odoo_password_manager
3. Mettre à jour les tests
4. Tester avec différents scénarios
## Notes de Version
- Version originale: 17.0.0.1
- Dernière analyse: 26/01/2025
## Points d'Attention Particuliers
1. **Sécurité**
- Gestion des accès
- Protection des données
- Audit des modifications
2. **Fiabilité**
- Gestion des erreurs
- Validation des accès
- Cohérence des données
3. **Maintenance**
- Documentation des accès
- Gestion des cas spéciaux
- Logs pour le débogage

View file

@ -0,0 +1,31 @@
# Migration vers Odoo 18.0 - bemade_utils
## Description
Module utilitaire contenant des fonctions communes
## Fonctionnalités Ajoutées
- Fonctions utilitaires communes
- Gestion des exceptions
- Historique des modifications
## Modèles et Champs Modifiés
- ir.model
- Ajout du champ utility_functions (text)
- Ajout du champ last_utility_update (datetime)
## Statut Migration
- [ ] A migrer
- [ ] En cours
- [ ] Migré
## Détails Migration
- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0
- Analyser les impacts sur les workflows existants
## Actions Requises
- [ ] Vérifier la compatibilité avec Odoo 18.0
- [ ] Tester les fonctionnalités
- [ ] Mettre à jour la documentation
## Notes
- Ce module pourrait nécessiter des adaptations pour Odoo 18.0

View file

@ -0,0 +1 @@
from . import models

View file

@ -0,0 +1,46 @@
{
'name': 'Interactive AI Voice Assistant',
'version': '17.0.1.0.0',
'category': 'Productivity/Communication',
'summary': 'Natural Language Voice Interaction for Odoo using Open WebUI',
'sequence': 1,
'author': 'Benoît Vézina',
'website': 'https://bemade.org',
'maintainer': 'it@bemade.org',
'license': 'LGPL-3',
'description': """
Interactive AI Voice Assistant for Odoo
=====================================
This module enables natural language voice interaction with Odoo directly in the Discuss interface:
- Voice input processing using Open WebUI models
- Interactive AI chat assistant
- Smart context-aware responses
- Draft mode for new records creation
""",
'depends': [
'base',
'web',
'mail',
],
'data': [
'security/ir.model.access.csv',
'views/ai_assistant_views.xml',
'views/ai_config_views.xml',
],
'assets': {
'web.assets_backend': [
'interactive_discuss_ai/static/src/js/ai_assistant_chat.js',
'interactive_discuss_ai/static/src/xml/ai_assistant_chat.xml',
],
},
'demo': [],
'installable': True,
'application': True,
'auto_install': False,
'external_dependencies': {
'python': [
'requests',
],
},
}

View file

@ -0,0 +1,2 @@
from . import ai_assistant
from . import ai_config

View file

@ -0,0 +1,101 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError
class AIAssistantChannel(models.Model):
_name = 'ai.assistant.channel'
_description = 'AI Assistant Channel'
_inherit = ['mail.thread']
name = fields.Char(default="Assistant AI", readonly=True, tracking=True)
company_id = fields.Many2one(
'res.company',
string='Company',
required=True,
default=lambda self: self.env.company,
tracking=True
)
active = fields.Boolean(default=True, tracking=True)
user_id = fields.Many2one(
'res.users',
string='User',
required=True,
default=lambda self: self.env.user,
tracking=True
)
message_ids = fields.One2many(
'mail.message',
'res_id',
string='Messages',
domain=lambda self: [('model', '=', self._name)],
tracking=True
)
@api.model_create_multi
def create(self, vals_list):
records = super().create(vals_list)
for record in records:
# Create a dedicated discussion channel for the assistant
channel = self.env['mail.channel'].create({
'name': _('Assistant AI - %s', record.company_id.name),
'channel_type': 'chat',
'channel_partner_ids': [(4, record.user_id.partner_id.id)],
})
return records
def _get_conversation_history(self, limit=10):
"""Get recent conversation history"""
self.ensure_one()
messages = self.env['mail.message'].search([
('model', '=', self._name),
('res_id', '=', self.id)
], limit=limit, order='id desc')
history = []
for msg in reversed(messages):
role = "assistant" if msg.author_id == self.user_id.partner_id else "user"
history.append({
"role": role,
"content": msg.body
})
return history
def process_voice_message(self, voice_input):
"""Process voice input and respond"""
self.ensure_one()
if not voice_input:
raise UserError(_('No voice input provided'))
# Get conversation history
conversation_history = self._get_conversation_history()
# Use AI service to generate response
ai_service = self.env['ai.service'].with_company(self.company_id)
response = ai_service.generate_response(voice_input, conversation_history)
# Post response as message
self.message_post(
body=response,
message_type='comment',
subtype_xmlid='mail.mt_comment'
)
return True
@api.model
def get_assistant_for_user(self, user_id=None):
"""Get or create an assistant for the user in their company"""
if not user_id:
user_id = self.env.user.id
assistant = self.search([
('user_id', '=', user_id),
('company_id', '=', self.env.company.id),
('active', '=', True)
], limit=1)
if not assistant:
assistant = self.create({
'user_id': user_id,
'company_id': self.env.company.id
})
return assistant

View file

@ -0,0 +1,61 @@
from odoo import models, fields, api
from odoo.exceptions import UserError
class AIConfig(models.Model):
_name = 'ai.config'
_description = 'AI Configuration'
_inherit = ['mail.thread']
name = fields.Char(string='Name', required=True, default='Default Config', tracking=True)
company_id = fields.Many2one(
'res.company',
string='Company',
required=True,
default=lambda self: self.env.company,
tracking=True
)
openwebui_url = fields.Char(
string='Open WebUI URL',
required=True,
default='http://localhost:8080',
tracking=True
)
model_name = fields.Char(
string='Model Name',
required=True,
help='Nom du modèle à utiliser dans Open WebUI',
tracking=True
)
system_prompt = fields.Text(
string='System Prompt',
default="""Tu es un assistant Odoo expert qui aide les utilisateurs à effectuer des actions
dans le système. Analyse leurs demandes et propose des actions concrètes.""",
tracking=True
)
temperature = fields.Float(
string='Temperature',
default=0.7,
help='Contrôle la créativité des réponses (0.0 - 1.0)',
tracking=True
)
max_tokens = fields.Integer(
string='Max Tokens',
default=2000,
tracking=True
)
active = fields.Boolean(default=True, tracking=True)
_sql_constraints = [
('company_uniq', 'unique(company_id, active)',
'Une seule configuration active par compagnie est autorisée!')
]
@api.model
def get_default_config(self):
"""Récupère la configuration active pour la compagnie actuelle"""
config = self.search([
('active', '=', True),
('company_id', '=', self.env.company.id)
], limit=1)
if not config:
raise UserError('Aucune configuration AI active trouvée pour votre compagnie')

View file

@ -0,0 +1,62 @@
import requests
import json
from odoo import models, tools
from odoo.exceptions import UserError
class AIService(models.AbstractModel):
_name = 'ai.service'
_description = 'AI Service for Open WebUI Integration'
def _get_headers(self):
return {
'Content-Type': 'application/json',
}
def _call_openwebui_api(self, endpoint, payload):
"""Appelle l'API Open WebUI avec la configuration de la compagnie actuelle"""
config = self.env['ai.config'].with_company(self.env.company).get_default_config()
url = f"{config.openwebui_url}/api/v1/{endpoint}"
try:
response = requests.post(
url,
headers=self._get_headers(),
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
raise UserError(f"Erreur de communication avec Open WebUI: {str(e)}")
def generate_response(self, user_input, conversation_history=None):
"""Génère une réponse en utilisant le modèle Open WebUI de la compagnie"""
config = self.env['ai.config'].with_company(self.env.company).get_default_config()
messages = []
if config.system_prompt:
messages.append({
"role": "system",
"content": config.system_prompt
})
# Ajouter l'historique de conversation si disponible
if conversation_history:
messages.extend(conversation_history)
# Ajouter l'entrée utilisateur actuelle
messages.append({
"role": "user",
"content": user_input
})
payload = {
"model": config.model_name,
"messages": messages,
"temperature": config.temperature,
"max_tokens": config.max_tokens,
"stream": False
}
response = self._call_openwebui_api('chat/completions', payload)
return response.get('choices', [{}])[0].get('message', {}).get('content', '')

View file

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_ai_assistant_channel_user,ai.assistant.channel.user,interactive_discuss_ai.model_ai_assistant_channel,base.group_user,1,1,1,1
access_ai_config_user,ai.config.user,interactive_discuss_ai.model_ai_config,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_ai_assistant_channel_user ai.assistant.channel.user interactive_discuss_ai.model_ai_assistant_channel base.group_user 1 1 1 1
3 access_ai_config_user ai.config.user interactive_discuss_ai.model_ai_config base.group_user 1 1 1 1

View file

@ -0,0 +1,52 @@
/** @odoo-module **/
import { registerPatch } from '@mail/model/model_core';
import { attr } from '@mail/model/model_field';
import { clear } from '@mail/model/model_field_command';
registerPatch({
name: 'mail.composer',
fields: {
isVoiceRecording: attr({
default: false,
}),
},
recordMethods: {
async onClickVoiceRecord() {
if (!this.isVoiceRecording) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
this.mediaRecorder = new MediaRecorder(stream);
const audioChunks = [];
this.mediaRecorder.addEventListener('dataavailable', (event) => {
audioChunks.push(event.data);
});
this.mediaRecorder.addEventListener('stop', async () => {
const audioBlob = new Blob(audioChunks);
// Convert to base64 and send to backend
const reader = new FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = async () => {
const base64data = reader.result;
await this.env.services.rpc({
model: 'ai.assistant.channel',
method: 'process_voice_message',
args: [this.thread.id, base64data],
});
};
});
this.mediaRecorder.start();
this.update({ isVoiceRecording: true });
} catch (err) {
console.error('Error accessing microphone:', err);
}
} else {
this.mediaRecorder.stop();
this.update({ isVoiceRecording: false });
}
},
},
});

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-inherit="mail.Composer" t-inherit-mode="extension">
<xpath expr="//div[hasclass('o-mail-Composer-buttons')]" position="inside">
<button class="btn btn-light"
t-on-click="onClickVoiceRecord"
t-att-class="{ 'btn-danger': isVoiceRecording }">
<i class="fa fa-microphone" t-att-class="{ 'fa-pulse': isVoiceRecording }"/>
</button>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- AI Assistant Channel Form View -->
<record id="view_ai_assistant_channel_form" model="ir.ui.view">
<field name="name">ai.assistant.channel.form</field>
<field name="model">ai.assistant.channel</field>
<field name="arch" type="xml">
<form string="AI Assistant Channel">
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button" options="{&quot;terminology&quot;: &quot;archive&quot;}"/>
</button>
</div>
<group>
<group>
<field name="name"/>
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<!-- AI Assistant Channel Tree View -->
<record id="view_ai_assistant_channel_tree" model="ir.ui.view">
<field name="name">ai.assistant.channel.tree</field>
<field name="model">ai.assistant.channel</field>
<field name="arch" type="xml">
<tree string="AI Assistant Channels">
<field name="name"/>
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<!-- AI Assistant Channel Search View -->
<record id="view_ai_assistant_channel_search" model="ir.ui.view">
<field name="name">ai.assistant.channel.search</field>
<field name="model">ai.assistant.channel</field>
<field name="arch" type="xml">
<search string="Search AI Assistant Channels">
<field name="name"/>
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
</search>
</field>
</record>
<!-- AI Assistant Channel Action -->
<record id="action_ai_assistant_channel" model="ir.actions.act_window">
<field name="name">AI Assistant Channels</field>
<field name="res_model">ai.assistant.channel</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_ai_assistant_channel_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first AI Assistant Channel!
</p>
<p>
AI Assistant Channels allow you to interact with the AI assistant through messages.
</p>
</field>
</record>
<!-- Menu Items -->
<menuitem id="menu_ai_assistant"
name="AI Assistant"
web_icon="interactive_discuss_ai,static/description/icon.png"
sequence="10"/>
<menuitem id="menu_ai_assistant_channel"
name="Assistant Channels"
parent="menu_ai_assistant"
action="action_ai_assistant_channel"
sequence="10"/>
</odoo>

View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_ai_config_form" model="ir.ui.view">
<field name="name">ai.config.form</field>
<field name="model">ai.config</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button"/>
</button>
</div>
<group>
<group>
<field name="name"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="openwebui_url"/>
<field name="model_name"/>
<field name="active"/>
</group>
<group>
<field name="temperature"/>
<field name="max_tokens"/>
</group>
</group>
<group string="System Prompt">
<field name="system_prompt" nolabel="1"/>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<record id="view_ai_config_tree" model="ir.ui.view">
<field name="name">ai.config.tree</field>
<field name="model">ai.config</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="model_name"/>
<field name="openwebui_url"/>
<field name="active"/>
</tree>
</field>
</record>
<record id="view_ai_config_search" model="ir.ui.view">
<field name="name">ai.config.search</field>
<field name="model">ai.config</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="model_name"/>
<separator/>
<filter string="Archivé" name="inactive" domain="[('active', '=', False)]"/>
<group expand="0" string="Group By">
<filter string="Compagnie" name="company" domain="[]" context="{'group_by': 'company_id'}"/>
</group>
</search>
</field>
</record>
<record id="action_ai_config" model="ir.actions.act_window">
<field name="name">Configuration AI</field>
<field name="res_model">ai.config</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_ai_config_search"/>
<field name="context">{'search_default_active': 1}</field>
</record>
<menuitem id="menu_ai_config"
name="Configuration AI"
action="action_ai_config"
parent="base.menu_administration"
sequence="100"/>
</odoo>

View file

@ -0,0 +1,90 @@
# Odoo Proxmox Manager
This module allows you to manage your Proxmox servers and virtual machines directly from Odoo 17.0.
## Features
- Manage multiple Proxmox servers and clusters
- Monitor server status and resources
- View and manage virtual machines
- Start, stop, restart, suspend, and resume VMs
- Group servers into clusters for better organization
- Multi-company support
- Role-based access control
## Installation
### Prerequisites
1. Odoo 17.0
2. Python package requirements:
```
proxmoxer
requests
```
### Steps
1. Clone this repository into your Odoo addons directory
2. Install the required Python packages:
```bash
pip install proxmoxer requests
```
3. Update your Odoo addons list
4. Install the module through Odoo's Apps menu
## Configuration
1. Create an API Token in your Proxmox server:
- Log in to your Proxmox web interface
- Go to Datacenter -> Permissions -> API Tokens
- Create a new token and note down the Token ID and Secret
2. In Odoo:
- Go to the Proxmox menu
- Create a new cluster (optional)
- Create a new server:
- Enter the server hostname
- Enter your API token information
- Test the connection
## Usage
### Managing Servers
1. Navigate to Proxmox -> Servers
2. Create or select a server
3. Click "Sync VMs" to synchronize virtual machines
4. View server status and resource information
### Managing Virtual Machines
1. Navigate to Proxmox -> Virtual Machines
2. View all VMs across your servers
3. Use the action buttons to:
- Start VMs
- Stop VMs
- Restart VMs
- Suspend VMs
- Resume VMs
### Managing Clusters
1. Navigate to Proxmox -> Clusters
2. Create a new cluster
3. Add servers to the cluster
4. Use "Sync All Servers" to update all servers in the cluster
## Security
The module includes two user groups:
- Proxmox User: Can view servers and VMs
- Proxmox Manager: Can manage servers and VMs
## Support
For bugs or feature requests, please create an issue in the repository.
## License
LGPL-3

View file

@ -0,0 +1,3 @@
from . import models
from . import controllers
from . import wizard

View file

@ -0,0 +1,35 @@
{
'name': 'Proxmox Manager',
'version': '17.0.1.0.0',
'category': 'Administration',
'summary': 'Manage Proxmox servers and clusters from Odoo',
'sequence': 1,
'author': 'DurPro',
'website': 'https://www.durpro.com',
'license': 'LGPL-3',
'icon': '/odoo_proxmox_manager/static/description/icon.png',
'depends': [
'base',
'web',
'mail'
],
'data': [
'security/proxmox_security.xml',
'security/ir.model.access.csv',
'views/proxmox_server_views.xml',
'views/proxmox_cluster_views.xml',
'views/proxmox_vm_views.xml',
'views/proxmox_menus.xml',
],
'assets': {
'web.assets_backend': [
'odoo_proxmox_manager/static/src/components/**/*',
'odoo_proxmox_manager/static/src/js/dashboard_view.js',
'odoo_proxmox_manager/static/src/scss/dashboard.scss',
'odoo_proxmox_manager/static/src/xml/dashboard.xml',
],
},
'application': True,
'installable': True,
'auto_install': False
}

View file

@ -0,0 +1 @@
from . import main

View file

@ -0,0 +1,9 @@
from odoo import http
from odoo.http import request
class ProxmoxController(http.Controller):
@http.route('/proxmox/dashboard/data', type='json', auth='user')
def get_dashboard_data(self):
"""Get dashboard data for the Proxmox overview"""
return request.env['proxmox.server'].get_dashboard_data()

View file

@ -0,0 +1,3 @@
from . import proxmox_server
from . import proxmox_cluster
from . import proxmox_vm

View file

@ -0,0 +1,37 @@
from odoo import models, fields, api
class ProxmoxCluster(models.Model):
_name = 'proxmox.cluster'
_description = 'Proxmox Cluster'
_order = 'name'
_inherit = ['mail.thread']
name = fields.Char(string='Name', required=True, tracking=True)
description = fields.Text(string='Description', tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company)
server_ids = fields.One2many('proxmox.server', 'cluster_id', string='Servers')
server_count = fields.Integer(string='Server Count', compute='_compute_server_count')
total_vms = fields.Integer(string='Total VMs', compute='_compute_total_vms')
active_servers = fields.Integer(string='Active Servers', compute='_compute_active_servers')
@api.depends('server_ids')
def _compute_server_count(self):
for cluster in self:
cluster.server_count = len(cluster.server_ids)
@api.depends('server_ids.vm_ids')
def _compute_total_vms(self):
for cluster in self:
cluster.total_vms = sum(server.vm_count for server in cluster.server_ids)
@api.depends('server_ids.state')
def _compute_active_servers(self):
for cluster in self:
cluster.active_servers = len(cluster.server_ids.filtered(lambda s: s.state == 'online'))
def action_sync_all_servers(self):
"""Synchronize all servers in the cluster"""
self.ensure_one()
for server in self.server_ids:
server.action_sync_vms()
return True

View file

@ -0,0 +1,164 @@
from odoo import models, fields, api
from proxmoxer import ProxmoxAPI
import requests
import logging
_logger = logging.getLogger(__name__)
class ProxmoxServer(models.Model):
_name = 'proxmox.server'
_description = 'Proxmox Server'
_order = 'name'
_inherit = ['mail.thread']
name = fields.Char(string='Name', required=True, tracking=True)
hostname = fields.Char(string='Hostname', required=True, tracking=True)
port = fields.Integer(string='Port', default=8006, tracking=True)
cluster_id = fields.Many2one('proxmox.cluster', string='Cluster', tracking=True)
username = fields.Char(string='Username', required=True, tracking=True)
token_name = fields.Char(string='API Token Name', tracking=True)
token_value = fields.Char(string='API Token Value', tracking=True)
verify_ssl = fields.Boolean(string='Verify SSL', default=True, tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.company)
state = fields.Selection([
('offline', 'Offline'),
('online', 'Online')
], string='Status', default='offline', compute='_compute_state', store=True, tracking=True)
vm_ids = fields.One2many('proxmox.vm', 'server_id', string='Virtual Machines')
vm_count = fields.Integer(string='VM Count', compute='_compute_vm_count')
node_info = fields.Text(string='Node Information', compute='_compute_node_info')
def _get_proxmox_connection(self):
try:
if not self.token_name or not self.token_value:
raise ValueError("API Token is required")
return ProxmoxAPI(
self.hostname,
port=self.port,
user=self.username,
token_name=self.token_name,
token_value=self.token_value,
verify_ssl=self.verify_ssl
)
except Exception as e:
_logger.error(f"Failed to connect to Proxmox server {self.name}: {str(e)}")
return None
@api.depends('hostname', 'port', 'token_name', 'token_value')
def _compute_state(self):
for server in self:
try:
proxmox = server._get_proxmox_connection()
if proxmox:
# Test connection by getting version info
proxmox.version.get()
server.state = 'online'
else:
server.state = 'offline'
except:
server.state = 'offline'
@api.depends('vm_ids')
def _compute_vm_count(self):
for server in self:
server.vm_count = len(server.vm_ids)
def _compute_node_info(self):
for server in self:
try:
proxmox = server._get_proxmox_connection()
if proxmox:
node_info = proxmox.nodes(server.hostname).status.get()
server.node_info = str(node_info)
else:
server.node_info = "Unable to connect to server"
except Exception as e:
server.node_info = f"Error getting node info: {str(e)}"
def action_sync_vms(self):
"""Synchronize VMs from Proxmox server"""
self.ensure_one()
proxmox = self._get_proxmox_connection()
if not proxmox:
return False
try:
# Get all VMs from the server
vms = proxmox.nodes(self.hostname).qemu.get()
# Update or create VM records
for vm in vms:
vm_vals = {
'name': vm.get('name'),
'vmid': vm.get('vmid'),
'status': vm.get('status'),
'server_id': self.id,
}
existing_vm = self.env['proxmox.vm'].search([
('server_id', '=', self.id),
('vmid', '=', vm.get('vmid'))
])
if existing_vm:
existing_vm.write(vm_vals)
else:
self.env['proxmox.vm'].create(vm_vals)
return True
except Exception as e:
_logger.error(f"Failed to sync VMs for server {self.name}: {str(e)}")
return False
@api.model
def get_dashboard_data(self):
"""Get dashboard data for the Proxmox overview"""
servers = self.search([])
clusters = self.env['proxmox.cluster'].search([])
vms = self.env['proxmox.vm'].search([])
server_data = []
for server in servers:
try:
proxmox = server._get_proxmox_connection()
if proxmox:
node_info = proxmox.nodes(server.hostname).status.get()
memory_total = node_info.get('memory', {}).get('total', 0)
memory_used = node_info.get('memory', {}).get('used', 0)
memory_usage = round((memory_used / memory_total) * 100, 2) if memory_total else 0
cpu_usage = round(node_info.get('cpu', 0) * 100, 2)
server_data.append({
'id': server.id,
'name': server.name,
'state': server.state,
'vm_count': server.vm_count,
'memory_usage': memory_usage,
'cpu_usage': cpu_usage,
})
else:
server_data.append({
'id': server.id,
'name': server.name,
'state': 'offline',
'vm_count': server.vm_count,
'memory_usage': 0,
'cpu_usage': 0,
})
except Exception as e:
_logger.error(f"Error getting data for server {server.name}: {str(e)}")
server_data.append({
'id': server.id,
'name': server.name,
'state': 'offline',
'vm_count': server.vm_count,
'memory_usage': 0,
'cpu_usage': 0,
})
return {
'server_count': len(servers),
'cluster_count': len(clusters),
'vm_count': len(vms),
'servers': server_data,
}

View file

@ -0,0 +1,87 @@
from odoo import models, fields, api
class ProxmoxVM(models.Model):
_name = 'proxmox.vm'
_description = 'Proxmox Virtual Machine'
_order = 'name'
_inherit = ['mail.thread']
name = fields.Char(string='Name', required=True, tracking=True)
vmid = fields.Integer(string='VM ID', required=True, tracking=True)
server_id = fields.Many2one('proxmox.server', string='Server', required=True, tracking=True)
company_id = fields.Many2one('res.company', string='Company', required=True,
related='server_id.company_id', store=True, readonly=True)
status = fields.Selection([
('running', 'Running'),
('stopped', 'Stopped'),
('suspended', 'Suspended')
], string='Status', default='stopped', tracking=True)
memory = fields.Integer(string='Memory (MB)')
cpus = fields.Integer(string='vCPUs')
disk_size = fields.Float(string='Disk Size (GB)')
ip_address = fields.Char(string='IP Address')
def action_start(self):
"""Start the virtual machine"""
self.ensure_one()
proxmox = self.server_id._get_proxmox_connection()
if proxmox:
try:
proxmox.nodes(self.server_id.hostname).qemu(self.vmid).status.start.post()
self.status = 'running'
return True
except Exception as e:
return False
return False
def action_stop(self):
"""Stop the virtual machine"""
self.ensure_one()
proxmox = self.server_id._get_proxmox_connection()
if proxmox:
try:
proxmox.nodes(self.server_id.hostname).qemu(self.vmid).status.stop.post()
self.status = 'stopped'
return True
except Exception as e:
return False
return False
def action_restart(self):
"""Restart the virtual machine"""
self.ensure_one()
proxmox = self.server_id._get_proxmox_connection()
if proxmox:
try:
proxmox.nodes(self.server_id.hostname).qemu(self.vmid).status.reset.post()
self.status = 'running'
return True
except Exception as e:
return False
return False
def action_suspend(self):
"""Suspend the virtual machine"""
self.ensure_one()
proxmox = self.server_id._get_proxmox_connection()
if proxmox:
try:
proxmox.nodes(self.server_id.hostname).qemu(self.vmid).status.suspend.post()
self.status = 'suspended'
return True
except Exception as e:
return False
return False
def action_resume(self):
"""Resume the virtual machine"""
self.ensure_one()
proxmox = self.server_id._get_proxmox_connection()
if proxmox:
try:
proxmox.nodes(self.server_id.hostname).qemu(self.vmid).status.resume.post()
self.status = 'running'
return True
except Exception as e:
return False
return False

View file

@ -0,0 +1,2 @@
proxmoxer>=1.3.1
requests>=2.31.0

View file

@ -0,0 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_proxmox_server_user,proxmox.server.user,model_proxmox_server,group_proxmox_user,1,0,0,0
access_proxmox_server_manager,proxmox.server.manager,model_proxmox_server,group_proxmox_manager,1,1,1,1
access_proxmox_cluster_user,proxmox.cluster.user,model_proxmox_cluster,group_proxmox_user,1,0,0,0
access_proxmox_cluster_manager,proxmox.cluster.manager,model_proxmox_cluster,group_proxmox_manager,1,1,1,1
access_proxmox_vm_user,proxmox.vm.user,model_proxmox_vm,group_proxmox_user,1,1,0,0
access_proxmox_vm_manager,proxmox.vm.manager,model_proxmox_vm,group_proxmox_manager,1,1,1,1
access_proxmox_server_wizard,proxmox.server.wizard,model_proxmox_server_wizard,base.group_user,1,1,1,0
access_proxmox_server_wizard_node,proxmox.server.wizard.node,model_proxmox_server_wizard_node,base.group_user,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_proxmox_server_user proxmox.server.user model_proxmox_server group_proxmox_user 1 0 0 0
3 access_proxmox_server_manager proxmox.server.manager model_proxmox_server group_proxmox_manager 1 1 1 1
4 access_proxmox_cluster_user proxmox.cluster.user model_proxmox_cluster group_proxmox_user 1 0 0 0
5 access_proxmox_cluster_manager proxmox.cluster.manager model_proxmox_cluster group_proxmox_manager 1 1 1 1
6 access_proxmox_vm_user proxmox.vm.user model_proxmox_vm group_proxmox_user 1 1 0 0
7 access_proxmox_vm_manager proxmox.vm.manager model_proxmox_vm group_proxmox_manager 1 1 1 1
8 access_proxmox_server_wizard proxmox.server.wizard model_proxmox_server_wizard base.group_user 1 1 1 0
9 access_proxmox_server_wizard_node proxmox.server.wizard.node model_proxmox_server_wizard_node base.group_user 1 1 1 0

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="module_proxmox_category" model="ir.module.category">
<field name="name">Proxmox Management</field>
<field name="description">Manage Proxmox servers and virtual machines</field>
<field name="sequence">20</field>
</record>
<record id="group_proxmox_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="module_proxmox_category"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="group_proxmox_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id" ref="module_proxmox_category"/>
<field name="implied_ids" eval="[(4, ref('group_proxmox_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
</record>
</data>
<data noupdate="1">
<record id="proxmox_server_rule" model="ir.rule">
<field name="name">Proxmox Server Multi-Company</field>
<field name="model_id" ref="model_proxmox_server"/>
<field name="global" eval="True"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
<record id="proxmox_cluster_rule" model="ir.rule">
<field name="name">Proxmox Cluster Multi-Company</field>
<field name="model_id" ref="model_proxmox_cluster"/>
<field name="global" eval="True"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
</data>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

View file

@ -0,0 +1,32 @@
/** @odoo-module **/
import { ListController } from "@web/views/list/list_controller";
import { registry } from "@web/core/registry";
import { listView } from "@web/views/list/list_view";
class ProxmoxServerListController extends ListController {
setup() {
super.setup();
}
async onAddServer() {
await this.env.services.action.doAction({
type: 'ir.actions.act_window',
res_model: 'proxmox.server.wizard',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
target: 'new',
context: {},
});
}
}
ProxmoxServerListController.template = 'odoo_proxmox_manager.ProxmoxServerListView.Buttons';
export const proxmoxServerList = {
...listView,
Controller: ProxmoxServerListController,
};
registry.category("views").add("proxmox_server_list", proxmoxServerList);

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="odoo_proxmox_manager.ProxmoxServerListView.Buttons" t-inherit="web.ListView.Buttons" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('o_list_buttons')]" position="inside">
<button type="button" class="btn btn-primary" t-on-click="onAddServer">
Ajouter un serveur
</button>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,51 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { Layout } from "@web/search/layout";
import { useService } from "@web/core/utils/hooks";
import { Component, onWillStart, useRef } from "@odoo/owl";
class ProxmoxDashboardController extends Component {
setup() {
this.actionService = useService("action");
this.orm = useService("orm");
this.serverData = {};
this.chartRefs = {};
onWillStart(async () => {
await this.fetchData();
});
}
async fetchData() {
const serverData = await this.orm.call(
'proxmox.server',
'get_dashboard_data',
[]
);
this.serverData = serverData;
this.render();
}
openServers() {
this.actionService.doAction('odoo_proxmox_manager.action_proxmox_server');
}
openClusters() {
this.actionService.doAction('odoo_proxmox_manager.action_proxmox_cluster');
}
openVMs() {
this.actionService.doAction('odoo_proxmox_manager.action_proxmox_vm');
}
}
ProxmoxDashboardController.template = 'odoo_proxmox_manager.DashboardView';
ProxmoxDashboardController.components = { Layout };
registry.category("actions").add("proxmox_dashboard_client_action", {
type: "ir.actions.client",
tag: "proxmox_dashboard",
target: "main",
Component: ProxmoxDashboardController,
});

View file

@ -0,0 +1,52 @@
/** @odoo-module **/
import { ListController } from "@web/views/list/list_controller";
import { registry } from "@web/core/registry";
import { listView } from "@web/views/list/list_view";
export class ProxmoxServerListController extends ListController {
setup() {
super.setup();
this.state = {};
}
/**
* @override
*/
async getLocalState() {
const state = await super.getLocalState();
return { ...state, ...this.state };
}
/**
* @override
*/
async setLocalState(state) {
if (state) {
this.state = { ...this.state, ...state };
await super.setLocalState(state);
}
}
async onAddServer() {
await this.env.services.action.doAction({
type: 'ir.actions.act_window',
res_model: 'proxmox.server.wizard',
view_mode: 'form',
views: [[false, 'form']],
target: 'new',
context: {},
}, {
onClose: () => this.actionService.restore(),
});
}
}
ProxmoxServerListController.template = 'odoo_proxmox_manager.ProxmoxServerListView';
export const ProxmoxServerListView = {
...listView,
Controller: ProxmoxServerListController,
};
registry.category("views").add("proxmox_server_list", ProxmoxServerListView);

View file

@ -0,0 +1,113 @@
.proxmox-dashboard {
padding: 1rem;
.dashboard-header {
margin-bottom: 2rem;
h1 {
color: #2b2b2b;
font-size: 2rem;
}
}
.dashboard-stats {
display: flex;
gap: 1.5rem;
margin-bottom: 2rem;
.stat-card {
flex: 1;
background: white;
border-radius: 8px;
padding: 1.5rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
cursor: pointer;
transition: transform 0.2s;
&:hover {
transform: translateY(-2px);
}
.stat-value {
font-size: 2.5rem;
font-weight: bold;
color: #2b2b2b;
margin-bottom: 0.5rem;
}
.stat-label {
color: #666;
font-size: 1rem;
}
}
}
.dashboard-servers {
h2 {
color: #2b2b2b;
margin-bottom: 1rem;
}
.server-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1rem;
.server-card {
background: white;
border-radius: 8px;
padding: 1rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
.server-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
.server-name {
font-weight: bold;
font-size: 1.1rem;
}
.server-status {
padding: 0.25rem 0.75rem;
border-radius: 12px;
font-size: 0.9rem;
&.status-online {
background: #e6f4ea;
color: #1e8e3e;
}
&.status-offline {
background: #fce8e6;
color: #d93025;
}
}
}
.server-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.5rem;
.stat {
text-align: center;
.label {
display: block;
color: #666;
font-size: 0.9rem;
margin-bottom: 0.25rem;
}
.value {
font-weight: bold;
color: #2b2b2b;
}
}
}
}
}
}
}

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="odoo_proxmox_manager.DashboardView" owl="1">
<Layout>
<div class="proxmox-dashboard">
<div class="dashboard-header">
<h1>Proxmox Dashboard</h1>
</div>
<div class="dashboard-stats">
<div class="stat-card" t-on-click="openServers">
<div class="stat-value"><t t-esc="serverData.server_count || 0"/></div>
<div class="stat-label">Servers</div>
</div>
<div class="stat-card" t-on-click="openClusters">
<div class="stat-value"><t t-esc="serverData.cluster_count || 0"/></div>
<div class="stat-label">Clusters</div>
</div>
<div class="stat-card" t-on-click="openVMs">
<div class="stat-value"><t t-esc="serverData.vm_count || 0"/></div>
<div class="stat-label">Virtual Machines</div>
</div>
</div>
<div class="dashboard-servers">
<h2>Server Status</h2>
<div class="server-list">
<t t-foreach="serverData.servers || []" t-as="server" t-key="server.id">
<div class="server-card">
<div class="server-header">
<span class="server-name"><t t-esc="server.name"/></span>
<span t-attf-class="server-status status-#{server.state}">
<t t-esc="server.state"/>
</span>
</div>
<div class="server-stats">
<div class="stat">
<span class="label">VMs:</span>
<span class="value"><t t-esc="server.vm_count"/></span>
</div>
<div class="stat">
<span class="label">Memory:</span>
<span class="value"><t t-esc="server.memory_usage"/>%</span>
</div>
<div class="stat">
<span class="label">CPU:</span>
<span class="value"><t t-esc="server.cpu_usage"/>%</span>
</div>
</div>
</div>
</t>
</div>
</div>
</div>
</Layout>
</t>
</templates>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="odoo_proxmox_manager.ProxmoxServerListView" t-inherit="web.ListView" t-inherit-mode="primary" owl="1">
<xpath expr="//div[hasclass('o_control_panel_main_buttons')]" position="inside">
<button type="button" class="btn btn-primary" t-on-click="onAddServer">
Ajouter un serveur
</button>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Cluster Tree View -->
<record id="view_proxmox_cluster_tree" model="ir.ui.view">
<field name="name">proxmox.cluster.tree</field>
<field name="model">proxmox.cluster</field>
<field name="arch" type="xml">
<tree string="Proxmox Clusters" create="False">
<field name="name"/>
<field name="server_count"/>
<field name="active_servers"/>
<field name="total_vms"/>
</tree>
</field>
</record>
<!-- Cluster Form View -->
<record id="view_proxmox_cluster_form" model="ir.ui.view">
<field name="name">proxmox.cluster.form</field>
<field name="model">proxmox.cluster</field>
<field name="arch" type="xml">
<form string="Proxmox Cluster">
<header>
<button name="action_sync_all_servers" string="Sync All Servers" type="object" class="oe_highlight"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="name" placeholder="Cluster Name"/>
</h1>
</div>
<group>
<group>
<field name="description"/>
</group>
<group>
<field name="server_count"/>
<field name="active_servers"/>
<field name="total_vms"/>
</group>
</group>
<notebook>
<page string="Servers">
<field name="server_ids">
<tree>
<field name="name"/>
<field name="hostname"/>
<field name="state"/>
<field name="vm_count"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Cluster Search View -->
<record id="view_proxmox_cluster_search" model="ir.ui.view">
<field name="name">proxmox.cluster.search</field>
<field name="model">proxmox.cluster</field>
<field name="arch" type="xml">
<search string="Search Proxmox Clusters">
<field name="name"/>
<field name="description"/>
</search>
</field>
</record>
<!-- Cluster Action Window -->
<record id="action_proxmox_cluster" model="ir.actions.act_window">
<field name="name">Proxmox Clusters</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">proxmox.cluster</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_proxmox_cluster_search"/>
<field name="context">{'form_view_ref': 'odoo_proxmox_manager.view_proxmox_cluster_form'}</field>
<field name="domain">[]</field>
<field name="limit">80</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first Proxmox cluster!
</p>
</field>
</record>
</data>
</odoo>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Main Menu -->
<menuitem id="menu_proxmox_root"
name="Proxmox"
web_icon="odoo_proxmox_manager,static/description/icon.png"
sequence="100"
groups="base.group_system"/>
<!-- Clusters Menu -->
<menuitem id="menu_proxmox_clusters"
name="Clusters"
parent="menu_proxmox_root"
action="action_proxmox_cluster"
sequence="10"/>
<!-- Servers Menu -->
<menuitem id="menu_proxmox_servers"
name="Servers"
parent="menu_proxmox_root"
action="action_proxmox_server"
sequence="20"/>
<!-- Virtual Machines Menu -->
<menuitem id="menu_proxmox_vms"
name="Virtual Machines"
parent="menu_proxmox_root"
action="action_proxmox_vm"
sequence="30"/>
</data>
</odoo>

View file

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Server Tree View -->
<record id="view_proxmox_server_tree" model="ir.ui.view">
<field name="name">proxmox.server.tree</field>
<field name="model">proxmox.server</field>
<field name="arch" type="xml">
<tree js_class="proxmox_server_list" string="Proxmox Servers">
<field name="name"/>
<field name="hostname"/>
<field name="cluster_id"/>
<field name="state"/>
<field name="vm_count"/>
</tree>
</field>
</record>
<!-- Server Form View -->
<record id="view_proxmox_server_form" model="ir.ui.view">
<field name="name">proxmox.server.form</field>
<field name="model">proxmox.server</field>
<field name="arch" type="xml">
<form string="Proxmox Server">
<header>
<button name="action_sync_vms" string="Sync VMs" type="object" class="oe_highlight"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="name" placeholder="Server Name"/>
</h1>
</div>
<group>
<group>
<field name="hostname"/>
<field name="port"/>
<field name="cluster_id"/>
<field name="state"/>
</group>
<group>
<field name="username"/>
<field name="token_name"/>
<field name="token_value" password="True"/>
<field name="verify_ssl"/>
</group>
</group>
<notebook>
<page string="Virtual Machines">
<field name="vm_ids">
<tree>
<field name="name"/>
<field name="vmid"/>
<field name="status"/>
<field name="memory"/>
<field name="cpus"/>
<field name="disk_size"/>
<field name="ip_address"/>
</tree>
</field>
</page>
<page string="Node Information">
<field name="node_info"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- Server Search View -->
<record id="view_proxmox_server_search" model="ir.ui.view">
<field name="name">proxmox.server.search</field>
<field name="model">proxmox.server</field>
<field name="arch" type="xml">
<search string="Search Proxmox Servers">
<field name="name"/>
<field name="hostname"/>
<field name="cluster_id"/>
<separator/>
<filter string="Online" name="online" domain="[('state', '=', 'online')]"/>
<filter string="Offline" name="offline" domain="[('state', '=', 'offline')]"/>
<group expand="0" string="Group By">
<filter string="Cluster" name="cluster" context="{'group_by': 'cluster_id'}"/>
<filter string="Status" name="status" context="{'group_by': 'state'}"/>
</group>
</search>
</field>
</record>
<!-- Server Action Window -->
<record id="action_proxmox_server" model="ir.actions.act_window">
<field name="name">Proxmox Servers</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">proxmox.server</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_proxmox_server_search"/>
<field name="context">{'search_default_cluster': 1, 'form_view_ref': 'odoo_proxmox_manager.view_proxmox_server_form'}</field>
<field name="domain">[]</field>
<field name="limit">80</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first Proxmox server!
</p>
</field>
</record>
</data>
</odoo>

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- VM Tree View -->
<record id="view_proxmox_vm_tree" model="ir.ui.view">
<field name="name">proxmox.vm.tree</field>
<field name="model">proxmox.vm</field>
<field name="arch" type="xml">
<tree string="Virtual Machines" create="False">
<field name="name"/>
<field name="vmid"/>
<field name="server_id"/>
<field name="status"/>
<field name="memory"/>
<field name="cpus"/>
<field name="disk_size"/>
<field name="ip_address"/>
</tree>
</field>
</record>
<!-- VM Form View -->
<record id="view_proxmox_vm_form" model="ir.ui.view">
<field name="name">proxmox.vm.form</field>
<field name="model">proxmox.vm</field>
<field name="arch" type="xml">
<form string="Virtual Machine">
<header>
<button name="action_start" string="Start" type="object"
invisible="status == 'running'"
class="oe_highlight"/>
<button name="action_stop" string="Stop" type="object"
invisible="status == 'stopped'"
class="btn-danger"/>
<button name="action_restart" string="Restart" type="object"
invisible="status == 'stopped'"
class="btn-warning"/>
<button name="action_suspend" string="Suspend" type="object"
invisible="status in ('suspended', 'stopped')"
class="btn-info"/>
<button name="action_resume" string="Resume" type="object"
invisible="status != 'suspended'"
class="oe_highlight"/>
<field name="status" widget="statusbar"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="name" placeholder="VM Name"/>
</h1>
</div>
<group>
<group>
<field name="vmid"/>
<field name="server_id"/>
<field name="ip_address"/>
</group>
<group>
<field name="memory"/>
<field name="cpus"/>
<field name="disk_size"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- VM Search View -->
<record id="view_proxmox_vm_search" model="ir.ui.view">
<field name="name">proxmox.vm.search</field>
<field name="model">proxmox.vm</field>
<field name="arch" type="xml">
<search string="Search Virtual Machines">
<field name="name"/>
<field name="vmid"/>
<field name="server_id"/>
<field name="ip_address"/>
<filter string="Running" name="running" domain="[('status', '=', 'running')]"/>
<filter string="Stopped" name="stopped" domain="[('status', '=', 'stopped')]"/>
<filter string="Suspended" name="suspended" domain="[('status', '=', 'suspended')]"/>
<group expand="0" string="Group By">
<filter string="Server" name="server" context="{'group_by': 'server_id'}"/>
<filter string="Status" name="status" context="{'group_by': 'status'}"/>
</group>
</search>
</field>
</record>
<!-- VM Action Window -->
<record id="action_proxmox_vm" model="ir.actions.act_window">
<field name="name">Virtual Machines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">proxmox.vm</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_proxmox_vm_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No virtual machines found!
</p>
<p>
Virtual machines will be synchronized from your Proxmox servers.
</p>
</field>
</record>
</data>
</odoo>

View file

@ -0,0 +1 @@
from . import proxmox_server_wizard

View file

@ -0,0 +1,98 @@
from odoo import api, fields, models
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class ProxmoxServerWizard(models.TransientModel):
_name = 'proxmox.server.wizard'
_description = 'Assistant de configuration serveur Proxmox'
name = fields.Char(string='Nom', required=True)
hostname = fields.Char(string='Nom d\'hôte/IP', required=True)
port = fields.Integer(string='Port', default=443)
username = fields.Char(string='Nom d\'utilisateur', required=True)
password = fields.Char(string='Mot de passe', required=True)
verify_ssl = fields.Boolean(string='Vérifier SSL', default=False)
def _get_proxmox_connection(self):
"""Établit une connexion à l'API Proxmox"""
base_url = f"https://{self.hostname}:{self.port}/api2/json"
try:
auth_response = requests.post(
f"{base_url}/access/ticket",
verify=self.verify_ssl,
data={
"username": self.username,
"password": self.password
}
)
auth_response.raise_for_status()
auth_data = auth_response.json()['data']
headers = {
'CSRFPreventionToken': auth_data['CSRFPreventionToken'],
'Cookie': f"PVEAuthCookie={auth_data['ticket']}"
}
return base_url, headers
except Exception as e:
raise ValueError(f"Erreur de connexion: {str(e)}")
def action_test_connection(self):
"""Teste la connexion et crée le serveur et le cluster si la connexion réussit"""
try:
base_url, headers = self._get_proxmox_connection()
# Vérifier si c'est un cluster
cluster_response = requests.get(
f"{base_url}/cluster/status",
headers=headers,
verify=self.verify_ssl
)
cluster_response.raise_for_status()
cluster_data = cluster_response.json()['data']
is_cluster = any(node['type'] == 'cluster' for node in cluster_data)
cluster = False
if is_cluster:
cluster_name = next((node['name'] for node in cluster_data if node['type'] == 'cluster'), 'Cluster Proxmox')
cluster = self.env['proxmox.cluster'].create({
'name': cluster_name,
})
# Créer le serveur principal
main_server = self.env['proxmox.server'].create({
'name': self.name,
'hostname': self.hostname,
'port': self.port,
'username': self.username,
'password': self.password,
'cluster_id': cluster.id if cluster else False,
})
# Créer les autres nœuds si c'est un cluster
if is_cluster:
nodes = [node for node in cluster_data if node['type'] == 'node' and node['name'] != self.hostname]
for node in nodes:
self.env['proxmox.server'].create({
'name': node['name'],
'hostname': node['name'],
'port': self.port,
'username': self.username,
'password': self.password,
'cluster_id': cluster.id,
})
return {
'type': 'ir.actions.act_window',
'res_model': 'proxmox.server',
'res_id': main_server.id,
'view_mode': 'form',
'view_type': 'form',
'views': [(False, 'form')],
'target': 'current',
'flags': {'mode': 'readonly'},
}
except Exception as e:
raise ValueError(f"Erreur lors du test de connexion: {str(e)}")

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_proxmox_server_wizard_form" model="ir.ui.view">
<field name="name">proxmox.server.wizard.form</field>
<field name="model">proxmox.server.wizard</field>
<field name="arch" type="xml">
<form string="Configuration Serveur Proxmox">
<header>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group states="connect">
<group>
<field name="name" placeholder="Ex: Proxmox-1"/>
<field name="hostname" placeholder="Ex: proxmox.example.com"/>
<field name="port"/>
</group>
<group>
<field name="username" placeholder="Ex: root@pam"/>
<field name="password" password="True"/>
<field name="verify_ssl"/>
</group>
</group>
<group states="config" attrs="{'invisible': [('state', '!=', 'config')]}">
<group>
<field name="is_cluster"/>
<field name="cluster_name" attrs="{'invisible': [('is_cluster', '=', False)], 'required': [('is_cluster', '=', True)]}"/>
</group>
<group attrs="{'invisible': [('is_cluster', '=', False)]}">
<field name="other_nodes" nolabel="1" colspan="2">
<tree editable="bottom">
<field name="name"/>
<field name="hostname"/>
<field name="port"/>
<field name="username"/>
<field name="password" password="True"/>
</tree>
</field>
</group>
</group>
</sheet>
<footer>
<button name="action_test_connection" string="Tester la connexion" type="object"
class="btn-primary" states="connect"/>
<button name="action_create_server" string="Créer" type="object"
class="btn-primary" states="config"/>
<button string="Annuler" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_proxmox_server_wizard" model="ir.actions.act_window">
<field name="name">Ajouter un serveur Proxmox</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">proxmox.server.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem id="menu_proxmox_server_wizard"
name="Ajouter un serveur"
action="action_proxmox_server_wizard"
parent="menu_proxmox_server_root"
sequence="10"/>
</odoo>