Browse Source

sale_template_contract update

Roberto pineda 6 months ago
parent
commit
de445553a0

+ 51 - 3
sale_template_contract/models/sale_order_template.py

@@ -13,14 +13,14 @@ class SaleOrderTemplate(models.Model):
     _inherit = 'sale.order.template'
 
     use_contract_partner = fields.Boolean(
-        string='Usar la plantilla para creación de órdenes recurrentes',
+        string='Creación de órdenes y proyectos',
         help=""
     )
 
     monthly_invoice_project = fields.Boolean(
-        string='Generar ventas y proyectos mensuales',
+        string='Generar órdenes y proyectos mensuales',
         default=True,
-        help=""
+        help="No puede cambiarse si ya hay órdenes generadas"
     )
 
     contract_partner_id = fields.Many2one(
@@ -36,6 +36,13 @@ class SaleOrderTemplate(models.Model):
         help="Términos de pago que se aplicarán a los pedidos generados desde esta plantilla."
     )
 
+    opportunity_id = fields.Many2one(
+        'crm.lead',
+        string='Oportunidad',
+        domain="[('type', '=', 'opportunity')]",
+        help="Oportunidad opcional que se asignará a los pedidos generados desde esta plantilla."
+    )
+
     date_start = fields.Date(
         string='Fecha de Inicio del Contrato',
         help="Fecha de inicio para el rango del contrato de esta plantilla."
@@ -203,6 +210,24 @@ class SaleOrderTemplate(models.Model):
                 ptr_date = ptr_date.replace(day=1)
         return order_dates
 
+
+
+    def _update_analytic_account_partner(self, original_account, partner_id):
+        """
+        Actualiza el partner de una cuenta analítica existente.
+        Si la cuenta analítica ya tiene el partner correcto, no hace nada.
+        """
+        if not original_account:
+            return original_account
+            
+        # Si la cuenta analítica ya tiene el partner correcto, no hacer nada
+        if original_account.partner_id.id == partner_id:
+            return original_account
+        
+        # Actualizar el partner de la cuenta analítica existente
+        original_account.write({'partner_id': partner_id})
+        return original_account
+
     def _configure_project_for_contract(self, template_line):
         """
         Configura un proyecto para ser billable y asignar el contract_partner_id
@@ -218,6 +243,12 @@ class SaleOrderTemplate(models.Model):
             if template_line.project_id.partner_id != self.contract_partner_id:
                 project_updates['partner_id'] = self.contract_partner_id.id
             
+            # Asignar partner de la cuenta analítica del proyecto
+            if template_line.project_id.account_id and template_line.project_id.account_id.partner_id != template_line.contract_partner_id:
+                project_updates['account_id'] = template_line.project_id.account_id.id
+                # Actualizar el partner de la cuenta analítica
+                template_line.project_id.account_id = self._update_analytic_account_partner(template_line.project_id.account_id, template_line.contract_partner_id.id)
+            
             # Actualizar proyecto si hay cambios
             if project_updates:
                 template_line.project_id.write(project_updates)
@@ -259,6 +290,7 @@ class SaleOrderTemplate(models.Model):
             if first_line:
                 vals['allow_billable'] = True
                 vals['partner_id'] = self.contract_partner_id.id
+                # No asignar account_id aquí, se generará automáticamente al crear el proyecto
             if sale_order:
                 vals['reinvoiced_sale_order_id'] = sale_order.id
                 vals['sale_line_id'] = False
@@ -266,10 +298,16 @@ class SaleOrderTemplate(models.Model):
                 # Copiar el proyecto original
                 project_copy = project.copy(vals)
                 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:
+                    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
                 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:
+                    self._update_analytic_account_partner(project_copy.account_id, first_line.contract_partner_id.id)
             project_map[project.id] = project_copy
         return project_map
 
@@ -306,15 +344,22 @@ class SaleOrderTemplate(models.Model):
                 if first_line:
                     vals['allow_billable'] = True
                     vals['partner_id'] = self.contract_partner_id.id
+                    # No asignar account_id aquí, se generará automáticamente al crear el proyecto
                 if sale_order:
                     vals['reinvoiced_sale_order_id'] = sale_order.id
                     vals['sale_line_id'] = False
                 if not project_copy:
                     project_copy = project.copy(vals)
                     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:
+                        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:
+                        self._update_analytic_account_partner(project_copy.account_id, first_line.contract_partner_id.id)
                 project_map[project.id] = project_copy
             return project_map
 
@@ -485,6 +530,8 @@ class SaleOrderTemplate(models.Model):
                 update_vals = {'date_order': order_datetime}
                 if self.payment_term_id and existing_order.payment_term_id != self.payment_term_id:
                     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
                 existing_order.write(update_vals)
 
                 # Procesar orden y proyectos
@@ -520,6 +567,7 @@ class SaleOrderTemplate(models.Model):
                     '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,
                     'order_line': [Command.create(vals) for vals in order_lines_vals]
                 }
                 new_order = SaleOrder.create(order_vals)

+ 4 - 4
sale_template_contract/models/sale_order_template_line.py

@@ -19,7 +19,7 @@ class SaleOrderTemplateLine(models.Model):
     # El dominio permite productos globales (sin compañía) o de la compañía de la plantilla.
     # Mantenemos ('sale_ok', '=', True) para mostrar solo productos vendibles.
     product_id = fields.Many2one(
-        domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
+        #domain="[('sale_ok', '=', True), '|', ('company_id', '=', False), ('company_id', '=', company_id)]"
     )
 
     # Este dominio es más flexible, permitiendo clientes globales o de la misma compañía.
@@ -27,7 +27,7 @@ class SaleOrderTemplateLine(models.Model):
         'res.partner',
         string='Cliente final',
         help="Partner asociado a esta línea de la plantilla de presupuesto.",
-        domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]"
+        #domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]"
     )
 
     # Los empleados y proyectos suelen ser específicos de una compañía.
@@ -35,7 +35,7 @@ class SaleOrderTemplateLine(models.Model):
         'hr.employee',
         string='Empleado',
         help="Empleado opcional asociado a esta línea de la plantilla de presupuesto.",
-        domain="[('company_id', '=', company_id)]"
+        #domain="[('company_id', '=', company_id)]"
     )
 
     price_unit = fields.Float(
@@ -48,7 +48,7 @@ class SaleOrderTemplateLine(models.Model):
         'project.project',
         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="[('company_id', '=', company_id), ('sale_order_template_project', '=', True)]"
     )
 
     def _prepare_order_line_values(self):

+ 2 - 1
sale_template_contract/views/sale_order_template_views.xml

@@ -10,7 +10,7 @@
                 <xpath expr="//div[@name='button_box']" position="inside">
                     <button name="action_generate_contract_orders"
                             type="object"
-                            string="Generar/Actualizar Pedidos de Contrato"
+                            string="Generar/Actualizar Pedidos y proyectos"
                             class="oe_highlight"
                             invisible="not use_contract_partner or not contract_partner_id or not date_start or not date_end or not sale_order_template_line_ids"/>
                 </xpath>
@@ -23,6 +23,7 @@
                            invisible="not use_contract_partner"/>
                     <field name="monthly_invoice_project" invisible="not use_contract_partner" required="use_contract_partner" readonly="has_contract_orders"/>
                     <field name="payment_term_id" invisible="not use_contract_partner" required="use_contract_partner"/>
+                    <field name="opportunity_id" invisible="not use_contract_partner" options="{'no_create': True, 'no_open': False}"/>
                     <field name="date_start" invisible="not use_contract_partner" required="use_contract_partner"/>
                     <field name="date_end" invisible="not use_contract_partner" required="use_contract_partner"/>
                 </xpath>