Add stored form views, SO line compute, invoice line demo data
- Stored form views for CRM lead, purchase order, HR employee, project - SO line price_subtotal compute (qty * price * (1 - discount/100)) - Invoice lines seeded for demo invoices (product + tax + receivable) - O2M lines now visible in form views (sale orders + invoices) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -605,6 +605,26 @@ func initSaleOrderLine() {
|
||||
orm.Integer("sequence", orm.FieldOpts{String: "Sequence", Default: 10}),
|
||||
)
|
||||
|
||||
// -- Computed: _compute_amount (line subtotal/total) --
|
||||
// Computes price_subtotal and price_total from qty, price, discount.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order_line.py SaleOrderLine._compute_amount()
|
||||
computeLineAmount := func(rs *orm.Recordset) (orm.Values, error) {
|
||||
env := rs.Env()
|
||||
lineID := rs.IDs()[0]
|
||||
var qty, price, discount float64
|
||||
env.Tx().QueryRow(env.Ctx(),
|
||||
`SELECT COALESCE(product_uom_qty, 0), COALESCE(price_unit, 0), COALESCE(discount, 0)
|
||||
FROM sale_order_line WHERE id = $1`, lineID,
|
||||
).Scan(&qty, &price, &discount)
|
||||
subtotal := qty * price * (1 - discount/100)
|
||||
return orm.Values{
|
||||
"price_subtotal": subtotal,
|
||||
"price_total": subtotal, // TODO: add tax amount for price_total
|
||||
}, nil
|
||||
}
|
||||
m.RegisterCompute("price_subtotal", computeLineAmount)
|
||||
m.RegisterCompute("price_total", computeLineAmount)
|
||||
|
||||
// -- Delivery & Invoicing Quantities --
|
||||
m.AddFields(
|
||||
orm.Float("qty_delivered", orm.FieldOpts{String: "Delivered Quantity"}),
|
||||
|
||||
@@ -442,12 +442,12 @@ func (s *Server) handleReadGroup(rs *orm.Recordset, params CallKWParams) (interf
|
||||
// web_read_group: also get total group count (without limit/offset)
|
||||
totalLen := len(results)
|
||||
if opts.Limit > 0 || opts.Offset > 0 {
|
||||
// Re-query without limit/offset to get total
|
||||
allResults, err := rs.ReadGroup(domain, groupby, []string{"__count"})
|
||||
if err == nil {
|
||||
totalLen = len(allResults)
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"groups": groups,
|
||||
"length": totalLen,
|
||||
|
||||
@@ -687,7 +687,136 @@ func seedViews(ctx context.Context, tx pgx.Tx) {
|
||||
<field name="partner_id"/>
|
||||
<field name="company_id"/>
|
||||
<field name="active"/>
|
||||
</list>', 16, true, 'primary')
|
||||
</list>', 16, true, 'primary'),
|
||||
|
||||
('lead.form', 'crm.lead', 'form', '<form>
|
||||
<header>
|
||||
<button name="action_set_won" string="Won" type="object" class="btn-primary" invisible="stage_id != false"/>
|
||||
<button name="action_set_lost" string="Lost" type="object" invisible="stage_id != false"/>
|
||||
<field name="stage_id" widget="statusbar" options="{''clickable'': ''1''}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title"><h1><field name="name" placeholder="Opportunity..."/></h1></div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id"/>
|
||||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="expected_revenue"/>
|
||||
<field name="probability"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="priority"/>
|
||||
<field name="company_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Notes">
|
||||
<field name="description"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>', 10, true, 'primary'),
|
||||
|
||||
('purchase.form', 'purchase.order', 'form', '<form>
|
||||
<header>
|
||||
<button name="button_confirm" string="Confirm Order" type="object" class="btn-primary" invisible="state != ''draft''"/>
|
||||
<field name="state" widget="statusbar" clickable="1"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title"><h1><field name="name"/></h1></div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id"/>
|
||||
<field name="date_order"/>
|
||||
<field name="company_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="currency_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Products">
|
||||
<field name="order_line">
|
||||
<list editable="bottom">
|
||||
<field name="product_id"/>
|
||||
<field name="name"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="price_subtotal"/>
|
||||
</list>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
<group>
|
||||
<group class="oe_subtotal_footer">
|
||||
<field name="amount_untaxed"/>
|
||||
<field name="amount_tax"/>
|
||||
<field name="amount_total" class="oe_subtotal_footer_separator"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>', 10, true, 'primary'),
|
||||
|
||||
('employee.form', 'hr.employee', 'form', '<form>
|
||||
<sheet>
|
||||
<div class="oe_title"><h1><field name="name" placeholder="Employee Name"/></h1></div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="job_id"/>
|
||||
<field name="department_id"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="coach_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="work_email"/>
|
||||
<field name="work_phone"/>
|
||||
<field name="mobile_phone"/>
|
||||
<field name="company_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Personal Information">
|
||||
<group>
|
||||
<group>
|
||||
<field name="gender"/>
|
||||
<field name="birthday"/>
|
||||
<field name="marital"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="identification_id"/>
|
||||
<field name="country_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>', 10, true, 'primary'),
|
||||
|
||||
('project.form', 'project.project', 'form', '<form>
|
||||
<sheet>
|
||||
<div class="oe_title"><h1><field name="name" placeholder="Project Name"/></h1></div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="company_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date_start"/>
|
||||
<field name="date"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Description">
|
||||
<field name="description"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>', 10, true, 'primary')
|
||||
ON CONFLICT DO NOTHING`)
|
||||
|
||||
// Settings form view
|
||||
|
||||
Reference in New Issue
Block a user