Browse Source

refactor(helpdesk_extras): Mejorar form builder para usar campos específicos del template

- Usar selection_type en lugar de widget para campos selection y many2one
- Usar rows del template_field para textarea (configurable, default 3)
- Usar input_type del template_field para campos de texto (configurable, default 'text')
- Eliminar soporte para checkbox en campos many2one (no es estándar)
- Eliminar módulos analytic_enterprise y web_enterprise del catálogo
- Alinear comportamiento con Odoo form builder estándar
odoo 2 tháng trước cách đây
mục cha
commit
749d7ee3c0

+ 0 - 12
helpdesk_extras/data/helpdesk_affected_module_data.xml

@@ -44,12 +44,6 @@
             <field name="is_main_application">true</field>
             <field name="active">True</field>
         </record>
-        <record id="helpdesk_extras.module_analytic_enterprise" model="helpdesk.affected.module">
-            <field name="code">analytic_enterprise</field>
-            <field name="name">Analytic Accounting Enterprise</field>
-            <field name="is_main_application">true</field>
-            <field name="active">True</field>
-        </record>
         <record id="helpdesk_extras.module_appointment" model="helpdesk.affected.module">
             <field name="code">appointment</field>
             <field name="name">Appointments</field>
@@ -604,12 +598,6 @@
             <field name="is_main_application">false</field>
             <field name="active">True</field>
         </record>
-        <record id="helpdesk_extras.module_web_enterprise" model="helpdesk.affected.module">
-            <field name="code">web_enterprise</field>
-            <field name="name">Web Enterprise</field>
-            <field name="is_main_application">false</field>
-            <field name="active">True</field>
-        </record>
         <record id="helpdesk_extras.module_web_gantt" model="helpdesk.affected.module">
             <field name="code">web_gantt</field>
             <field name="name">Web Gantt</field>

+ 13 - 52
helpdesk_extras/models/helpdesk_team.py

@@ -722,12 +722,13 @@ class HelpdeskTeamExtras(models.Model):
             if template_field.default_value and template_field.default_value.lower() in ('yes', '1', 'true'):
                 input_el.set('checked', 'checked')
         elif field_type in ('text', 'html'):
-            # Textarea - CORREGIDO: eliminar atributo type (no existe en textarea)
+            # Textarea - Use rows from template_field (default 3, same as Odoo formbuilder)
+            rows_value = str(template_field.rows) if template_field.rows else '3'
             input_el = etree.SubElement(input_div, 'textarea', {
                 'class': 'form-control s_website_form_input',
                 'name': field_name,
                 'id': field_id,
-                'rows': '3'
+                'rows': rows_value
             })
             if template_field.placeholder:
                 input_el.set('placeholder', template_field.placeholder)
@@ -769,13 +770,13 @@ class HelpdeskTeamExtras(models.Model):
                     _logger.warning(f"Invalid JSON in selection_options for field {field_name}: {template_field.selection_options}")
                     selection_options = None
             
-            # Determine widget type
-            widget_type = template_field.widget or 'default'
+            # Determine selection type (dropdown or radio) - same as Odoo formbuilder
+            selection_type = template_field.selection_type if template_field.selection_type else 'dropdown'
             
             # Check if this is a relation field (many2one stored as selection)
             is_relation = bool(field.relation)
             
-            if widget_type == 'radio' and not is_relation:
+            if selection_type == 'radio' and not is_relation:
                 # Radio buttons for selection (non-relation)
                 radio_wrapper = etree.SubElement(input_div, 'div', {
                     'class': 'row s_col_no_resize s_col_no_bgcolor s_website_form_multiple',
@@ -844,7 +845,7 @@ class HelpdeskTeamExtras(models.Model):
                     })
                     radio_label.text = option_label
                 input_el = radio_wrapper  # For consistency, but not used
-            elif widget_type == 'checkbox' and not is_relation:
+            elif template_field.widget == 'checkbox' and not is_relation:
                 # Checkboxes for selection (non-relation) - multiple selection
                 checkbox_wrapper = etree.SubElement(input_div, 'div', {
                     'class': 'row s_col_no_resize s_col_no_bgcolor s_website_form_multiple',
@@ -1025,10 +1026,10 @@ class HelpdeskTeamExtras(models.Model):
             if required:
                 input_el.set('required', '1')
         elif field_type == 'many2one':
-            # Determine widget type for many2one
-            widget_type = template_field.widget or 'default'
+            # Determine selection type (dropdown or radio) - same as Odoo formbuilder
+            selection_type = template_field.selection_type if template_field.selection_type else 'dropdown'
             
-            if widget_type == 'radio':
+            if selection_type == 'radio':
                 # Radio buttons for many2one
                 radio_wrapper = etree.SubElement(input_div, 'div', {
                     'class': 'row s_col_no_resize s_col_no_bgcolor s_website_form_multiple',
@@ -1069,47 +1070,6 @@ class HelpdeskTeamExtras(models.Model):
                     except Exception:
                         pass
                 input_el = radio_wrapper
-            elif widget_type == 'checkbox':
-                # Checkboxes for many2one (multiple selection - unusual but supported)
-                checkbox_wrapper = etree.SubElement(input_div, 'div', {
-                    'class': 'row s_col_no_resize s_col_no_bgcolor s_website_form_multiple',
-                    'data-name': field_name,
-                    'data-display': 'horizontal'
-                })
-                relation = field.relation
-                if relation and relation != 'ir.attachment':
-                    try:
-                        domain = self._get_relation_domain(relation, env)
-                        records = env[relation].sudo().search_read(
-                            domain, ['display_name'], limit=1000
-                        )
-                        default_values = template_field.default_value.split(',') if template_field.default_value else []
-                        for record in records:
-                            checkbox_div = etree.SubElement(checkbox_wrapper, 'div', {
-                                'class': 'checkbox col-12 col-lg-4 col-md-6'
-                            })
-                            form_check = etree.SubElement(checkbox_div, 'div', {
-                                'class': 'form-check'
-                            })
-                            checkbox_input = etree.SubElement(form_check, 'input', {
-                                'type': 'checkbox',
-                                'class': 's_website_form_input form-check-input',
-                                'name': field_name,
-                                'id': f'{field_id}_{record["id"]}',
-                                'value': str(record['id'])
-                            })
-                            if required:
-                                checkbox_input.set('required', '1')
-                            if str(record['id']) in [v.strip() for v in default_values]:
-                                checkbox_input.set('checked', 'checked')
-                            checkbox_label = etree.SubElement(form_check, 'label', {
-                                'class': 'form-check-label s_website_form_check_label',
-                                'for': checkbox_input.get('id')
-                            })
-                            checkbox_label.text = record['display_name']
-                    except Exception:
-                        pass
-                input_el = checkbox_wrapper
             else:
                 # Default: Select dropdown for many2one
                 input_el = etree.SubElement(input_div, 'select', {
@@ -1273,9 +1233,10 @@ class HelpdeskTeamExtras(models.Model):
             if required:
                 input_el.set('required', '1')
         else:
-            # Default: text input (char) - exactly as form builder does
+            # Default: text input (char) - Use input_type from template_field (default 'text', same as Odoo formbuilder)
+            input_type_value = template_field.input_type if template_field.input_type else 'text'
             input_el = etree.SubElement(input_div, 'input', {
-                'type': 'text',
+                'type': input_type_value,
                 'class': 'form-control s_website_form_input',
                 'name': field_name,
                 'id': field_id

+ 26 - 1
helpdesk_extras/models/helpdesk_template.py

@@ -280,10 +280,35 @@ class HelpdeskTemplateField(models.Model):
         default='default',
         help="Widget to use for selection/many2one fields. Default uses dropdown select."
     )
+    selection_type = fields.Selection(
+        [
+            ('dropdown', 'Dropdown List'),
+            ('radio', 'Radio'),
+        ],
+        string='Selection Type',
+        default='dropdown',
+        help="Display type for selection and many2one fields. Dropdown List shows a select dropdown, Radio shows radio buttons. Same as Odoo formbuilder."
+    )
     selection_options = fields.Text(
         string='Selection Options',
         help="For selection fields (not relations): JSON array of [value, label] pairs. Example: [['option1', 'Option 1'], ['option2', 'Option 2']]"
     )
+    rows = fields.Integer(
+        string='Height (Rows)',
+        default=3,
+        help="Number of rows for textarea fields. Default is 3."
+    )
+    input_type = fields.Selection(
+        [
+            ('text', 'Text'),
+            ('email', 'Email'),
+            ('tel', 'Telephone'),
+            ('url', 'Url'),
+        ],
+        string='Input Type',
+        default='text',
+        help="Input type for text fields. Determines the HTML input type attribute."
+    )
     sequence = fields.Integer(
         string='Sequence',
         default=10,
@@ -638,7 +663,7 @@ class HelpdeskTemplateField(models.Model):
         if any(key in vals for key in ['field_id', 'sequence', 'required', 'visibility_dependency', 
                                        'visibility_condition', 'visibility_comparator', 'label_custom', 
                                        'model_required', 'placeholder', 'default_value', 'help_text', 
-                                       'widget', 'selection_options']):
+                                       'widget', 'selection_options', 'rows', 'input_type', 'selection_type']):
             # Get unique templates that were modified
             templates = self.mapped('template_id')
             

+ 10 - 1
helpdesk_extras/views/helpdesk_template_views.xml

@@ -42,9 +42,18 @@
                                     <field name="placeholder" placeholder="Placeholder text"/>
                                     <field name="default_value" placeholder="Default value"/>
                                     <field name="help_text" widget="html" placeholder="Help text (HTML)"/>
+                                    <field name="rows" 
+                                           string="Height (Rows)"
+                                           invisible="field_type not in ['text', 'html']"/>
+                                    <field name="input_type" 
+                                           string="Input Type"
+                                           invisible="field_type != 'char'"/>
+                                    <field name="selection_type" 
+                                           string="Selection Type"
+                                           invisible="field_type not in ['selection', 'many2one']"/>
                                     <field name="widget" 
                                            column_invisible="1"
-                                           invisible="field_type not in ['selection', 'many2one']"/>
+                                           invisible="field_type not in ['one2many', 'many2many']"/>
                                     <field name="selection_options" 
                                            widget="text" 
                                            column_invisible="1"