Full port of Odoo's ERP system from Python to Go, with the original Odoo JavaScript frontend (OWL framework) running against the Go server. Backend (10,691 LoC Go): - Custom ORM: CRUD, domains→SQL with JOINs, computed fields, sequences - 93 models across 14 modules (base, account, sale, stock, purchase, hr, project, crm, fleet, product, l10n_de, google_address/translate/calendar) - Auth with bcrypt + session cookies - Setup wizard (company, SKR03 chart, admin, demo data) - Double-entry bookkeeping constraint - Sale→Invoice workflow (confirm SO → generate invoice → post) - SKR03 chart of accounts (110 accounts) + German taxes (USt/VSt) - Record rules (multi-company filter) - Google integrations as opt-in modules (Maps, Translate, Calendar) Frontend: - Odoo's original OWL webclient (503 JS modules, 378 XML templates) - JS transpiled via Odoo's js_transpiler (ES modules → odoo.define) - SCSS compiled to CSS (675KB) via dart-sass - XML templates compiled to registerTemplate() JS calls - Static file serving from Odoo source addons - Login page, session management, menu navigation - Contacts list view renders with real data from PostgreSQL Infrastructure: - 14MB single binary (CGO_ENABLED=0) - Docker Compose (Go server + PostgreSQL 16) - Zero phone-home (no outbound calls to odoo.com) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
223 lines
9.7 KiB
Go
223 lines
9.7 KiB
Go
package models
|
|
|
|
import "odoo-go/pkg/orm"
|
|
|
|
// initFleetVehicle registers the fleet.vehicle model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle.py
|
|
func initFleetVehicle() {
|
|
m := orm.NewModel("fleet.vehicle", orm.ModelOpts{
|
|
Description: "Vehicle",
|
|
Order: "license_plate asc, name asc",
|
|
})
|
|
|
|
m.AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Name", Compute: "_compute_vehicle_name", Store: true}),
|
|
orm.Char("license_plate", orm.FieldOpts{String: "License Plate", Required: true, Index: true}),
|
|
orm.Char("vin_sn", orm.FieldOpts{String: "Chassis Number", Help: "Unique vehicle identification number (VIN)"}),
|
|
orm.Many2one("driver_id", "res.partner", orm.FieldOpts{String: "Driver", Index: true}),
|
|
orm.Many2one("future_driver_id", "res.partner", orm.FieldOpts{String: "Future Driver"}),
|
|
orm.Many2one("model_id", "fleet.vehicle.model", orm.FieldOpts{
|
|
String: "Model", Required: true,
|
|
}),
|
|
orm.Many2one("brand_id", "fleet.vehicle.model.brand", orm.FieldOpts{
|
|
String: "Brand", Related: "model_id.brand_id", Store: true,
|
|
}),
|
|
orm.Many2one("state_id", "fleet.vehicle.state", orm.FieldOpts{String: "State"}),
|
|
orm.Many2one("company_id", "res.company", orm.FieldOpts{
|
|
String: "Company", Required: true, Index: true,
|
|
}),
|
|
orm.Many2one("manager_id", "res.users", orm.FieldOpts{String: "Fleet Manager"}),
|
|
orm.Char("color", orm.FieldOpts{String: "Color"}),
|
|
orm.Integer("seats", orm.FieldOpts{String: "Seats Number"}),
|
|
orm.Integer("doors", orm.FieldOpts{String: "Doors Number", Default: 5}),
|
|
orm.Selection("transmission", []orm.SelectionItem{
|
|
{Value: "manual", Label: "Manual"},
|
|
{Value: "automatic", Label: "Automatic"},
|
|
}, orm.FieldOpts{String: "Transmission"}),
|
|
orm.Selection("fuel_type", []orm.SelectionItem{
|
|
{Value: "gasoline", Label: "Gasoline"},
|
|
{Value: "diesel", Label: "Diesel"},
|
|
{Value: "lpg", Label: "LPG"},
|
|
{Value: "electric", Label: "Electric"},
|
|
{Value: "hybrid", Label: "Hybrid"},
|
|
}, orm.FieldOpts{String: "Fuel Type"}),
|
|
orm.Integer("power", orm.FieldOpts{String: "Power (kW)"}),
|
|
orm.Integer("horsepower", orm.FieldOpts{String: "Horsepower"}),
|
|
orm.Float("co2", orm.FieldOpts{String: "CO2 Emissions (g/km)"}),
|
|
orm.Float("horsepower_tax", orm.FieldOpts{String: "Horsepower Taxation"}),
|
|
orm.Float("odometer", orm.FieldOpts{String: "Last Odometer", Compute: "_compute_odometer"}),
|
|
orm.Selection("odometer_unit", []orm.SelectionItem{
|
|
{Value: "kilometers", Label: "km"},
|
|
{Value: "miles", Label: "mi"},
|
|
}, orm.FieldOpts{String: "Odometer Unit", Default: "kilometers", Required: true}),
|
|
orm.Date("acquisition_date", orm.FieldOpts{String: "Immatriculation Date"}),
|
|
orm.Date("first_contract_date", orm.FieldOpts{String: "First Contract Date"}),
|
|
orm.Many2many("tag_ids", "fleet.vehicle.tag", orm.FieldOpts{String: "Tags"}),
|
|
orm.One2many("log_contracts", "fleet.vehicle.log.contract", "vehicle_id", orm.FieldOpts{String: "Contracts"}),
|
|
orm.One2many("log_services", "fleet.vehicle.log.services", "vehicle_id", orm.FieldOpts{String: "Services"}),
|
|
orm.Boolean("active", orm.FieldOpts{String: "Active", Default: true}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleModel registers the fleet.vehicle.model model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle_model.py
|
|
func initFleetVehicleModel() {
|
|
m := orm.NewModel("fleet.vehicle.model", orm.ModelOpts{
|
|
Description: "Model of a vehicle",
|
|
Order: "name asc",
|
|
})
|
|
|
|
m.AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Model Name", Required: true}),
|
|
orm.Many2one("brand_id", "fleet.vehicle.model.brand", orm.FieldOpts{
|
|
String: "Manufacturer", Required: true, Index: true,
|
|
}),
|
|
orm.Many2one("category_id", "fleet.vehicle.model.category", orm.FieldOpts{String: "Category"}),
|
|
orm.Integer("seats", orm.FieldOpts{String: "Seats Number"}),
|
|
orm.Integer("doors", orm.FieldOpts{String: "Doors Number", Default: 5}),
|
|
orm.Char("color", orm.FieldOpts{String: "Color"}),
|
|
orm.Selection("transmission", []orm.SelectionItem{
|
|
{Value: "manual", Label: "Manual"},
|
|
{Value: "automatic", Label: "Automatic"},
|
|
}, orm.FieldOpts{String: "Transmission"}),
|
|
orm.Selection("fuel_type", []orm.SelectionItem{
|
|
{Value: "gasoline", Label: "Gasoline"},
|
|
{Value: "diesel", Label: "Diesel"},
|
|
{Value: "lpg", Label: "LPG"},
|
|
{Value: "electric", Label: "Electric"},
|
|
{Value: "hybrid", Label: "Hybrid"},
|
|
}, orm.FieldOpts{String: "Fuel Type"}),
|
|
orm.Integer("power", orm.FieldOpts{String: "Power (kW)"}),
|
|
orm.Integer("horsepower", orm.FieldOpts{String: "Horsepower"}),
|
|
orm.Float("co2", orm.FieldOpts{String: "CO2 Emissions (g/km)"}),
|
|
orm.Binary("image_128", orm.FieldOpts{String: "Image"}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleModelBrand registers the fleet.vehicle.model.brand model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle_model.py FleetVehicleModelBrand
|
|
func initFleetVehicleModelBrand() {
|
|
orm.NewModel("fleet.vehicle.model.brand", orm.ModelOpts{
|
|
Description: "Brand of the vehicle",
|
|
Order: "name asc",
|
|
}).AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Make", Required: true}),
|
|
orm.Binary("image_128", orm.FieldOpts{String: "Image"}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleModelCategory registers the fleet.vehicle.model.category model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle_model.py FleetVehicleModelCategory
|
|
func initFleetVehicleModelCategory() {
|
|
orm.NewModel("fleet.vehicle.model.category", orm.ModelOpts{
|
|
Description: "Category of the vehicle",
|
|
Order: "sequence asc, id asc",
|
|
}).AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Category Name", Required: true}),
|
|
orm.Integer("sequence", orm.FieldOpts{String: "Sequence", Default: 10}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleState registers the fleet.vehicle.state model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle.py FleetVehicleState
|
|
func initFleetVehicleState() {
|
|
orm.NewModel("fleet.vehicle.state", orm.ModelOpts{
|
|
Description: "Vehicle State",
|
|
Order: "sequence asc",
|
|
}).AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "State Name", Required: true, Translate: true}),
|
|
orm.Integer("sequence", orm.FieldOpts{String: "Sequence", Default: 10}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleTag registers the fleet.vehicle.tag model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle.py FleetVehicleTag
|
|
func initFleetVehicleTag() {
|
|
orm.NewModel("fleet.vehicle.tag", orm.ModelOpts{
|
|
Description: "Vehicle Tag",
|
|
Order: "name",
|
|
}).AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Tag Name", Required: true, Translate: true}),
|
|
orm.Integer("color", orm.FieldOpts{String: "Color Index"}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleLogContract registers the fleet.vehicle.log.contract model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle_log_contract.py
|
|
func initFleetVehicleLogContract() {
|
|
m := orm.NewModel("fleet.vehicle.log.contract", orm.ModelOpts{
|
|
Description: "Vehicle Contract",
|
|
Order: "state desc, expiration_date",
|
|
})
|
|
|
|
m.AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Name", Compute: "_compute_contract_name", Store: true}),
|
|
orm.Many2one("vehicle_id", "fleet.vehicle", orm.FieldOpts{
|
|
String: "Vehicle", Required: true, Index: true,
|
|
}),
|
|
orm.Many2one("cost_subtype_id", "fleet.service.type", orm.FieldOpts{String: "Type"}),
|
|
orm.Float("amount", orm.FieldOpts{String: "Recurring Cost"}),
|
|
orm.Date("date", orm.FieldOpts{String: "Date"}),
|
|
orm.Date("start_date", orm.FieldOpts{String: "Contract Start Date"}),
|
|
orm.Date("expiration_date", orm.FieldOpts{String: "Contract Expiration Date"}),
|
|
orm.Selection("state", []orm.SelectionItem{
|
|
{Value: "futur", Label: "Incoming"},
|
|
{Value: "open", Label: "In Progress"},
|
|
{Value: "expired", Label: "Expired"},
|
|
{Value: "closed", Label: "Closed"},
|
|
}, orm.FieldOpts{String: "Status", Default: "open"}),
|
|
orm.Float("cost_generated", orm.FieldOpts{String: "Recurring Cost Amount"}),
|
|
orm.Selection("cost_frequency", []orm.SelectionItem{
|
|
{Value: "no", Label: "No"},
|
|
{Value: "daily", Label: "Daily"},
|
|
{Value: "weekly", Label: "Weekly"},
|
|
{Value: "monthly", Label: "Monthly"},
|
|
{Value: "yearly", Label: "Yearly"},
|
|
}, orm.FieldOpts{String: "Recurring Cost Frequency", Default: "monthly"}),
|
|
orm.Many2one("insurer_id", "res.partner", orm.FieldOpts{String: "Vendor"}),
|
|
orm.Char("ins_ref", orm.FieldOpts{String: "Reference"}),
|
|
orm.Many2one("company_id", "res.company", orm.FieldOpts{
|
|
String: "Company", Required: true, Index: true,
|
|
}),
|
|
orm.Boolean("active", orm.FieldOpts{String: "Active", Default: true}),
|
|
)
|
|
}
|
|
|
|
// initFleetVehicleLogServices registers the fleet.vehicle.log.services model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_vehicle_log_services.py
|
|
func initFleetVehicleLogServices() {
|
|
m := orm.NewModel("fleet.vehicle.log.services", orm.ModelOpts{
|
|
Description: "Vehicle Services Log",
|
|
Order: "date desc",
|
|
})
|
|
|
|
m.AddFields(
|
|
orm.Many2one("vehicle_id", "fleet.vehicle", orm.FieldOpts{
|
|
String: "Vehicle", Required: true, Index: true,
|
|
}),
|
|
orm.Many2one("cost_subtype_id", "fleet.service.type", orm.FieldOpts{String: "Type"}),
|
|
orm.Float("amount", orm.FieldOpts{String: "Cost"}),
|
|
orm.Date("date", orm.FieldOpts{String: "Date"}),
|
|
orm.Text("description", orm.FieldOpts{String: "Description"}),
|
|
orm.Many2one("vendor_id", "res.partner", orm.FieldOpts{String: "Vendor"}),
|
|
orm.Many2one("company_id", "res.company", orm.FieldOpts{
|
|
String: "Company", Required: true, Index: true,
|
|
}),
|
|
)
|
|
}
|
|
|
|
// initFleetServiceType registers the fleet.service.type model.
|
|
// Mirrors: odoo/addons/fleet/models/fleet_service_type.py
|
|
func initFleetServiceType() {
|
|
orm.NewModel("fleet.service.type", orm.ModelOpts{
|
|
Description: "Fleet Service Type",
|
|
Order: "name",
|
|
}).AddFields(
|
|
orm.Char("name", orm.FieldOpts{String: "Name", Required: true, Translate: true}),
|
|
orm.Selection("category", []orm.SelectionItem{
|
|
{Value: "contract", Label: "Contract"},
|
|
{Value: "service", Label: "Service"},
|
|
}, orm.FieldOpts{String: "Category", Required: true}),
|
|
)
|
|
}
|