Marwan Alwali 23158e9fbf update
2025-09-08 03:00:23 +03:00

1120 lines
43 KiB
Python

"""
Analytics app forms for CRUD operations.
"""
from django import forms
from django.core.exceptions import ValidationError
from django.utils import timezone
from datetime import datetime, date
from .models import (
Dashboard, DashboardWidget, DataSource, Report,
MetricDefinition
)
class DashboardForm(forms.ModelForm):
"""
Form for creating and updating dashboards.
"""
class Meta:
model = Dashboard
fields = [
'name', 'description', 'dashboard_type', 'is_public',
'layout_config', 'refresh_interval', 'is_active'
]
widgets = {
'name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter dashboard name'
}),
'description': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter dashboard description'
}),
'dashboard_type': forms.Select(attrs={'class': 'form-control'}),
'is_public': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'layout_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 5,
'placeholder': 'Enter JSON layout configuration'
}),
'refresh_interval': forms.NumberInput(attrs={
'class': 'form-control',
'min': 30,
'max': 3600,
'step': 30
}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
}
help_texts = {
'name': 'Unique name for this dashboard',
'dashboard_type': 'Dashboard type for organization',
'is_public': 'Whether this dashboard is publicly accessible',
'layout_config': 'JSON configuration for dashboard layout',
'refresh_interval': 'Auto-refresh interval in seconds (30-3600)',
}
def clean_name(self):
name = self.cleaned_data['name']
if len(name) < 3:
raise ValidationError('Dashboard name must be at least 3 characters long.')
return name
def clean_refresh_interval(self):
interval = self.cleaned_data['refresh_interval']
if interval and (interval < 30 or interval > 3600):
raise ValidationError('Refresh interval must be between 30 and 3600 seconds.')
return interval
class DashboardWidgetForm(forms.ModelForm):
"""
Form for creating and updating dashboard widgets.
"""
class Meta:
model = DashboardWidget
fields = [
'dashboard', 'name', 'widget_type', 'position_x', 'position_y',
'width', 'height', 'display_config', 'query_config', 'is_active'
]
widgets = {
'dashboard': forms.Select(attrs={'class': 'form-control'}),
'name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter widget name'
}),
'widget_type': forms.Select(attrs={'class': 'form-control'}),
'position_x': forms.NumberInput(attrs={
'class': 'form-control',
'min': 0,
'max': 12
}),
'position_y': forms.NumberInput(attrs={
'class': 'form-control',
'min': 0
}),
'width': forms.NumberInput(attrs={
'class': 'form-control',
'min': 1,
'max': 12
}),
'height': forms.NumberInput(attrs={
'class': 'form-control',
'min': 1,
'max': 20
}),
'display_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Enter JSON display configuration'
}),
'query_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter query configuration'
}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
}
help_texts = {
'widget_type': 'Type of widget (chart, table, KPI, etc.)',
'position_x': 'Horizontal position (0-12 grid system)',
'position_y': 'Vertical position',
'width': 'Widget width (1-12 grid columns)',
'height': 'Widget height in grid rows',
'display_config': 'JSON configuration for widget display',
'query_config': 'Query configuration for widget content',
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user:
self.fields['dashboard'].queryset = Dashboard.objects.filter(
tenant=user.tenant
).order_by('name')
def clean_position_x(self):
x = self.cleaned_data['position_x']
if x < 0 or x > 12:
raise ValidationError('Position X must be between 0 and 12.')
return x
def clean_width(self):
width = self.cleaned_data['width']
if width < 1 or width > 12:
raise ValidationError('Width must be between 1 and 12.')
return width
class DataSourceForm(forms.ModelForm):
"""
Form for creating and updating data sources.
"""
class Meta:
model = DataSource
fields = [
'name', 'description', 'source_type', 'connection_config',
'authentication_config', 'query_template', 'cache_duration',
'is_active'
]
widgets = {
'name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter data source name'
}),
'description': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter data source description'
}),
'source_type': forms.Select(attrs={'class': 'form-control'}),
'connection_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Enter JSON connection configuration'
}),
'authentication_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter JSON authentication configuration'
}),
'query_template': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Enter query template'
}),
'cache_duration': forms.NumberInput(attrs={
'class': 'form-control',
'min': 0,
'max': 86400,
'value': 300
}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
}
help_texts = {
'name': 'Unique name for this data source',
'source_type': 'Type of data source (database, API, file, etc.)',
'connection_config': 'JSON configuration for connection settings',
'authentication_config': 'JSON configuration for authentication',
'cache_duration': 'Cache duration in seconds (0-86400)',
}
def clean_name(self):
name = self.cleaned_data['name']
if len(name) < 3:
raise ValidationError('Data source name must be at least 3 characters long.')
return name
def clean_cache_duration(self):
cache_duration = self.cleaned_data['cache_duration']
if cache_duration < 0 or cache_duration > 86400:
raise ValidationError('Cache duration must be between 0 and 86400 seconds.')
return cache_duration
class ReportForm(forms.ModelForm):
"""
Form for creating and updating reports.
"""
class Meta:
model = Report
fields = [
'name', 'description', 'report_type', 'data_source',
'query_config', 'output_format', 'template_config',
'schedule_config', 'is_active'
]
widgets = {
'name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter report name'
}),
'description': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter report description'
}),
'report_type': forms.Select(attrs={'class': 'form-control'}),
'data_source': forms.Select(attrs={'class': 'form-control'}),
'query_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 8,
'placeholder': 'Enter query configuration'
}),
'template_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Enter JSON template configuration'
}),
'output_format': forms.Select(attrs={'class': 'form-control'}),
'schedule_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter JSON schedule configuration'
}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
}
help_texts = {
'name': 'Unique name for this report',
'report_type': 'Report type for organization',
'query_config': 'Query configuration for report data',
'template_config': 'Template configuration for report formatting',
'output_format': 'Default output format for report',
'schedule_config': 'JSON configuration for automated scheduling',
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user:
self.fields['data_source'].queryset = DataSource.objects.filter(
tenant=user.tenant,
is_active=True
).order_by('name')
def clean_report_name(self):
name = self.cleaned_data['report_name']
if len(name) < 3:
raise ValidationError('Report name must be at least 3 characters long.')
return name
def clean_query_definition(self):
query = self.cleaned_data['query_definition']
if len(query.strip()) < 10:
raise ValidationError('Query definition must be at least 10 characters long.')
return query
class MetricDefinitionForm(forms.ModelForm):
"""
Form for creating and updating metric definitions.
"""
class Meta:
model = MetricDefinition
fields = [
'name', 'description', 'metric_type', 'data_source',
'calculation_config', 'aggregation_period', 'unit_of_measure',
'target_value', 'warning_threshold', 'critical_threshold',
'aggregation_config', 'is_active'
]
widgets = {
'name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter metric name'
}),
'description': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter metric description'
}),
'metric_type': forms.Select(attrs={'class': 'form-control'}),
'data_source': forms.Select(attrs={'class': 'form-control'}),
'calculation_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 6,
'placeholder': 'Enter calculation configuration'
}),
'aggregation_period': forms.Select(attrs={'class': 'form-control'}),
'unit_of_measure': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'e.g., %, count, minutes, dollars'
}),
'target_value': forms.NumberInput(attrs={
'class': 'form-control',
'step': 'any',
'placeholder': 'Target value for this metric'
}),
'warning_threshold': forms.NumberInput(attrs={
'class': 'form-control',
'step': 'any',
'placeholder': 'Warning threshold value'
}),
'critical_threshold': forms.NumberInput(attrs={
'class': 'form-control',
'step': 'any',
'placeholder': 'Critical threshold value'
}),
'aggregation_config': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Enter aggregation configuration'
}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
}
help_texts = {
'name': 'Unique name for this metric',
'metric_type': 'Metric type for organization',
'calculation_config': 'Configuration for metric calculation',
'aggregation_period': 'Period for metric aggregation',
'unit_of_measure': 'Unit of measurement for metric values',
'target_value': 'Target or goal value for this metric',
'warning_threshold': 'Value that triggers warning alerts',
'critical_threshold': 'Value that triggers critical alerts',
'aggregation_config': 'Configuration for metric aggregation',
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user:
self.fields['data_source'].queryset = DataSource.objects.filter(
tenant=user.tenant,
is_active=True
).order_by('source_name')
def clean_metric_name(self):
name = self.cleaned_data['metric_name']
if len(name) < 3:
raise ValidationError('Metric name must be at least 3 characters long.')
return name
def clean_query_definition(self):
query = self.cleaned_data['query_definition']
if len(query.strip()) < 5:
raise ValidationError('Query definition must be at least 5 characters long.')
return query
def clean(self):
cleaned_data = super().clean()
target = cleaned_data.get('target_value')
warning = cleaned_data.get('threshold_warning')
critical = cleaned_data.get('threshold_critical')
# Validate threshold relationships
if target and warning and critical:
if warning == critical:
raise ValidationError('Warning and critical thresholds must be different.')
return cleaned_data
# from django import forms
# from django.core.exceptions import ValidationError
# from django.utils import timezone
# from crispy_forms.helper import FormHelper
# from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML, Div
# from crispy_forms.bootstrap import FormActions
# import json
#
# from .models import Dashboard, DashboardWidget, DataSource, Report, MetricDefinition
# from core.models import Tenant
#
#
# class ReportGenerationForm(forms.ModelForm):
# """
# Form for report generation configuration
# """
# parameters = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
# )
# output_format = forms.ChoiceField(
# choices=[
# ('pdf', 'PDF'),
# ('excel', 'Excel'),
# ('csv', 'CSV'),
# ('json', 'JSON')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# schedule_execution = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# execution_time = forms.DateTimeField(
# required=False,
# widget=forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'})
# )
# email_recipients = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
#
# class Meta:
# model = Report
# fields = [
# 'name', 'description', 'report_type', 'data_sources',
# 'parameters', 'output_format', 'schedule_execution',
# 'execution_time', 'email_recipients'
# ]
# widgets = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
# 'report_type': forms.Select(attrs={'class': 'form-control'}),
# 'data_sources': forms.CheckboxSelectMultiple(attrs={'class': 'form-check-input'})
# }
#
# def __init__(self, *args, **kwargs):
# tenant = kwargs.pop('tenant', None)
# super().__init__(*args, **kwargs)
#
# if tenant:
# self.fields['data_sources'].queryset = DataSource.objects.filter(tenant=tenant)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Report Configuration',
# Row(
# Column('name', css_class='form-group col-md-6 mb-0'),
# Column('report_type', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'description',
# 'data_sources',
# 'parameters'
# ),
# Fieldset(
# 'Output Settings',
# Row(
# Column('output_format', css_class='form-group col-md-6 mb-0'),
# Column('email_recipients', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# )
# ),
# Fieldset(
# 'Scheduling',
# HTML('<div class="form-check">'),
# 'schedule_execution',
# HTML(
# '<label class="form-check-label" for="id_schedule_execution">Schedule for later execution</label>'),
# HTML('</div>'),
# 'execution_time'
# ),
# FormActions(
# Submit('submit', 'Generate Report', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:report_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean_parameters(self):
# parameters = self.cleaned_data.get('parameters')
# if parameters:
# try:
# json.loads(parameters)
# except json.JSONDecodeError:
# raise ValidationError('Parameters must be valid JSON.')
# return parameters
#
# def clean(self):
# cleaned_data = super().clean()
# schedule_execution = cleaned_data.get('schedule_execution')
# execution_time = cleaned_data.get('execution_time')
#
# if schedule_execution and not execution_time:
# raise ValidationError('Execution time is required when scheduling execution.')
#
# return cleaned_data
#
#
# class DashboardCreationForm(forms.ModelForm):
# """
# Form for dashboard creation
# """
# layout_template = forms.ChoiceField(
# choices=[
# ('grid_2x2', '2x2 Grid'),
# ('grid_3x3', '3x3 Grid'),
# ('sidebar_main', 'Sidebar + Main'),
# ('top_bottom', 'Top + Bottom'),
# ('custom', 'Custom Layout')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# copy_from_dashboard = forms.ModelChoiceField(
# queryset=None,
# required=False,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
#
# class Meta:
# model = Dashboard
# fields = [
# 'name', 'description', 'dashboard_type', 'layout_template',
# 'refresh_interval', 'is_public', 'allowed_roles',
# 'copy_from_dashboard'
# ]
# widgets = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
# 'dashboard_type': forms.Select(attrs={'class': 'form-control'}),
# 'refresh_interval': forms.NumberInput(attrs={'class': 'form-control'}),
# 'is_public': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
# 'allowed_roles': forms.Textarea(attrs={'class': 'form-control', 'rows': 2})
# }
#
# def __init__(self, *args, **kwargs):
# tenant = kwargs.pop('tenant', None)
# super().__init__(*args, **kwargs)
#
# if tenant:
# self.fields['copy_from_dashboard'].queryset = Dashboard.objects.filter(
# tenant=tenant,
# is_active=True
# )
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Dashboard Information',
# Row(
# Column('name', css_class='form-group col-md-6 mb-0'),
# Column('dashboard_type', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'description'
# ),
# Fieldset(
# 'Layout Configuration',
# Row(
# Column('layout_template', css_class='form-group col-md-6 mb-0'),
# Column('refresh_interval', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'copy_from_dashboard'
# ),
# Fieldset(
# 'Access Control',
# HTML('<div class="form-check">'),
# 'is_public',
# HTML('<label class="form-check-label" for="id_is_public">Make dashboard public</label>'),
# HTML('</div>'),
# 'allowed_roles'
# ),
# FormActions(
# Submit('submit', 'Create Dashboard', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:dashboard_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
#
# class DataSourceConfigurationForm(forms.ModelForm):
# """
# Form for data source configuration
# """
# test_connection = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# class Meta:
# model = DataSource
# fields = [
# 'name', 'description', 'source_type', 'connection_config',
# 'query_config', 'refresh_interval', 'is_active',
# 'test_connection'
# ]
# widgets = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
# 'source_type': forms.Select(attrs={'class': 'form-control'}),
# 'connection_config': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
# 'query_config': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
# 'refresh_interval': forms.NumberInput(attrs={'class': 'form-control'}),
# 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
# }
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Data Source Information',
# Row(
# Column('name', css_class='form-group col-md-6 mb-0'),
# Column('source_type', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'description'
# ),
# Fieldset(
# 'Connection Configuration',
# 'connection_config',
# HTML('<small class="form-text text-muted">Enter connection details in JSON format</small>')
# ),
# Fieldset(
# 'Query Configuration',
# 'query_config',
# HTML('<small class="form-text text-muted">Enter query configuration in JSON format</small>')
# ),
# Fieldset(
# 'Settings',
# Row(
# Column('refresh_interval', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# HTML('<div class="form-check">'),
# 'is_active',
# HTML('<label class="form-check-label" for="id_is_active">Active</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'test_connection',
# HTML('<label class="form-check-label" for="id_test_connection">Test connection after saving</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Save Data Source', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:data_source_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean_connection_config(self):
# config = self.cleaned_data.get('connection_config')
# if config:
# try:
# json.loads(config)
# except json.JSONDecodeError:
# raise ValidationError('Connection configuration must be valid JSON.')
# return config
#
# def clean_query_config(self):
# config = self.cleaned_data.get('query_config')
# if config:
# try:
# json.loads(config)
# except json.JSONDecodeError:
# raise ValidationError('Query configuration must be valid JSON.')
# return config
#
#
# class MetricCalculationForm(forms.ModelForm):
# """
# Form for metric calculation configuration
# """
# calculate_now = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# date_range_start = forms.DateField(
# required=False,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
# date_range_end = forms.DateField(
# required=False,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
#
# class Meta:
# model = MetricDefinition
# fields = [
# 'name', 'description', 'metric_type', 'data_source',
# 'calculation_config', 'aggregation_period', 'target_value',
# 'warning_threshold', 'critical_threshold', 'unit_of_measure',
# 'calculate_now', 'date_range_start', 'date_range_end'
# ]
# widgets = {
# 'name': forms.TextInput(attrs={'class': 'form-control'}),
# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
# 'metric_type': forms.Select(attrs={'class': 'form-control'}),
# 'data_source': forms.Select(attrs={'class': 'form-control'}),
# 'calculation_config': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
# 'aggregation_period': forms.Select(attrs={'class': 'form-control'}),
# 'target_value': forms.NumberInput(attrs={'class': 'form-control'}),
# 'warning_threshold': forms.NumberInput(attrs={'class': 'form-control'}),
# 'critical_threshold': forms.NumberInput(attrs={'class': 'form-control'}),
# 'unit_of_measure': forms.TextInput(attrs={'class': 'form-control'})
# }
#
# def __init__(self, *args, **kwargs):
# tenant = kwargs.pop('tenant', None)
# super().__init__(*args, **kwargs)
#
# if tenant:
# self.fields['data_source'].queryset = DataSource.objects.filter(tenant=tenant)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Metric Definition',
# Row(
# Column('name', css_class='form-group col-md-6 mb-0'),
# Column('metric_type', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'description',
# Row(
# Column('data_source', css_class='form-group col-md-6 mb-0'),
# Column('aggregation_period', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'calculation_config'
# ),
# Fieldset(
# 'Thresholds and Targets',
# Row(
# Column('target_value', css_class='form-group col-md-4 mb-0'),
# Column('warning_threshold', css_class='form-group col-md-4 mb-0'),
# Column('critical_threshold', css_class='form-group col-md-4 mb-0'),
# css_class='form-row'
# ),
# 'unit_of_measure'
# ),
# Fieldset(
# 'Calculation Options',
# HTML('<div class="form-check">'),
# 'calculate_now',
# HTML('<label class="form-check-label" for="id_calculate_now">Calculate metric immediately</label>'),
# HTML('</div>'),
# Row(
# Column('date_range_start', css_class='form-group col-md-6 mb-0'),
# Column('date_range_end', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# )
# ),
# FormActions(
# Submit('submit', 'Save Metric', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:metric_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean_calculation_config(self):
# config = self.cleaned_data.get('calculation_config')
# if config:
# try:
# json.loads(config)
# except json.JSONDecodeError:
# raise ValidationError('Calculation configuration must be valid JSON.')
# return config
#
#
# class QualityAssuranceForm(forms.Form):
# """
# Form for quality assurance configuration
# """
# check_data_accuracy = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# validate_calculations = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# verify_data_sources = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# check_performance = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# generate_qa_report = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# qa_threshold = forms.DecimalField(
# max_digits=5,
# decimal_places=2,
# initial=95.0,
# widget=forms.NumberInput(attrs={'class': 'form-control'})
# )
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Quality Assurance Checks',
# HTML('<div class="form-check">'),
# 'check_data_accuracy',
# HTML('<label class="form-check-label" for="id_check_data_accuracy">Check Data Accuracy</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'validate_calculations',
# HTML('<label class="form-check-label" for="id_validate_calculations">Validate Calculations</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'verify_data_sources',
# HTML('<label class="form-check-label" for="id_verify_data_sources">Verify Data Sources</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'check_performance',
# HTML('<label class="form-check-label" for="id_check_performance">Check Performance</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'generate_qa_report',
# HTML('<label class="form-check-label" for="id_generate_qa_report">Generate QA Report</label>'),
# HTML('</div>')
# ),
# Fieldset(
# 'Quality Threshold',
# 'qa_threshold',
# HTML('<small class="form-text text-muted">Minimum quality score percentage (0-100)</small>')
# ),
# FormActions(
# Submit('submit', 'Start Quality Check', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:dashboard\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
#
# class DistributionForm(forms.Form):
# """
# Form for report distribution configuration
# """
# distribution_method = forms.ChoiceField(
# choices=[
# ('email', 'Email'),
# ('download', 'Download Link'),
# ('ftp', 'FTP Upload'),
# ('api', 'API Endpoint'),
# ('dashboard', 'Dashboard Publication')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# recipients = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
# )
# subject = forms.CharField(
# required=False,
# widget=forms.TextInput(attrs={'class': 'form-control'})
# )
# message = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
# )
# schedule_distribution = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# distribution_time = forms.DateTimeField(
# required=False,
# widget=forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'})
# )
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Distribution Method',
# 'distribution_method',
# 'recipients',
# HTML('<small class="form-text text-muted">Enter email addresses separated by commas</small>')
# ),
# Fieldset(
# 'Message Content',
# 'subject',
# 'message'
# ),
# Fieldset(
# 'Scheduling',
# HTML('<div class="form-check">'),
# 'schedule_distribution',
# HTML('<label class="form-check-label" for="id_schedule_distribution">Schedule distribution</label>'),
# HTML('</div>'),
# 'distribution_time'
# ),
# FormActions(
# Submit('submit', 'Distribute Report', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:report_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean(self):
# cleaned_data = super().clean()
# distribution_method = cleaned_data.get('distribution_method')
# recipients = cleaned_data.get('recipients')
# schedule_distribution = cleaned_data.get('schedule_distribution')
# distribution_time = cleaned_data.get('distribution_time')
#
# if distribution_method == 'email' and not recipients:
# raise ValidationError('Recipients are required for email distribution.')
#
# if schedule_distribution and not distribution_time:
# raise ValidationError('Distribution time is required when scheduling distribution.')
#
# return cleaned_data
#
#
# class VisualizationForm(forms.Form):
# """
# Form for visualization configuration
# """
# chart_type = forms.ChoiceField(
# choices=[
# ('line', 'Line Chart'),
# ('bar', 'Bar Chart'),
# ('pie', 'Pie Chart'),
# ('scatter', 'Scatter Plot'),
# ('heatmap', 'Heat Map'),
# ('gauge', 'Gauge'),
# ('table', 'Data Table')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# title = forms.CharField(
# required=True,
# widget=forms.TextInput(attrs={'class': 'form-control'})
# )
# x_axis_label = forms.CharField(
# required=False,
# widget=forms.TextInput(attrs={'class': 'form-control'})
# )
# y_axis_label = forms.CharField(
# required=False,
# widget=forms.TextInput(attrs={'class': 'form-control'})
# )
# color_scheme = forms.ChoiceField(
# choices=[
# ('default', 'Default'),
# ('blue', 'Blue Theme'),
# ('green', 'Green Theme'),
# ('red', 'Red Theme'),
# ('purple', 'Purple Theme'),
# ('custom', 'Custom Colors')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# show_legend = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# show_grid = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Chart Configuration',
# Row(
# Column('chart_type', css_class='form-group col-md-6 mb-0'),
# Column('color_scheme', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'title'
# ),
# Fieldset(
# 'Axis Labels',
# Row(
# Column('x_axis_label', css_class='form-group col-md-6 mb-0'),
# Column('y_axis_label', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# )
# ),
# Fieldset(
# 'Display Options',
# HTML('<div class="form-check">'),
# 'show_legend',
# HTML('<label class="form-check-label" for="id_show_legend">Show Legend</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'show_grid',
# HTML('<label class="form-check-label" for="id_show_grid">Show Grid</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Create Visualization', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:dashboard\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
#
# class AnalysisForm(forms.Form):
# """
# Form for data analysis configuration
# """
# analysis_type = forms.ChoiceField(
# choices=[
# ('descriptive', 'Descriptive Analysis'),
# ('trend', 'Trend Analysis'),
# ('correlation', 'Correlation Analysis'),
# ('regression', 'Regression Analysis'),
# ('forecasting', 'Forecasting'),
# ('anomaly', 'Anomaly Detection')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# data_source = forms.ModelChoiceField(
# queryset=None,
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# date_range_start = forms.DateField(
# required=True,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
# date_range_end = forms.DateField(
# required=True,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
# confidence_level = forms.DecimalField(
# max_digits=5,
# decimal_places=2,
# initial=95.0,
# widget=forms.NumberInput(attrs={'class': 'form-control'})
# )
# generate_insights = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# def __init__(self, *args, **kwargs):
# tenant = kwargs.pop('tenant', None)
# super().__init__(*args, **kwargs)
#
# if tenant:
# self.fields['data_source'].queryset = DataSource.objects.filter(tenant=tenant)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Analysis Configuration',
# Row(
# Column('analysis_type', css_class='form-group col-md-6 mb-0'),
# Column('data_source', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# Row(
# Column('date_range_start', css_class='form-group col-md-6 mb-0'),
# Column('date_range_end', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'confidence_level'
# ),
# Fieldset(
# 'Options',
# HTML('<div class="form-check">'),
# 'generate_insights',
# HTML('<label class="form-check-label" for="id_generate_insights">Generate Insights</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Start Analysis', css_class='btn btn-primary'),
# HTML('<a href="{% url \'analytics:dashboard\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#