Fix P0-P2 bugs: sale.order M2M, display_name, DefaultGet
P0: Fix sale.order creation (was completely broken) - Corrected M2M junction table name from sale_order_line_account_tax_rel to account_tax_sale_order_line_rel (ORM sorts alphabetically) - Added fallback in BeforeCreate if sequence generation fails P1: Add display_name as magic field on ALL models - Added to addMagicFields() in pkg/orm/model.go (like Python BaseModel) - Computed on-the-fly in Read() from recName field, no DB column - Removed explicit display_name from res.partner (now auto-inherited) P2: Add DefaultGet hooks for sale.order and purchase.order - Sets company_id, currency_id, date_order/date_planned from environment - Follows same pattern as account.move's DefaultGet Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,6 @@ func initResPartner() {
|
||||
// -- Identity --
|
||||
m.AddFields(
|
||||
orm.Char("name", orm.FieldOpts{String: "Name", Required: true, Index: true}),
|
||||
orm.Char("display_name", orm.FieldOpts{String: "Display Name", Compute: "_compute_display_name", Store: true}),
|
||||
orm.Char("ref", orm.FieldOpts{String: "Reference", Index: true}),
|
||||
orm.Selection("type", []orm.SelectionItem{
|
||||
{Value: "contact", Label: "Contact"},
|
||||
|
||||
@@ -107,6 +107,32 @@ func initPurchaseOrder() {
|
||||
orm.Char("origin", orm.FieldOpts{String: "Source Document"}),
|
||||
)
|
||||
|
||||
// -- DefaultGet: Provide dynamic defaults for new records --
|
||||
// Mirrors: odoo/addons/purchase/models/purchase_order.py PurchaseOrder.default_get()
|
||||
// Supplies company_id, currency_id, date_order when creating a new PO.
|
||||
m.DefaultGet = func(env *orm.Environment, fields []string) orm.Values {
|
||||
vals := make(orm.Values)
|
||||
|
||||
// Default company from the current user's session
|
||||
companyID := env.CompanyID()
|
||||
if companyID > 0 {
|
||||
vals["company_id"] = companyID
|
||||
}
|
||||
|
||||
// Default currency from the company
|
||||
var currencyID int64
|
||||
err := env.Tx().QueryRow(env.Ctx(),
|
||||
`SELECT currency_id FROM res_company WHERE id = $1`, companyID).Scan(¤cyID)
|
||||
if err == nil && currencyID > 0 {
|
||||
vals["currency_id"] = currencyID
|
||||
}
|
||||
|
||||
// Default date_order = now
|
||||
vals["date_order"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
// button_confirm: draft → purchase
|
||||
m.RegisterMethod("button_confirm", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
||||
env := rs.Env()
|
||||
|
||||
@@ -135,7 +135,7 @@ func initSaleOrder() {
|
||||
`SELECT COALESCE(SUM(
|
||||
product_uom_qty * price_unit * (1 - COALESCE(discount,0)/100)
|
||||
* COALESCE((SELECT t.amount / 100 FROM account_tax t
|
||||
JOIN sale_order_line_account_tax_rel rel ON rel.account_tax_id = t.id
|
||||
JOIN account_tax_sale_order_line_rel rel ON rel.account_tax_id = t.id
|
||||
WHERE rel.sale_order_line_id = sol.id LIMIT 1), 0)
|
||||
), 0)
|
||||
FROM sale_order_line sol WHERE sol.order_id = $1
|
||||
@@ -156,12 +156,41 @@ func initSaleOrder() {
|
||||
m.RegisterCompute("amount_tax", computeSaleAmounts)
|
||||
m.RegisterCompute("amount_total", computeSaleAmounts)
|
||||
|
||||
// -- DefaultGet: Provide dynamic defaults for new records --
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder.default_get()
|
||||
// Supplies company_id, currency_id, date_order when creating a new quotation.
|
||||
m.DefaultGet = func(env *orm.Environment, fields []string) orm.Values {
|
||||
vals := make(orm.Values)
|
||||
|
||||
// Default company from the current user's session
|
||||
companyID := env.CompanyID()
|
||||
if companyID > 0 {
|
||||
vals["company_id"] = companyID
|
||||
}
|
||||
|
||||
// Default currency from the company
|
||||
var currencyID int64
|
||||
err := env.Tx().QueryRow(env.Ctx(),
|
||||
`SELECT currency_id FROM res_company WHERE id = $1`, companyID).Scan(¤cyID)
|
||||
if err == nil && currencyID > 0 {
|
||||
vals["currency_id"] = currencyID
|
||||
}
|
||||
|
||||
// Default date_order = now
|
||||
vals["date_order"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
// -- Sequence Hook --
|
||||
m.BeforeCreate = func(env *orm.Environment, vals orm.Values) error {
|
||||
name, _ := vals["name"].(string)
|
||||
if name == "" || name == "/" {
|
||||
seq, err := orm.NextByCode(env, "sale.order")
|
||||
if err == nil {
|
||||
if err != nil {
|
||||
// Fallback: generate a simple name like purchase.order does
|
||||
vals["name"] = fmt.Sprintf("SO/%d", time.Now().UnixNano()%100000)
|
||||
} else {
|
||||
vals["name"] = seq
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user