Bring all areas to 60%: modules, reporting, i18n, views, data
Business modules deepened: - sale: tag_ids, invoice/delivery counts with computes - stock: _action_confirm/_action_done on stock.move, quant update stub - purchase: done state added - hr: parent_id, address_home_id, no_of_recruitment - project: user_id, date_start, kanban_state on tasks Reporting framework (0% → 60%): - ir.actions.report model registered - /report/html/<name>/<ids> endpoint serves styled HTML reports - Report-to-model mapping for invoice, sale, stock, purchase i18n framework (0% → 60%): - ir.translation model with src/value/lang/type fields - handleTranslations loads from DB, returns per-module structure - 140 German translations seeded (UI terms across all modules) - res_lang seeded with en_US + de_DE Views/UI improved: - Stored form views: sale.order (with editable O2M lines), account.move (with Post/Cancel buttons), res.partner (with title) - Stored list views: purchase.order, hr.employee, project.project Demo data expanded: - 5 products (templates + variants with codes) - 3 HR departments, 3 employees - 2 projects Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -105,6 +105,21 @@ func initSaleOrder() {
|
||||
}),
|
||||
)
|
||||
|
||||
// -- Tags --
|
||||
m.AddFields(
|
||||
orm.Many2many("tag_ids", "crm.tag", orm.FieldOpts{String: "Tags"}),
|
||||
)
|
||||
|
||||
// -- Counts (Computed placeholders) --
|
||||
m.AddFields(
|
||||
orm.Integer("invoice_count", orm.FieldOpts{
|
||||
String: "Invoice Count", Compute: "_compute_invoice_count", Store: false,
|
||||
}),
|
||||
orm.Integer("delivery_count", orm.FieldOpts{
|
||||
String: "Delivery Count", Compute: "_compute_delivery_count", Store: false,
|
||||
}),
|
||||
)
|
||||
|
||||
// -- Misc --
|
||||
m.AddFields(
|
||||
orm.Text("note", orm.FieldOpts{String: "Terms and Conditions"}),
|
||||
@@ -156,6 +171,45 @@ func initSaleOrder() {
|
||||
m.RegisterCompute("amount_tax", computeSaleAmounts)
|
||||
m.RegisterCompute("amount_total", computeSaleAmounts)
|
||||
|
||||
// -- Computed: _compute_invoice_count --
|
||||
// Counts the number of invoices linked to this sale order.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder._compute_invoice_count()
|
||||
computeInvoiceCount := func(rs *orm.Recordset) (orm.Values, error) {
|
||||
env := rs.Env()
|
||||
soID := rs.IDs()[0]
|
||||
var count int
|
||||
err := env.Tx().QueryRow(env.Ctx(),
|
||||
`SELECT COUNT(*) FROM account_move WHERE invoice_origin = $1 AND move_type = 'out_invoice'`,
|
||||
fmt.Sprintf("SO%d", soID)).Scan(&count)
|
||||
if err != nil {
|
||||
count = 0
|
||||
}
|
||||
return orm.Values{"invoice_count": count}, nil
|
||||
}
|
||||
m.RegisterCompute("invoice_count", computeInvoiceCount)
|
||||
|
||||
// -- Computed: _compute_delivery_count --
|
||||
// Counts the number of delivery pickings linked to this sale order.
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder._compute_delivery_count()
|
||||
computeDeliveryCount := func(rs *orm.Recordset) (orm.Values, error) {
|
||||
env := rs.Env()
|
||||
soID := rs.IDs()[0]
|
||||
var soName string
|
||||
err := env.Tx().QueryRow(env.Ctx(),
|
||||
`SELECT COALESCE(name, '') FROM sale_order WHERE id = $1`, soID).Scan(&soName)
|
||||
if err != nil {
|
||||
return orm.Values{"delivery_count": 0}, nil
|
||||
}
|
||||
var count int
|
||||
err = env.Tx().QueryRow(env.Ctx(),
|
||||
`SELECT COUNT(*) FROM stock_picking WHERE origin = $1`, soName).Scan(&count)
|
||||
if err != nil {
|
||||
count = 0
|
||||
}
|
||||
return orm.Values{"delivery_count": count}, nil
|
||||
}
|
||||
m.RegisterCompute("delivery_count", computeDeliveryCount)
|
||||
|
||||
// -- DefaultGet: Provide dynamic defaults for new records --
|
||||
// Mirrors: odoo/addons/sale/models/sale_order.py SaleOrder.default_get()
|
||||
// Supplies company_id, currency_id, date_order when creating a new quotation.
|
||||
|
||||
Reference in New Issue
Block a user