validateView static method
Implementation
static ValidationReport validateView(OdooView view) {
final issues = <ValidationIssue>[];
// View ID
if (view.id.trim().isEmpty) {
issues.add(const ValidationIssue(
severity: ValidationSeverity.error,
code: 'EMPTY_ID',
message: 'View ID cannot be empty.',
));
} else if (!_isValidXmlId(view.id)) {
issues.add(ValidationIssue(
severity: ValidationSeverity.error,
code: 'INVALID_ID',
message: 'View ID "${view.id}" contains invalid characters. Use only a-z, 0-9, _.',
));
}
// Model name
if (view.model.trim().isEmpty) {
issues.add(const ValidationIssue(
severity: ValidationSeverity.error,
code: 'EMPTY_MODEL',
message: 'Model name cannot be empty (e.g. res.partner).',
));
} else if (!_isValidModelName(view.model)) {
issues.add(ValidationIssue(
severity: ValidationSeverity.warning,
code: 'UNUSUAL_MODEL',
message: 'Model name "${view.model}" looks unusual. Expected format: module.name',
));
}
// View name
if (view.name.trim().isEmpty) {
issues.add(const ValidationIssue(
severity: ValidationSeverity.warning,
code: 'EMPTY_NAME',
message: 'View name is empty — a descriptive name is recommended.',
));
}
// Empty view
if (view.isEmpty) {
issues.add(ValidationIssue(
severity: ValidationSeverity.warning,
code: 'EMPTY_VIEW',
message: 'The ${view.viewType.label} has no fields or groups.',
));
}
// Field-level validation
for (final field in view.allFields) {
issues.addAll(_validateField(field, context: view.viewType.value));
}
// Group depth
for (final group in view.groups) {
issues.addAll(_validateGroupDepth(group, depth: 1));
}
// Duplicate field names
final fieldNames = view.allFields.map((f) => f.name).toList();
final duplicates = fieldNames
.where((name) => fieldNames.where((n) => n == name).length > 1)
.toSet();
for (final dup in duplicates) {
issues.add(ValidationIssue(
severity: ValidationSeverity.warning,
code: 'DUPLICATE_FIELD',
message: 'Field "$dup" appears more than once in this view.',
));
}
return ValidationReport(issues);
}