# -*- coding: utf-8 -*- from odoo import models, fields, api, _ import re class ReservationCustomField(models.Model): _name = 'reservation.custom.field' _description = 'Reservation Custom Field' _order = 'sequence, id' name = fields.Char(string='Field Label / Question', required=True, help="Label shown on the reservation form.") field_key = fields.Char(string='Field Key', compute='_compute_field_key', store=True, readonly=False, help="Technical identifier for form input.") field_type = fields.Selection([ ('char', 'Text (Single Line)'), ('text', 'Text (Multi-line)'), ('selection', 'Dropdown (Selection)'), ('boolean', 'Checkbox (Yes / No)'), ('integer', 'Number'), ], string='Field Type', default='char', required=True) selection_options = fields.Text(string='Dropdown Options', help="Comma-separated list of choices, e.g. Vegetarian, Vegan, Halal, Gluten-Free") placeholder = fields.Char(string='Placeholder', help="Optional placeholder text for the input box.") is_required = fields.Boolean(string='Required', default=False, help="Whether this field must be filled by customer.") is_active = fields.Boolean(string='Active (Show on Form)', default=True, help="If checked, field will appear on reservation form.") sequence = fields.Integer(string='Sequence', default=10) @api.depends('name') def _compute_field_key(self): for rec in self: if rec.name and not rec.field_key: clean = re.sub(r'[^a-zA-Z0-9_]', '_', rec.name.lower().strip()) rec.field_key = f"custom_{clean[:30]}" def get_options_list(self): """ Return options as a list of strings for selection rendering """ self.ensure_one() if not self.selection_options: return [] return [opt.strip() for opt in self.selection_options.split(',') if opt.strip()] class ReservationCustomFieldValue(models.Model): _name = 'reservation.custom.field.value' _description = 'Reservation Custom Field Answer' _order = 'id' reservation_id = fields.Many2one('restaurant.reservation', string='Reservation', ondelete='cascade', required=True) field_id = fields.Many2one('reservation.custom.field', string='Custom Field', ondelete='cascade', required=True) field_name = fields.Char(related='field_id.name', string='Field Label', readonly=True) field_type = fields.Selection(related='field_id.field_type', string='Field Type', readonly=True) value = fields.Text(string='Value / Answer')