- 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>
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package server
|
|
|
|
import "odoo-go/pkg/orm"
|
|
|
|
// fieldsGetForModel returns field metadata for a model.
|
|
// Mirrors: odoo/orm/models.py BaseModel.fields_get()
|
|
func fieldsGetForModel(modelName string) map[string]interface{} {
|
|
m := orm.Registry.Get(modelName)
|
|
if m == nil {
|
|
return map[string]interface{}{}
|
|
}
|
|
|
|
result := make(map[string]interface{})
|
|
for name, f := range m.Fields() {
|
|
fType := f.Type.String()
|
|
|
|
fieldInfo := map[string]interface{}{
|
|
"name": name,
|
|
"type": fType,
|
|
"string": f.String,
|
|
"help": f.Help,
|
|
"readonly": f.Readonly,
|
|
"required": f.Required,
|
|
"searchable": f.IsStored(),
|
|
"sortable": f.IsStored(),
|
|
"store": f.IsStored(),
|
|
"manual": false,
|
|
"depends": f.Depends,
|
|
"groupable": f.IsStored() && f.Type != orm.TypeText && f.Type != orm.TypeHTML,
|
|
"exportable": true,
|
|
"change_default": false,
|
|
"company_dependent": false,
|
|
}
|
|
|
|
// Relational fields
|
|
if f.Comodel != "" {
|
|
fieldInfo["relation"] = f.Comodel
|
|
}
|
|
if f.InverseField != "" {
|
|
fieldInfo["relation_field"] = f.InverseField
|
|
}
|
|
|
|
// Selection
|
|
if f.Type == orm.TypeSelection && len(f.Selection) > 0 {
|
|
sel := make([][]string, len(f.Selection))
|
|
for i, item := range f.Selection {
|
|
sel[i] = []string{item.Value, item.Label}
|
|
}
|
|
fieldInfo["selection"] = sel
|
|
}
|
|
|
|
// Monetary fields need currency_field
|
|
if f.Type == orm.TypeMonetary {
|
|
cf := f.CurrencyField
|
|
if cf == "" {
|
|
cf = "currency_id"
|
|
}
|
|
fieldInfo["currency_field"] = cf
|
|
}
|
|
|
|
// Computed fields
|
|
if f.Compute != "" {
|
|
fieldInfo["compute"] = f.Compute
|
|
}
|
|
if f.Related != "" {
|
|
fieldInfo["related"] = f.Related
|
|
}
|
|
|
|
// Default domain & context
|
|
fieldInfo["domain"] = "[]"
|
|
fieldInfo["context"] = "{}"
|
|
|
|
result[name] = fieldInfo
|
|
}
|
|
|
|
return result
|
|
}
|