- Portal: /my/* routes, signup, password reset, portal user support - Email Inbound: IMAP polling (go-imap/v2), thread matching - Discuss: mail.channel, long-polling bus, DM, unread count - Cron: ir.cron runner (goroutine scheduler) - Bank Import, CSV/Excel Import - Automation (ir.actions.server) - Fetchmail service - HR Payroll model - Various fixes across account, sale, stock, purchase, crm, hr, project Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
90 lines
3.1 KiB
Go
90 lines
3.1 KiB
Go
package models
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"odoo-go/pkg/orm"
|
|
)
|
|
|
|
// initPurchaseAgreement registers purchase.requisition and purchase.requisition.line.
|
|
// Mirrors: odoo/addons/purchase_requisition/models/purchase_requisition.py
|
|
|
|
func initPurchaseAgreement() {
|
|
m := orm.NewModel("purchase.requisition", orm.ModelOpts{
|
|
Description: "Purchase Agreement",
|
|
Order: "name desc",
|
|
})
|
|
|
|
m.AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Reference", Readonly: true, Default: "New"}),
|
|
orm.Many2one("user_id", "res.users", orm.FieldOpts{String: "Responsible"}),
|
|
orm.Selection("type_id", []orm.SelectionItem{
|
|
{Value: "blanket", Label: "Blanket Order"},
|
|
{Value: "purchase", Label: "Purchase Tender"},
|
|
}, orm.FieldOpts{String: "Agreement Type", Default: "blanket"}),
|
|
orm.Selection("state", []orm.SelectionItem{
|
|
{Value: "draft", Label: "Draft"},
|
|
{Value: "ongoing", Label: "Confirmed"},
|
|
{Value: "in_progress", Label: "Bid Selection"},
|
|
{Value: "open", Label: "Bid Selection"},
|
|
{Value: "done", Label: "Closed"},
|
|
{Value: "cancel", Label: "Cancelled"},
|
|
}, orm.FieldOpts{String: "Status", Default: "draft"}),
|
|
orm.Many2one("company_id", "res.company", orm.FieldOpts{String: "Company"}),
|
|
orm.Date("date_end", orm.FieldOpts{String: "Agreement Deadline"}),
|
|
orm.One2many("line_ids", "purchase.requisition.line", "requisition_id", orm.FieldOpts{String: "Lines"}),
|
|
)
|
|
|
|
// action_confirm: draft → ongoing
|
|
m.RegisterMethod("action_confirm", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
|
env := rs.Env()
|
|
for _, id := range rs.IDs() {
|
|
if _, err := env.Tx().Exec(env.Ctx(),
|
|
`UPDATE purchase_requisition SET state = 'ongoing' WHERE id = $1 AND state = 'draft'`, id); err != nil {
|
|
return nil, fmt.Errorf("purchase.requisition: confirm %d: %w", id, err)
|
|
}
|
|
}
|
|
return true, nil
|
|
})
|
|
|
|
m.RegisterMethod("action_done", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
|
env := rs.Env()
|
|
for _, id := range rs.IDs() {
|
|
if _, err := env.Tx().Exec(env.Ctx(),
|
|
`UPDATE purchase_requisition SET state = 'done' WHERE id = $1`, id); err != nil {
|
|
return nil, fmt.Errorf("purchase.requisition: done %d: %w", id, err)
|
|
}
|
|
}
|
|
return true, nil
|
|
})
|
|
|
|
m.RegisterMethod("action_cancel", func(rs *orm.Recordset, args ...interface{}) (interface{}, error) {
|
|
env := rs.Env()
|
|
for _, id := range rs.IDs() {
|
|
if _, err := env.Tx().Exec(env.Ctx(),
|
|
`UPDATE purchase_requisition SET state = 'cancel' WHERE id = $1`, id); err != nil {
|
|
return nil, fmt.Errorf("purchase.requisition: cancel %d: %w", id, err)
|
|
}
|
|
}
|
|
return true, nil
|
|
})
|
|
|
|
initPurchaseRequisitionLine()
|
|
}
|
|
|
|
func initPurchaseRequisitionLine() {
|
|
orm.NewModel("purchase.requisition.line", orm.ModelOpts{
|
|
Description: "Purchase Agreement Line",
|
|
Order: "id",
|
|
}).AddFields(
|
|
orm.Many2one("requisition_id", "purchase.requisition", orm.FieldOpts{
|
|
String: "Agreement", Required: true, OnDelete: orm.OnDeleteCascade,
|
|
}),
|
|
orm.Many2one("product_id", "product.product", orm.FieldOpts{
|
|
String: "Product", Required: true,
|
|
}),
|
|
orm.Float("product_qty", orm.FieldOpts{String: "Quantity"}),
|
|
orm.Float("price_unit", orm.FieldOpts{String: "Unit Price"}),
|
|
)
|
|
}
|