From 348fb6cb05b6018e79bcc498dda3fe5b1b30d970 Mon Sep 17 00:00:00 2001 From: xtremxpert Date: Thu, 6 Mar 2025 11:39:23 -0500 Subject: [PATCH] replace invoiving user --- replace_invoicing_user/__manifest__.py | 9 +- replace_invoicing_user/models/__init__.py | 1 + replace_invoicing_user/models/account_move.py | 82 +++++++++++++++++++ .../models/res_config_settings.py | 30 ++++++- .../views/res_config_settings_views.xml | 6 +- .../wizard/sale_make_invoice_advance.py | 17 ++++ replace_invoicing_user/wizard/sale_order.py | 19 ++++- 7 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 replace_invoicing_user/models/account_move.py diff --git a/replace_invoicing_user/__manifest__.py b/replace_invoicing_user/__manifest__.py index d07f703..b44fc4f 100644 --- a/replace_invoicing_user/__manifest__.py +++ b/replace_invoicing_user/__manifest__.py @@ -17,14 +17,17 @@ # DEALINGS IN THE SOFTWARE. # { - 'name': 'Current User as Invoice User', + 'name': 'Replace invoicing user', 'version': '18.0.1.0.0', - 'summary': 'Instead of the salesperson, use the currently logged in user as the responsible user on invoice.', + 'summary': 'Instead of the salesperson, use the currently logged in user or a specific user as the responsible user on invoice.', 'category': 'Accounting', 'author': 'Bemade Inc.', 'website': 'http://www.bemade.org', 'license': 'OPL-1', - 'depends': ['sale', 'account'], + 'depends': [ + 'sale', + 'account' + ], 'data': [ 'views/res_config_settings_views.xml', ], diff --git a/replace_invoicing_user/models/__init__.py b/replace_invoicing_user/models/__init__.py index 0deb68c..123c3f2 100644 --- a/replace_invoicing_user/models/__init__.py +++ b/replace_invoicing_user/models/__init__.py @@ -1 +1,2 @@ from . import res_config_settings +from . import account_move diff --git a/replace_invoicing_user/models/account_move.py b/replace_invoicing_user/models/account_move.py new file mode 100644 index 0000000..23e9b76 --- /dev/null +++ b/replace_invoicing_user/models/account_move.py @@ -0,0 +1,82 @@ +from odoo import models, api, _ +from odoo.tools import float_compare + + +class AccountMove(models.Model): + _inherit = 'account.move' + + def _get_mail_thread_data_for_subtype(self, subtype_id): + # Surcharge de la méthode qui contrôle l'ajout des followers + # Si no_follower_tracking est activé, on empêche l'ajout du follower par défaut + if self.env.context.get('no_follower_tracking'): + return [] + return super()._get_mail_thread_data_for_subtype(subtype_id) + + def message_subscribe(self, partner_ids=None, subtype_ids=None, email=True): + # Empêcher l'ajout automatique de followers pour les factures si no_follower_tracking est activé + if self._name == 'account.move' and self.env.context.get('no_follower_tracking'): + # On ne permet l'ajout que de l'utilisateur spécifique + specific_user_id = self.env.context.get('specific_invoice_user_id') or int(self.env['ir.config_parameter'].sudo().get_param( + 'current_user_as_invoice_user.specific_user_id', '0' + )) + if specific_user_id: + specific_user = self.env['res.users'].browse(specific_user_id) + if specific_user.exists() and specific_user.partner_id: + # On filtre pour ne garder que l'utilisateur spécifique dans les partner_ids + partner_ids = [pid for pid in partner_ids if pid == specific_user.partner_id.id] if partner_ids else [] + # Si vide, on ne fait rien + if not partner_ids: + return True + else: + # Aucun utilisateur spécifique, on empêche l'ajout de followers + return True + return super().message_subscribe(partner_ids=partner_ids, subtype_ids=subtype_ids, email=email) + + @api.model_create_multi + def create(self, vals_list): + # Modélisation des vals_list pour empêcher l'ajout des followers par défaut + if self.env.context.get('no_follower_tracking'): + for vals in vals_list: + # Désactiver l'ajout automatique des followers lors de la création + vals['message_follower_ids'] = [] + + # Créer les factures normalement avec le contexte approprié + # Le contexte no_follower_tracking désactive l'ajout automatique du current_user via _get_mail_thread_data_for_subtype + moves = super().create(vals_list) + + # Vérifier si on doit configurer des followers spécifiques + if self.env.context.get('no_follower_tracking'): + # Utiliser specific_invoice_user_id du contexte s'il existe, sinon lire depuis les paramètres + specific_user_id = self.env.context.get('specific_invoice_user_id') or int(self.env['ir.config_parameter'].sudo().get_param( + 'current_user_as_invoice_user.specific_user_id', '0' + )) + + # Récupérer l'utilisateur spécifique + specific_user = None + if specific_user_id: + specific_user = self.env['res.users'].browse(specific_user_id) + + # Utiliser l'environnement superuser pour éviter les problèmes de droits + # et traiter tous les moves d'un coup + moves_sudo = moves.sudo() + + # D'abord, supprimer tous les followers pour tous les moves + follower_model = self.env['mail.followers'].sudo() + domain = [ + ('res_model', '=', 'account.move'), + ('res_id', 'in', moves.ids) + ] + followers = follower_model.search(domain) + if followers: + followers.unlink() + + # Ensuite, ajouter l'utilisateur spécifique comme seul follower si nécessaire + if specific_user and specific_user.exists() and specific_user.partner_id: + for move in moves_sudo: + follower_model.create({ + 'partner_id': specific_user.partner_id.id, + 'res_model': 'account.move', + 'res_id': move.id + }) + + return moves diff --git a/replace_invoicing_user/models/res_config_settings.py b/replace_invoicing_user/models/res_config_settings.py index 8b2bd28..1c98982 100644 --- a/replace_invoicing_user/models/res_config_settings.py +++ b/replace_invoicing_user/models/res_config_settings.py @@ -1,4 +1,4 @@ -from odoo import fields, models +from odoo import api, fields, models class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' @@ -10,9 +10,33 @@ class ResConfigSettings(models.TransientModel): default=True, help='If checked, the current user will be set as the invoice user. Otherwise, a specific user will be used.' ) + specific_invoice_user_id = fields.Many2one( - 'res.users', + comodel_name='res.users', string='Specific Invoice User', config_parameter='current_user_as_invoice_user.specific_user_id', - help='User to be set as invoice user when not using current user' + help='User to be set as invoice user when not using current user', + depends=['use_current_user'] ) + + @api.model + def get_values(self): + res = super(ResConfigSettings, self).get_values() + ICP = self.env['ir.config_parameter'].sudo() + use_current_user = ICP.get_param('current_user_as_invoice_user.use_current_user', 'True') + res.update({ + 'use_current_user': use_current_user == 'True', + }) + if specific_user_id := ICP.get_param('current_user_as_invoice_user.specific_user_id'): + res.update({ + 'specific_invoice_user_id': int(specific_user_id), + }) + return res + + def set_values(self): + super(ResConfigSettings, self).set_values() + ICP = self.env['ir.config_parameter'].sudo() + ICP.set_param('current_user_as_invoice_user.use_current_user', str(self.use_current_user)) + if self.specific_invoice_user_id: + ICP.set_param('current_user_as_invoice_user.specific_user_id', str(self.specific_invoice_user_id.id)) + diff --git a/replace_invoicing_user/views/res_config_settings_views.xml b/replace_invoicing_user/views/res_config_settings_views.xml index e9fbb24..1065f6d 100644 --- a/replace_invoicing_user/views/res_config_settings_views.xml +++ b/replace_invoicing_user/views/res_config_settings_views.xml @@ -5,7 +5,7 @@ res.config.settings - +
@@ -15,8 +15,8 @@
Choose between using current user or specific user as invoice user
-
-
+
+
diff --git a/replace_invoicing_user/wizard/sale_make_invoice_advance.py b/replace_invoicing_user/wizard/sale_make_invoice_advance.py index 0577e07..96105c7 100644 --- a/replace_invoicing_user/wizard/sale_make_invoice_advance.py +++ b/replace_invoicing_user/wizard/sale_make_invoice_advance.py @@ -21,9 +21,26 @@ class SaleMakeInvoiceAdvance(models.TransientModel): user_id = self.env.user.id else: user_id = specific_user_id if specific_user_id else self.env.user.id + # Ne pas tracker les followers si on n'utilise pas l'utilisateur courant + # Cette valeur sera lue depuis le contexte par le modèle account.move + self = self.with_context(no_follower_tracking=True, specific_invoice_user_id=specific_user_id) invoice_vals.update({ 'invoice_user_id': user_id, 'user_id': user_id, }) return invoice_vals + + def _create_invoices(self, sale_orders): + # Si on utilise un utilisateur spécifique, il faut aussi passer le contexte ici + use_current_user = self.env['ir.config_parameter'].sudo().get_param( + 'current_user_as_invoice_user.use_current_user', 'True' + ).lower() == 'true' + + if not use_current_user: + specific_user_id = int(self.env['ir.config_parameter'].sudo().get_param( + 'current_user_as_invoice_user.specific_user_id', '0' + )) + self = self.with_context(no_follower_tracking=True, specific_invoice_user_id=specific_user_id) + + return super()._create_invoices(sale_orders) diff --git a/replace_invoicing_user/wizard/sale_order.py b/replace_invoicing_user/wizard/sale_order.py index c1d16e2..f3b962b 100644 --- a/replace_invoicing_user/wizard/sale_order.py +++ b/replace_invoicing_user/wizard/sale_order.py @@ -21,9 +21,26 @@ class SaleOrder(models.Model): user_id = self.env.user.id else: user_id = specific_user_id if specific_user_id else self.env.user.id + # Ne pas tracker les followers si on n'utilise pas l'utilisateur courant + # Cette valeur sera lue depuis le contexte par le modèle account.move + self = self.with_context(no_follower_tracking=True, specific_invoice_user_id=specific_user_id) invoice_vals.update({ 'invoice_user_id': user_id, 'user_id': user_id, }) - return invoice_vals \ No newline at end of file + return invoice_vals + + def _create_invoices(self, grouped=False, final=False, date=None): + # Si on utilise un utilisateur spécifique, il faut aussi passer le contexte ici + use_current_user = self.env['ir.config_parameter'].sudo().get_param( + 'current_user_as_invoice_user.use_current_user', 'True' + ).lower() == 'true' + + if not use_current_user: + specific_user_id = int(self.env['ir.config_parameter'].sudo().get_param( + 'current_user_as_invoice_user.specific_user_id', '0' + )) + self = self.with_context(no_follower_tracking=True, specific_invoice_user_id=specific_user_id) + + return super()._create_invoices(grouped=grouped, final=final, date=date) \ No newline at end of file