Fix null→false, stock seed data, action_get on model, FK order
- Normalize null DB values to false (Odoo convention) in web_search_read and web_read responses - Seed stock reference data: 6 locations, 1 warehouse, 3 picking types - Fix FK order: warehouse must be created before picking types - Move action_get from hardcoded dispatcher to res.users RegisterMethod - Add action_res_users_my (ID 103) to seedActions - Remove hardcoded action_get case from dispatchORM Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -629,20 +629,6 @@ func (s *Server) dispatchORM(env *orm.Environment, params CallKWParams) (interfa
|
||||
case "activity_format":
|
||||
return []interface{}{}, nil
|
||||
|
||||
case "action_get":
|
||||
// res.users.action_get() — returns the preference action
|
||||
// Mirrors: odoo/addons/base/models/res_users.py action_get()
|
||||
return map[string]interface{}{
|
||||
"type": "ir.actions.act_window",
|
||||
"name": "Change My Preferences",
|
||||
"res_model": "res.users",
|
||||
"view_mode": "form",
|
||||
"views": [][]interface{}{{false, "form"}},
|
||||
"target": "new",
|
||||
"res_id": env.UID(),
|
||||
"context": map[string]interface{}{},
|
||||
}, nil
|
||||
|
||||
case "action_archive":
|
||||
ids := parseIDs(params.Args)
|
||||
if len(ids) > 0 {
|
||||
|
||||
@@ -89,6 +89,9 @@ func handleWebSearchRead(env *orm.Environment, model string, params CallKWParams
|
||||
// Format date/datetime fields to Odoo's expected string format
|
||||
formatDateFields(model, records)
|
||||
|
||||
// Convert SQL NULLs to Odoo-expected defaults (false, 0, etc.)
|
||||
normalizeNullFields(model, records)
|
||||
|
||||
if records == nil {
|
||||
records = []orm.Values{}
|
||||
}
|
||||
@@ -133,6 +136,9 @@ func handleWebRead(env *orm.Environment, model string, params CallKWParams) (int
|
||||
// Format date/datetime fields to Odoo's expected string format
|
||||
formatDateFields(model, records)
|
||||
|
||||
// Convert SQL NULLs to Odoo-expected defaults (false, 0, etc.)
|
||||
normalizeNullFields(model, records)
|
||||
|
||||
if records == nil {
|
||||
records = []orm.Values{}
|
||||
}
|
||||
@@ -203,6 +209,42 @@ func formatM2OFields(env *orm.Environment, modelName string, records []orm.Value
|
||||
}
|
||||
}
|
||||
|
||||
// normalizeNullFields converts SQL NULL (Go nil) values to Odoo-expected defaults.
|
||||
// In Python Odoo, empty fields return False (JSON false), not null.
|
||||
// Without this, the webclient may render "null" as literal text.
|
||||
// Mirrors: odoo/orm/fields.py convert_to_read() behaviour
|
||||
func normalizeNullFields(model string, records []orm.Values) {
|
||||
m := orm.Registry.Get(model)
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
for _, rec := range records {
|
||||
for fieldName, val := range rec {
|
||||
if val != nil {
|
||||
continue
|
||||
}
|
||||
f := m.GetField(fieldName)
|
||||
if f == nil {
|
||||
continue
|
||||
}
|
||||
switch f.Type {
|
||||
case orm.TypeChar, orm.TypeText, orm.TypeHTML, orm.TypeSelection:
|
||||
rec[fieldName] = false
|
||||
case orm.TypeMany2one:
|
||||
rec[fieldName] = false
|
||||
case orm.TypeInteger, orm.TypeFloat, orm.TypeMonetary:
|
||||
rec[fieldName] = false
|
||||
case orm.TypeBoolean:
|
||||
rec[fieldName] = false
|
||||
case orm.TypeDate, orm.TypeDatetime:
|
||||
rec[fieldName] = false
|
||||
default:
|
||||
rec[fieldName] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// formatDateFields converts date/datetime values to Odoo's expected string format.
|
||||
func formatDateFields(model string, records []orm.Values) {
|
||||
m := orm.Registry.Get(model)
|
||||
|
||||
Reference in New Issue
Block a user