diff --git a/odex25_takaful/odex_takaful/models/res_partner.py b/odex25_takaful/odex_takaful/models/res_partner.py index 6d41aba44..a0dc5b166 100644 --- a/odex25_takaful/odex_takaful/models/res_partner.py +++ b/odex25_takaful/odex_takaful/models/res_partner.py @@ -346,19 +346,31 @@ class ResPartner(models.Model): parent_record.sponsor_id = res.id + # OPTIMIZATION: Skip user creation during bulk import for performance + # The context 'import_file=True' is set by Odoo's base_import module. + # Many core modules (auth_signup, base_automation, etc.) use this pattern. + # Users can be created later via a separate action or scheduled job. + if self.env.context.get('import_file'): + return res + if 'is_sponsor_portal' in values or 'is_donor' in values: - if values['is_sponsor_portal'] == True or values['is_donor'] == True : - if res.mobile != False: - kafeel = self.env['res.users'].with_user(2).create({ - 'name' : values['name'], - 'branch_custom_id':values['branch_custom_id'], - 'sel_groups_1_9_10' : 9, - 'partner_id' : res.id, - 'login' : values['mobile'], - 'otp_mobile_phone' : values['mobile'], - 'otp_enabled' : True, - }) - res.kafel_id = kafeel + # Use .get() to safely check boolean values (handles case where only one key exists) + is_sponsor = values.get('is_sponsor_portal', False) + is_donor_val = values.get('is_donor', False) + if (is_sponsor == True or is_donor_val == True) and res.mobile: + # IMPORTANT: branch_custom_id is a RELATED field on res.users + # (related='partner_id.branch_custom_id') with store=False. + # It will be automatically computed from the partner_id. + # DO NOT pass it directly to create() - this causes unnecessary overhead. + kafeel = self.env['res.users'].with_user(2).create({ + 'name': res.name, + 'sel_groups_1_9_10': 9, + 'partner_id': res.id, + 'login': res.mobile, + 'otp_mobile_phone': res.mobile, + 'otp_enabled': True, + }) + res.kafel_id = kafeel return res @@ -375,14 +387,16 @@ class ResPartner(models.Model): self.kafel_id.login = vals['mobile'] if 'mobile' in vals and self.mobile == False: + # IMPORTANT: branch_custom_id is a RELATED field on res.users + # (related='partner_id.branch_custom_id') with store=False. + # It will be automatically computed from the partner_id. kafeel = self.env['res.users'].with_user(2).create({ - 'name' : self.name, - 'branch_custom_id':vals['branch_custom_id'] if 'branch_custom_id' in vals else self.branch_custom_id.id , - 'sel_groups_1_9_10' : 9, - 'partner_id' : self.id, - 'login' : vals['mobile'], - 'otp_mobile_phone' : vals['mobile'], - 'otp_enabled' : True, + 'name': self.name, + 'sel_groups_1_9_10': 9, + 'partner_id': self.id, + 'login': vals['mobile'], + 'otp_mobile_phone': vals['mobile'], + 'otp_enabled': True, }) self.kafel_id = kafeel @@ -418,6 +432,49 @@ class ResPartner(models.Model): self.user_id = user.id return self + def action_generate_users_for_imported_sponsors(self): + """ + Batch create users for imported sponsors that don't have kafel_id. + This should be called after bulk import to create portal users. + Can be triggered via a server action or manually. + """ + # Find sponsors without users that should have them + sponsors_without_users = self.search([ + ('is_sponsor_portal', '=', True), + ('kafel_id', '=', False), + ('mobile', '!=', False), + ]) + + created_count = 0 + for sponsor in sponsors_without_users: + try: + kafeel = self.env['res.users'].with_user(2).create({ + 'name': sponsor.name, + 'sel_groups_1_9_10': 9, + 'partner_id': sponsor.id, + 'login': sponsor.mobile, + 'otp_mobile_phone': sponsor.mobile, + 'otp_enabled': True, + }) + sponsor.kafel_id = kafeel + created_count += 1 + except Exception as e: + # Log error but continue with other sponsors + import logging + _logger = logging.getLogger(__name__) + _logger.warning(f"Failed to create user for sponsor {sponsor.id}: {e}") + + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': _('User Generation Complete'), + 'message': _('Created %s users for imported sponsors.') % created_count, + 'type': 'success', + 'sticky': False, + } + } + def action_open_sponsor_operation(self): """Open Operations History for a Sponsor"""