Files
goodie/addons/purchase/models/purchase_agreement.go
Marc 66383adf06 feat: Portal, Email Inbound, Discuss + module improvements
- 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>
2026-04-12 18:41:57 +02:00

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"}),
)
}