Roberto pineda 6 ay önce
ebeveyn
işleme
4c4f7a5bdf

+ 54 - 7
sale_template_contract/models/sale_order_template.py

@@ -109,6 +109,18 @@ class SaleOrderTemplate(models.Model):
             if rec.date_start and rec.date_end and rec.date_end <= rec.date_start:
                 raise ValidationError(_('La fecha de fin debe ser mayor a la fecha de inicio.'))
 
+    @api.constrains('company_id', 'sale_order_template_line_ids', 'sale_order_template_option_ids')
+    def _check_company_id(self):
+        """
+        Sobrescribe la validación del modelo padre para deshabilitarla cuando use_contract_partner está habilitado.
+        """
+        # Filtrar solo los registros que NO tienen use_contract_partner habilitado
+        templates_to_validate = self.filtered(lambda t: not t.use_contract_partner)
+        
+        # Llamar al método padre solo para los registros que necesitan validación
+        if templates_to_validate:
+            super(SaleOrderTemplate, templates_to_validate)._check_company_id()
+
     @api.constrains('sale_order_template_line_ids')
     def _check_employee_required_for_duplicate_partner_project(self):
         for rec in self:
@@ -270,15 +282,22 @@ class SaleOrderTemplate(models.Model):
                 line.product_uom_qty for line in self.sale_order_template_line_ids
                 if line.project_id and line.project_id.id == project.id and hasattr(line, 'product_uom_qty')
             )
+            
+            # Determinar el nombre del proyecto
+            project_name = project.name
+            if self.opportunity_id and self.opportunity_id.name:
+                # Si hay oportunidad, usar su nombre para el proyecto
+                project_name = self.opportunity_id.name
+            
             # Buscar si ya existe un proyecto mensual para este pedido y mes
             domain = [
-                ('name', '=', f"{project.name} - {order_datetime.strftime('%Y-%m')}")
+                ('name', '=', f"{project_name} - {order_datetime.strftime('%Y-%m')}")
             ]
             if sale_order:
                 domain.append(('reinvoiced_sale_order_id', '=', sale_order.id))
             project_copy = self.env['project.project'].search(domain, limit=1)
             vals = {
-                'name': f"{project.name} - {order_datetime.strftime('%Y-%m')}",
+                'name': f"{project_name} - {order_datetime.strftime('%Y-%m')}",
                 'date_start': date_start,
                 'date': date_end,
                 'allocated_hours': allocated_hours,
@@ -289,6 +308,7 @@ class SaleOrderTemplate(models.Model):
             first_line = next((l for l in self.sale_order_template_line_ids if l.project_id and l.project_id.id == project.id and l.contract_partner_id), None)
             if first_line:
                 vals['allow_billable'] = True
+                # Usar siempre el contract_partner_id para proyectos
                 vals['partner_id'] = self.contract_partner_id.id
                 # No asignar account_id aquí, se generará automáticamente al crear el proyecto
             if sale_order:
@@ -300,6 +320,7 @@ class SaleOrderTemplate(models.Model):
                 project_copy.write({'sale_line_id': False})
                 # Actualizar el partner de la cuenta analítica después de crear el proyecto
                 if project_copy.account_id and first_line:
+                    # Usar siempre el contract_partner_id para cuentas analíticas
                     self._update_analytic_account_partner(project_copy.account_id, first_line.contract_partner_id.id)
             else:
                 # Actualizar el proyecto mensual existente con los valores actuales de la plantilla
@@ -307,6 +328,7 @@ class SaleOrderTemplate(models.Model):
                 project_copy.write({'sale_line_id': False})
                 # Actualizar el partner de la cuenta analítica
                 if project_copy.account_id and first_line:
+                    # Usar siempre el contract_partner_id para cuentas analíticas
                     self._update_analytic_account_partner(project_copy.account_id, first_line.contract_partner_id.id)
             project_map[project.id] = project_copy
         return project_map
@@ -324,9 +346,15 @@ class SaleOrderTemplate(models.Model):
             project_map = {}
             unique_projects = {line.project_id for line in self.sale_order_template_line_ids if line.project_id}
             for project in unique_projects:
+                # Determinar el nombre del proyecto
+                project_name = project.name
+                if self.opportunity_id and self.opportunity_id.name:
+                    # Si hay oportunidad, usar su nombre para el proyecto
+                    project_name = self.opportunity_id.name
+                
                 # Buscar si ya existe una copia para este pedido, nombre y fechas
                 domain = [
-                    ('name', '=', project.name),
+                    ('name', '=', project_name),
                     ('date_start', '=', self.date_start),
                     ('date', '=', self.date_end),
                 ]
@@ -334,7 +362,7 @@ class SaleOrderTemplate(models.Model):
                     domain.append(('reinvoiced_sale_order_id', '=', sale_order.id))
                 project_copy = self.env['project.project'].search(domain, limit=1)
                 vals = {
-                    'name': project.name,
+                    'name': project_name,
                     'date_start': self.date_start,
                     'date': self.date_end,
                     'sale_line_id': False
@@ -343,6 +371,7 @@ class SaleOrderTemplate(models.Model):
                 first_line = next((l for l in self.sale_order_template_line_ids if l.project_id and l.project_id.id == project.id and l.contract_partner_id), None)
                 if first_line:
                     vals['allow_billable'] = True
+                    # Usar siempre el contract_partner_id para proyectos
                     vals['partner_id'] = self.contract_partner_id.id
                     # No asignar account_id aquí, se generará automáticamente al crear el proyecto
                 if sale_order:
@@ -353,12 +382,14 @@ class SaleOrderTemplate(models.Model):
                     project_copy.write({'sale_line_id': False})
                     # Actualizar el partner de la cuenta analítica después de crear el proyecto
                     if project_copy.account_id and first_line:
+                        # Usar siempre el contract_partner_id para cuentas analíticas
                         self._update_analytic_account_partner(project_copy.account_id, first_line.contract_partner_id.id)
                 else:
                     project_copy.write(vals)
                     project_copy.write({'sale_line_id': False})
                     # Actualizar el partner de la cuenta analítica
                     if project_copy.account_id and first_line:
+                        # Usar siempre el contract_partner_id para cuentas analíticas
                         self._update_analytic_account_partner(project_copy.account_id, first_line.contract_partner_id.id)
                 project_map[project.id] = project_copy
             return project_map
@@ -401,6 +432,7 @@ class SaleOrderTemplate(models.Model):
             # Buscar un pedido existente para este partner, plantilla y mes/año.
             # Usar sale_order_template_id es clave para identificar unívocamente el pedido
             # y evitar duplicados, sin importar el estado del pedido.
+            # Usar siempre el contract_partner_id para búsqueda de pedidos existentes
             domain = [
                 ('partner_id', '=', self.contract_partner_id.id),
                 ('sale_order_template_id', '=', self.id),
@@ -532,15 +564,24 @@ class SaleOrderTemplate(models.Model):
                     update_vals['payment_term_id'] = self.payment_term_id.id
                 if self.opportunity_id and existing_order.opportunity_id != self.opportunity_id:
                     update_vals['opportunity_id'] = self.opportunity_id.id
+                
+                # Actualizar el vendedor si hay oportunidad
+                if self.opportunity_id and self.opportunity_id.user_id:
+                    user_id = self.opportunity_id.user_id.id
+                    if existing_order.user_id.id != user_id:
+                        update_vals['user_id'] = user_id
+                
                 existing_order.write(update_vals)
 
                 # Procesar orden y proyectos
                 self._process_order_and_projects(existing_order, project_map)
             else:
                 # Crear nuevo pedido
-                pricelist = self.contract_partner_id.property_product_pricelist
+                # Usar siempre el contract_partner_id para el cliente del pedido
+                partner = self.contract_partner_id
+                pricelist = partner.property_product_pricelist
                 # Priorizar término de pago de la plantilla, si no, el del partner
-                payment_term = self.payment_term_id or self.contract_partner_id.property_payment_term_id
+                payment_term = self.payment_term_id or partner.property_payment_term_id
                 
                 # Configurar proyectos antes de crear líneas
                 for line in self.sale_order_template_line_ids:
@@ -560,14 +601,20 @@ class SaleOrderTemplate(models.Model):
                             vals['analytic_distribution'] = {project_month.account_id.id: 100}
                     order_lines_vals.append(vals)
 
+                # Determinar el vendedor: usar opportunity_id.user_id si existe
+                user_id = False
+                if self.opportunity_id and self.opportunity_id.user_id:
+                    user_id = self.opportunity_id.user_id.id
+                
                 order_vals = {
-                    'partner_id': self.contract_partner_id.id,
+                    'partner_id': partner.id,
                     'sale_order_template_id': self.id,
                     'date_order': order_datetime,
                     'pricelist_id': pricelist.id if pricelist else False,
                     'payment_term_id': payment_term.id if payment_term else False,
                     'company_id': (self.company_id or self.env.company).id,
                     'opportunity_id': self.opportunity_id.id if self.opportunity_id else False,
+                    'user_id': user_id,
                     'order_line': [Command.create(vals) for vals in order_lines_vals]
                 }
                 new_order = SaleOrder.create(order_vals)

+ 1 - 0
sale_template_contract/models/sale_order_template_line.py

@@ -49,6 +49,7 @@ class SaleOrderTemplateLine(models.Model):
         string='Proyecto',
         help="Proyecto plantilla asociado a esta línea de la plantilla de presupuesto.",
         #domain="[('company_id', '=', company_id), ('sale_order_template_project', '=', True)]"
+        domain="[('sale_order_template_project', '=', True)]"
     )
 
     def _prepare_order_line_values(self):