bemade-addons/helpdesk_sale_order_ai/models/ai_prompt_template.py
mathis ed9dda9bea [ADD] openwebui_connector, helpdesk_sale_order_ai: AI-powered sales order generation from helpdesk tickets
This commit introduces AI integration for helpdesk tickets to automatically generate sales orders:

- openwebui_connector: New module providing integration with OpenWebUI AI service
  * Configurable API connection (key, base URL, model)
  * AI prompt template system for reusable prompts
  * Uses Claude 3 Sonnet model by default

- helpdesk_sale_order_ai: Extends helpdesk_sale_order with AI capabilities
  * AI-powered analysis of ticket content to suggest products
  * Smart product quantity parsing from various formats
  * Dedicated UI tab for AI suggestions in helpdesk tickets
  * Auto-creation of sales orders with matched products

The integration streamlines the process of converting customer support requests into sales opportunities.
2025-07-15 15:18:01 -04:00

115 lines
4.4 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
class AIPromptTemplate(models.Model):
_name = 'helpdesk.ai.prompt.template'
_description = 'AI Prompt Template'
_rec_name = 'name'
_order = 'sequence, id'
name = fields.Char(
string='Name',
required=True,
)
sequence = fields.Integer(
string='Sequence',
default=10,
)
active = fields.Boolean(
string='Active',
default=True,
)
is_default = fields.Boolean(
string='Is Default',
default=False,
)
content = fields.Text(
string='Template Content',
required=True,
help='Template for the prompt sent to the AI. Use placeholders like {description}, {customer}, etc.',
)
@api.model
def _ensure_default_template(self):
"""Ensure there's at least one default template"""
import logging
_logger = logging.getLogger(__name__)
_logger.info("=== START: _ensure_default_template ====")
try:
_logger.info("Searching for default template")
default_template = self.search([('is_default', '=', True)], limit=1)
_logger.info(f"Default template search result: {default_template}")
if not default_template:
_logger.info("No default template found, creating one")
# Create a default template if none exists
default_content = """Based on the following helpdesk ticket description, identify products and services that should be included in a sales order:
Ticket Description: {description}
Customer: {customer}
Please provide a list of products/services with quantities and descriptions in the following format:
Product/Service Name | Quantity | Description
"""
_logger.info("Creating default template")
new_template = self.create({
'name': 'Default Template',
'content': default_content,
'is_default': True,
})
_logger.info(f"Created default template: {new_template}")
else:
_logger.info(f"Found existing default template: {default_template.name}")
_logger.info("=== END: _ensure_default_template ====")
return True
except Exception as e:
_logger.error(f"ERROR in _ensure_default_template: {str(e)}")
_logger.exception("Exception traceback:")
raise
@api.model_create_multi
def create(self, vals_list):
"""Override create to handle default templates"""
records = super(AIPromptTemplate, self).create(vals_list)
# If any new template is set as default, unset default flag on others
default_templates = records.filtered(lambda r: r.is_default)
if default_templates:
self.search([('id', 'not in', default_templates.ids), ('is_default', '=', True)]).write({'is_default': False})
return records
@api.model
def get_default_template(self):
"""Get the default template"""
import logging
_logger = logging.getLogger(__name__)
_logger.info("=== START: get_default_template ====")
try:
_logger.info("Searching for default template")
default_template = self.search([('is_default', '=', True)], limit=1)
_logger.info(f"Default template search result: {default_template}")
if not default_template:
_logger.info("No default template found, ensuring one exists")
self._ensure_default_template()
default_template = self.search([('is_default', '=', True)], limit=1)
_logger.info(f"Default template after ensure: {default_template}")
_logger.info("=== END: get_default_template ====")
return default_template
except Exception as e:
_logger.error(f"ERROR in get_default_template: {str(e)}")
_logger.exception("Exception traceback:")
return self.browse()
def set_as_default(self):
"""Set this template as the default"""
if self:
# Clear default flag on all other templates
self.search([('id', '!=', self.id)]).write({'is_default': False})
# Set this template as default
self.write({'is_default': True})
return True