from odoo import models, fields, api, _ from odoo.exceptions import ValidationError, UserError class CrmLead(models.Model): _inherit = 'crm.lead' addetto_acquisti = fields.Many2one( 'res.users', string='Addetto acquisti' ) addetto_acquisti_2 = fields.Many2one( 'res.users', string='Addetto acquisti 2' ) addetto_vendite_2 = fields.Many2one( 'res.users', string='Addetto vendite 2' ) def action_set_stage_wishlist_verificata(self): self.ensure_one() # Assicura che il metodo sia chiamato su un singolo record, tipico per un click da form. # Trova lo stadio di destinazione "Wishlist verificata" # Per maggiore robustezza, se conosci l'XML ID dello stadio, usa: # target_stage = self.env.ref('nome_tuo_modulo.xml_id_dello_stadio_wishlist_verificata', raise_if_not_found=False) target_stage = self.env['crm.stage'].search([('name', '=', 'Wishlist verificata')], limit=1) if not target_stage: raise UserError(_("Lo stadio 'Wishlist verificata' non è stato trovato. Assicurati che esista.")) # Verifica se l'opportunità è effettivamente nello stadio "Nuova" prima di cambiarlo # (questa è una doppia verifica, dato che l'XML dovrebbe già nascondere il bottone) if self.stage_id.name == 'Nuova': if self.stage_id.id == target_stage.id: # Già nello stadio desiderato (improbabile se il bottone è visibile solo in "Nuova") return True self.write({'stage_id': target_stage.id}) else: # Questo messaggio potrebbe apparire se la condizione 'invisible' nell'XML non fosse perfetta # o se il metodo fosse chiamato da un'altra parte. raise UserError(_("L'opportunità deve essere nello stadio 'Nuova' per poterla inviare a 'Wishlist verificata'.")) # --- Invio email agli addetti acquisti --- emails = [] if self.addetto_acquisti and self.addetto_acquisti.partner_id.email: emails.append(self.addetto_acquisti.partner_id.email) if self.addetto_acquisti_2 and self.addetto_acquisti_2.partner_id.email: emails.append(self.addetto_acquisti_2.partner_id.email) if not emails: return True # Nessun destinatario, esci silenziosamente base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') opportunity_url = f"{base_url}/web#id={self.id}&model=crm.lead&view_type=form&page=wishlist_cliente" button_html = f'Apri wishlist cliente' body_html = f""" Gentile Ufficio acquisti,

è stata verificata la wishlist presente nella seguente opportunità:

Nome cliente: {self.partner_id.name}
Nome opportunità: {self.name}

{button_html} """ mail_values = { 'subject': f"Wishlist verificata - {self.name}", 'body_html': body_html, 'email_to': ','.join(emails), 'auto_delete': True, 'model': 'crm.lead', 'res_id': self.id, } self.env['mail.mail'].sudo().create(mail_values).send() return True verifica_target = fields.Selection([ ('yes', 'Sì'), ('no', 'No') ], string="Verificato target ITA/EEUU") motivo_verifica_negata = fields.Text(string="Motivo mancata verifica") percent_provvigioni = fields.Float( string="% Provvigioni", digits=(5, 2), help="Inserisci la percentuale" ) agente_id = fields.Many2one( 'res.partner', string="Agente", domain="[('is_company', '=', False)]", help="Seleziona l'agente di riferimento") @api.onchange('partner_id') def _onchange_partner_id_set_agente(self): if self.partner_id: if self.partner_id.agente_id: self.agente_id = self.partner_id.agente_id self.percent_provvigioni = self.partner_id.percent_provvigioni @api.model_create_multi def create(self, vals_list): for vals in vals_list: if vals.get('partner_id'): partner = self.env['res.partner'].browse(vals['partner_id']) if not vals.get('agente_id') and partner.agente_id: vals['agente_id'] = partner.agente_id.id if not vals.get('percent_provvigioni'): vals['percent_provvigioni'] = partner.percent_provvigioni return super(CrmLead, self).create(vals_list) # Campi per la Richiesta Offerta fornitore_id = fields.Many2one('res.partner', string="Fornitore") buyer = fields.Char(string="Buyer") prodotti_richiesti = fields.Text(string="Prodotti Richiesti") minimo_ordine = fields.Char(string="Minimo Ordine") # Modifica del campo categoria_ids (Many2many) categoria_ids = fields.Many2many( 'crm.wishlist.categoria', string="Categorie" ) sottocategoria_ids = fields.Many2many( 'crm.wishlist.sottocategoria', string="Sottocategorie", domain="[('categoria_id', 'in', categoria_ids)]" ) stagione = fields.Selection([ ('close_out', 'Close Out'), ('attuale', 'Attuale'), ('preordine', 'Pre-ordine'), ], string="Stagione") budget = fields.Monetary(string="Budget", currency_field='currency_id') currency_id = fields.Many2one('res.currency', string='Valuta', default=lambda self: self.env.company.currency_id.id) tipo_richiesta = fields.Selection([ ('quotazione', 'Quotazione'), ('generica', 'Generica'), ], string="Tipo Richiesta") brand = fields.Char(string="Brand") target = fields.Char(string="Target") genere_ids = fields.Many2many( 'crm.lead.genere', # Riferimento al nuovo modello string="Genere" ) note = fields.Text(string="Note") shelf_life = fields.Char(string="Shelf life") allegato_ids = fields.Many2many('ir.attachment', string="Allegati") # Computazione del completamento della wishlist wishlist_complete_percent = fields.Float( string="Completamento Wishlist (%)", compute="_compute_wishlist_complete_percent", store=True ) @api.depends( 'categoria_ids', 'sottocategoria_ids', 'stagione', 'budget', 'tipo_richiesta', 'brand', 'target', 'genere_ids', 'verifica_target', ) def _compute_wishlist_complete_percent(self): for lead in self: fields_to_check = [ 'categoria_ids', 'sottocategoria_ids', 'stagione', 'budget', 'tipo_richiesta', 'brand', 'target', 'genere_ids', 'verifica_target', ] total = len(fields_to_check) completed = 0 for field_name in fields_to_check: value = getattr(lead, field_name) if value: # Per i Many2many, questo verifica se la relazione non è vuota completed += 1 lead.wishlist_complete_percent = round((completed / total) * 100.0, 2) if total else 0.0 @api.onchange('tipo_richiesta') def _onchange_tipo_richiesta(self): if self.tipo_richiesta == 'quotazione': self.priority = '3' elif self.tipo_richiesta == 'generica': self.priority = '2' else: self.priority = '1' class WishlistCategoria(models.Model): _name = 'crm.wishlist.categoria' _description = 'Categoria Wishlist' name = fields.Char(string="Nome Categoria") class WishlistSottocategoria(models.Model): _name = 'crm.wishlist.sottocategoria' _description = 'Sottocategoria Wishlist' name = fields.Char(required=True) categoria_id = fields.Many2one( 'crm.wishlist.categoria', string='Categoria di appartenenza', required=True, ondelete='cascade', ) # Nuovo modello per le opzioni del Genere class CrmLeadGenere(models.Model): _name = 'crm.lead.genere' _description = 'Genere per Lead CRM' name = fields.Char(string="Nome Genere", required=True, translate=True)