Deepen all business modules: methods, validations, workflows
Account: - action_post: partner validation, line count check, sequence number assignment (JOURNAL/YYYY/NNNN format) - action_register_payment: opens payment wizard from invoice - remove_move_reconcile: undo reconciliation, reset residuals - Register Payment button in invoice form (visible when posted+unpaid) Sale: - action_cancel: cancels linked draft invoices + SO state - action_draft: reset cancelled SO to draft - action_view_invoice: navigate to linked invoices - Cancel/Reset buttons in form view header Purchase: - button_draft: reset cancelled PO to draft - action_create_bill already existed Stock: - action_cancel on picking: cancels moves + picking state CRM: - action_set_won_rainbowman: sets Won stage + rainbow effect - convert_opportunity: lead→opportunity type switch HR: - hr.contract model (name, employee, wage, dates, state) Project: - action_blocked on task (kanban_state) - Task stage seed data (New, In Progress, Done, Cancelled) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -584,6 +584,68 @@ func initSaleOrder() {
|
||||
}, nil
|
||||
})
|
||||
|
||||
// action_cancel: Cancel a sale order and linked draft invoices.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder.action_cancel()
|
||||
m.RegisterMethod("action_cancel", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
||||
env := rs.Env()
|
||||
for _, soID := range rs.IDs() {
|
||||
// Cancel linked draft invoices
|
||||
rows, _ := env.Tx().Query(env.Ctx(),
|
||||
`SELECT id FROM account_move WHERE invoice_origin = (SELECT name FROM sale_order WHERE id = $1) AND state = 'draft'`, soID)
|
||||
for rows.Next() {
|
||||
var invID int64
|
||||
rows.Scan(&invID)
|
||||
env.Tx().Exec(env.Ctx(), `UPDATE account_move SET state = 'cancel' WHERE id = $1`, invID)
|
||||
}
|
||||
rows.Close()
|
||||
env.Tx().Exec(env.Ctx(), `UPDATE sale_order SET state = 'cancel' WHERE id = $1`, soID)
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
// action_draft: Reset a cancelled sale order back to quotation.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder.action_draft()
|
||||
m.RegisterMethod("action_draft", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
||||
env := rs.Env()
|
||||
for _, soID := range rs.IDs() {
|
||||
env.Tx().Exec(env.Ctx(), `UPDATE sale_order SET state = 'draft' WHERE id = $1 AND state = 'cancel'`, soID)
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
// action_view_invoice: Open invoices linked to this sale order.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder.action_view_invoice()
|
||||
m.RegisterMethod("action_view_invoice", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
||||
env := rs.Env()
|
||||
soID := rs.IDs()[0]
|
||||
var soName string
|
||||
env.Tx().QueryRow(env.Ctx(), `SELECT name FROM sale_order WHERE id = $1`, soID).Scan(&soName)
|
||||
|
||||
// Find invoices linked to this SO
|
||||
rows, _ := env.Tx().Query(env.Ctx(),
|
||||
`SELECT id FROM account_move WHERE invoice_origin = $1`, soName)
|
||||
var invIDs []interface{}
|
||||
for rows.Next() {
|
||||
var id int64
|
||||
rows.Scan(&id)
|
||||
invIDs = append(invIDs, id)
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
if len(invIDs) == 1 {
|
||||
return map[string]interface{}{
|
||||
"type": "ir.actions.act_window", "res_model": "account.move",
|
||||
"res_id": invIDs[0], "view_mode": "form",
|
||||
"views": [][]interface{}{{nil, "form"}}, "target": "current",
|
||||
}, nil
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"type": "ir.actions.act_window", "res_model": "account.move",
|
||||
"view_mode": "list,form", "views": [][]interface{}{{nil, "list"}, {nil, "form"}},
|
||||
"domain": []interface{}{[]interface{}{"id", "in", invIDs}}, "target": "current",
|
||||
}, nil
|
||||
})
|
||||
|
||||
// action_create_delivery: Generate a stock picking (delivery) from a confirmed sale order.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder._action_confirm() → _create_picking()
|
||||
m.RegisterMethod("action_create_delivery", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
||||
|
||||
Reference in New Issue
Block a user