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>
This commit is contained in:
Marc
2026-04-12 18:41:57 +02:00
parent 2c7c1e6c88
commit 66383adf06
87 changed files with 14696 additions and 654 deletions

View File

@@ -127,9 +127,28 @@ func initIrActions() {
{Value: "object_write", Label: "Update Record"},
{Value: "object_create", Label: "Create Record"},
{Value: "multi", Label: "Execute Several Actions"},
{Value: "email", Label: "Send Email"},
}, orm.FieldOpts{String: "Action To Do", Default: "code", Required: true}),
orm.Text("code", orm.FieldOpts{String: "Code"}),
orm.Many2many("groups_id", "res.groups", orm.FieldOpts{String: "Groups"}),
// Automated action fields
orm.Selection("trigger", []orm.SelectionItem{
{Value: "on_create", Label: "On Creation"},
{Value: "on_write", Label: "On Update"},
{Value: "on_create_or_write", Label: "On Creation & Update"},
{Value: "on_unlink", Label: "On Deletion"},
{Value: "on_time", Label: "Based on Time Condition"},
}, orm.FieldOpts{String: "Trigger"}),
orm.Boolean("active", orm.FieldOpts{String: "Active", Default: true}),
// object_write: fields to update
orm.Text("update_field_id", orm.FieldOpts{String: "Field to Update"}),
orm.Char("update_value", orm.FieldOpts{String: "Value"}),
// email: template fields
orm.Char("email_to", orm.FieldOpts{String: "Email To", Help: "Field name on the record (e.g. email, partner_id.email)"}),
orm.Char("email_subject", orm.FieldOpts{String: "Email Subject"}),
orm.Text("email_body", orm.FieldOpts{String: "Email Body", Help: "HTML body. Use {{field_name}} for record values."}),
// filter domain
orm.Text("filter_domain", orm.FieldOpts{String: "Filter Domain", Help: "Only trigger when record matches this domain"}),
)
}