Files
goodie/pkg/tools/config.go
Marc 2c7c1e6c88 PDF invoice reports + SMTP email sending
PDF Reports:
- Professional invoice HTML renderer (company header, partner address,
  styled line items, totals, Odoo-purple branding, A4 @page CSS)
- wkhtmltopdf installed in Docker runtime stage for real PDF generation
- Print button on invoice form (opens PDF in new tab)
- Exported HtmlToPDF/RenderInvoiceHTML for cross-package use

SMTP Email:
- SendEmail + SendEmailWithAttachments with MIME multipart support
- Base64 file attachments
- Config via ODOO_SMTP_HOST/PORT/USER/PASSWORD/FROM env vars
- LoadSMTPConfig helper, nil auth for relay servers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 13:58:19 +02:00

141 lines
3.2 KiB
Go

// Package tools provides configuration and utility functions.
// Mirrors: odoo/tools/config.py
package tools
import (
"fmt"
"os"
"strconv"
)
// Config holds the server configuration.
// Mirrors: odoo/tools/config.py configmanager
type Config struct {
// Database
DBHost string
DBPort int
DBUser string
DBPassword string
DBName string
DBSSLMode string
// Server
HTTPInterface string
HTTPPort int
Workers int
DataDir string
// Modules
AddonsPath []string
FrontendDir string // Directory containing embedded frontend assets (JS/CSS/XML/fonts)
BuildDir string // Directory for compiled assets (SCSS→CSS)
WithoutDemo bool
// Logging
LogLevel string
// Limits
LimitMemorySoft int64
LimitTimeReal int
// SMTP Email
SMTPHost string
SMTPPort int
SMTPUser string
SMTPPassword string
SMTPFrom string
}
// DefaultConfig returns a configuration with default values.
// Mirrors: odoo/tools/config.py _default_options
func DefaultConfig() *Config {
return &Config{
DBHost: "localhost",
DBPort: 5432,
DBUser: "odoo",
DBPassword: "odoo",
DBName: "odoo",
DBSSLMode: "disable",
HTTPInterface: "0.0.0.0",
HTTPPort: 8069,
Workers: 0,
DataDir: "/var/lib/odoo",
LogLevel: "info",
SMTPPort: 587,
}
}
// LoadFromEnv overrides config values from environment variables.
// Mirrors: odoo/tools/config.py _env_options (ODOO_* prefix)
func (c *Config) LoadFromEnv() {
if v := os.Getenv("ODOO_DB_HOST"); v != "" {
c.DBHost = v
}
// Also support Docker-style env vars (HOST, USER, PASSWORD)
if v := os.Getenv("HOST"); v != "" {
c.DBHost = v
}
if v := os.Getenv("ODOO_DB_PORT"); v != "" {
if port, err := strconv.Atoi(v); err == nil {
c.DBPort = port
}
}
if v := os.Getenv("ODOO_DB_USER"); v != "" {
c.DBUser = v
}
if v := os.Getenv("USER"); v != "" && os.Getenv("ODOO_DB_USER") == "" {
c.DBUser = v
}
if v := os.Getenv("ODOO_DB_PASSWORD"); v != "" {
c.DBPassword = v
}
if v := os.Getenv("PASSWORD"); v != "" && os.Getenv("ODOO_DB_PASSWORD") == "" {
c.DBPassword = v
}
if v := os.Getenv("ODOO_DB_NAME"); v != "" {
c.DBName = v
}
if v := os.Getenv("ODOO_HTTP_PORT"); v != "" {
if port, err := strconv.Atoi(v); err == nil {
c.HTTPPort = port
}
}
if v := os.Getenv("ODOO_DATA_DIR"); v != "" {
c.DataDir = v
}
if v := os.Getenv("ODOO_LOG_LEVEL"); v != "" {
c.LogLevel = v
}
if v := os.Getenv("ODOO_FRONTEND_DIR"); v != "" {
c.FrontendDir = v
}
if v := os.Getenv("ODOO_BUILD_DIR"); v != "" {
c.BuildDir = v
}
if v := os.Getenv("ODOO_SMTP_HOST"); v != "" {
c.SMTPHost = v
}
if v := os.Getenv("ODOO_SMTP_PORT"); v != "" {
if p, err := strconv.Atoi(v); err == nil {
c.SMTPPort = p
}
}
if v := os.Getenv("ODOO_SMTP_USER"); v != "" {
c.SMTPUser = v
}
if v := os.Getenv("ODOO_SMTP_PASSWORD"); v != "" {
c.SMTPPassword = v
}
if v := os.Getenv("ODOO_SMTP_FROM"); v != "" {
c.SMTPFrom = v
}
}
// DSN returns the PostgreSQL connection string.
func (c *Config) DSN() string {
return fmt.Sprintf(
"postgres://%s:%s@%s:%d/%s?sslmode=%s",
c.DBUser, c.DBPassword, c.DBHost, c.DBPort, c.DBName, c.DBSSLMode,
)
}