Backend improvements: views, fields_get, session, RPC stubs

- Improved auto-generated list/form/search views with priority fields,
  two-column form layout, statusbar widget, notebook for O2M fields
- Enhanced fields_get with currency_field, compute, related metadata
- Fixed session handling: handleSessionInfo/handleSessionCheck use real
  session from cookie instead of hardcoded values
- Added read_progress_bar and activity_format RPC stubs
- Improved bootstrap translations with lang_parameters
- Added "contacts" to session modules list

Server starts successfully: 14 modules, 93 models, 378 XML templates,
503 JS modules transpiled — all from local frontend/ directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc
2026-03-31 23:16:26 +02:00
parent 8741282322
commit 9c444061fd
32 changed files with 3416 additions and 148 deletions

View File

@@ -262,19 +262,19 @@ func (dc *DomainCompiler) compileSimpleCondition(column, operator string, value
return fmt.Sprintf("%q NOT IN (%s)", column, strings.Join(placeholders, ", ")), nil
case "like":
dc.params = append(dc.params, value)
dc.params = append(dc.params, wrapLikeValue(value))
return fmt.Sprintf("%q LIKE $%d", column, paramIdx), nil
case "not like":
dc.params = append(dc.params, value)
dc.params = append(dc.params, wrapLikeValue(value))
return fmt.Sprintf("%q NOT LIKE $%d", column, paramIdx), nil
case "ilike":
dc.params = append(dc.params, value)
dc.params = append(dc.params, wrapLikeValue(value))
return fmt.Sprintf("%q ILIKE $%d", column, paramIdx), nil
case "not ilike":
dc.params = append(dc.params, value)
dc.params = append(dc.params, wrapLikeValue(value))
return fmt.Sprintf("%q NOT ILIKE $%d", column, paramIdx), nil
case "=like":
@@ -369,26 +369,27 @@ func (dc *DomainCompiler) compileQualifiedCondition(qualifiedColumn, operator st
}
return fmt.Sprintf("%s %s (%s)", qualifiedColumn, op, strings.Join(placeholders, ", ")), nil
case "like", "not like", "ilike", "not ilike", "=like", "=ilike":
dc.params = append(dc.params, value)
sqlOp := strings.ToUpper(strings.TrimPrefix(operator, "="))
if strings.HasPrefix(operator, "=") {
sqlOp = strings.ToUpper(operator[1:])
}
case "like", "not like", "ilike", "not ilike":
dc.params = append(dc.params, wrapLikeValue(value))
sqlOp := "LIKE"
switch operator {
case "like":
sqlOp = "LIKE"
case "not like":
sqlOp = "NOT LIKE"
case "ilike", "=ilike":
case "ilike":
sqlOp = "ILIKE"
case "not ilike":
sqlOp = "NOT ILIKE"
case "=like":
sqlOp = "LIKE"
}
return fmt.Sprintf("%s %s $%d", qualifiedColumn, sqlOp, paramIdx), nil
case "=like":
dc.params = append(dc.params, value)
return fmt.Sprintf("%s LIKE $%d", qualifiedColumn, paramIdx), nil
case "=ilike":
dc.params = append(dc.params, value)
return fmt.Sprintf("%s ILIKE $%d", qualifiedColumn, paramIdx), nil
default:
dc.params = append(dc.params, value)
return fmt.Sprintf("%s %s $%d", qualifiedColumn, operator, paramIdx), nil
@@ -427,3 +428,18 @@ func normalizeSlice(value Value) []interface{} {
}
return nil
}
// wrapLikeValue wraps a string value with % wildcards for LIKE/ILIKE operators,
// matching Odoo's behavior where ilike/like auto-wrap the search term.
// If the value already contains %, it is left as-is.
// Mirrors: odoo/orm/domains.py _expression._unaccent_wrap (value wrapping)
func wrapLikeValue(value Value) Value {
s, ok := value.(string)
if !ok {
return value
}
if strings.Contains(s, "%") || strings.Contains(s, "_") {
return value // Already has wildcards, leave as-is
}
return "%" + s + "%"
}