Commit Graph

13 Commits

Author SHA1 Message Date
Marc
66383adf06 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>
2026-04-12 18:41:57 +02:00
Marc
5973a445c0 Fix DB setup: savepoints for seed, deduplicate AddField, field fixes
Critical fixes for fresh DB creation:
- AddField now skips duplicates (ExtendModel from multiple modules
  was adding same field twice → duplicate column error)
- SeedWithSetup wrapped in savepoints per seed block (one failing
  INSERT no longer aborts entire transaction)
- sale.order.cancel: display_name → cancel_reason (avoid magic field clash)
- purchase: removed duplicate supplier_rank (already on res.partner)
- safeExec helper: SAVEPOINT + ROLLBACK TO on error

Fresh DB creation now works:
- /web/database/create → creates all tables, seeds data, returns session
- Login works immediately after creation
- All 191 models, 51 menus, 34 actions seeded

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 01:37:10 +02:00
Marc
fad2a37d1c Expand Sale/Purchase/Project + 102 ORM tests — +4633 LOC
Sale (1177→2321 LOC):
- Quotation templates (apply to order, option lines)
- Sales reports (by month, product, customer, salesperson, category)
- Advance payment wizard (delivered/percentage/fixed modes)
- SO cancel wizard, discount wizard
- action_quotation_sent, action_lock/unlock, preview_quotation
- Line computes: invoice_status, price_reduce, untaxed_amount
- Partner extension: sale_order_total

Purchase (478→1424 LOC):
- Purchase reports (by month, category, bill status, receipt analysis)
- Receipt creation from PO (action_create_picking)
- 3-way matching: action_view_picking, action_view_invoice
- button_approve, button_done, action_rfq_send
- Line computes: price_subtotal/total with tax, product onchange
- Partner extension: purchase_order_count/total

Project (218→1161 LOC):
- Project updates (status tracking: on_track/at_risk/off_track)
- Milestones (deadline, reached tracking, task count)
- Timesheet integration (account.analytic.line extension)
- Timesheet reports (by project, employee, task, week)
- Task recurrence model
- Task: planned/effective/remaining hours, progress, subtask hours
- Project: allocated/remaining hours, profitability actions

ORM Tests (102 tests, 0→1257 LOC):
- domain_test.go: 32 tests (compile, operators, AND/OR/NOT, null)
- field_test.go: 15 tests (IsCopyable, SQLType, IsRelational, IsStored)
- model_test.go: 21 tests (NewModel, AddFields, RegisterMethod, ExtendModel)
- domain_parse_test.go: 21 tests (parse Python domain strings)
- sanitize_test.go: 13 tests (false→nil, type conversions)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:39:41 +02:00
Marc
b8fa4719ad Deep dive: Account, Stock, Sale, Purchase — +800 LOC business logic
Account:
- Multi-currency: company_currency_id, amount_total_signed
- Lock dates on res.company (period, fiscal year, tax) + enforcement in action_post
- Recurring entries: account.move.recurring with action_generate (copy+advance)
- Tax groups: amount_type='group' computes child taxes with include_base_amount
- ComputeTaxes batch function, findTaxAccount helper

Stock:
- Lot/Serial tracking: enhanced stock.lot with expiration dates + qty compute
- Routes: stock.route model with product/category/warehouse selectable flags
- Rules: stock.rule model with pull/push/buy/manufacture actions + procure methods
- Returns: action_return on picking (swap locations, copy moves)
- Product tracking extension (none/lot/serial) + route_ids M2M

Sale:
- Pricelist: get_product_price with fixed/percentage/formula computation
- Margin: purchase_price, margin, margin_percent on line + order totals
- Down payments: action_create_down_payment (deposit invoice at X%)

Purchase:
- 3-way matching: action_create_bill now updates qty_invoiced on PO lines
- Purchase agreements: purchase.requisition + line with state machine

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:05:39 +02:00
Marc
2e5a550069 Add _inherit (ExtendModel) + Inverse fields + sale extends partner
ORM:
- ExtendModel(name) retrieves existing model for extension (mirrors
  Python _inherit without _name). Panics on missing model.
- RegisterInverse(fieldName, fn) convenience for computed write-back
- Inverse field handling in Write(): caches new value, calls inverse
  method so computed fields can be written back

Sale module:
- Extends res.partner with sale_order_ids (O2M) and sale_order_count
  (computed) via ExtendModel — demonstrates real _inherit pattern

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:23:40 +02:00
Marc
cc1f150732 Deepen all business modules: methods, validations, workflows
Account:
- action_post: partner validation, line count check, sequence number
  assignment (JOURNAL/YYYY/NNNN format)
- action_register_payment: opens payment wizard from invoice
- remove_move_reconcile: undo reconciliation, reset residuals
- Register Payment button in invoice form (visible when posted+unpaid)

Sale:
- action_cancel: cancels linked draft invoices + SO state
- action_draft: reset cancelled SO to draft
- action_view_invoice: navigate to linked invoices
- Cancel/Reset buttons in form view header

Purchase:
- button_draft: reset cancelled PO to draft
- action_create_bill already existed

Stock:
- action_cancel on picking: cancels moves + picking state

CRM:
- action_set_won_rainbowman: sets Won stage + rainbow effect
- convert_opportunity: lead→opportunity type switch

HR:
- hr.contract model (name, employee, wage, dates, state)

Project:
- action_blocked on task (kanban_state)
- Task stage seed data (New, In Progress, Done, Cancelled)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:58:01 +02:00
Marc
5d48737c9d Implement core business logic depth: reconciliation, quants, invoicing
Account Reconciliation Engine:
- reconcile() method on account.move.line matches debit↔credit lines
- Creates account.partial.reconcile records for each match
- Detects full reconciliation (all residuals=0) → account.full.reconcile
- updatePaymentState() tracks paid/partial/not_paid on invoices
- Payment register wizard now creates journal entries + reconciles

Stock Quant Reservation:
- assignMove() reserves products from source location quants
- getAvailableQty() queries unreserved on-hand stock
- _action_confirm → confirmed + auto-assigns if stock available
- _action_assign creates stock.move.line reservations
- _action_done updates quants (decrease source, increase dest)
- button_validate on picking delegates to move._action_done
- Clears reserved_quantity on completion

Sale Invoice Creation (rewritten):
- Proper debit/credit/balance on invoice lines
- Tax computation from SO line M2M tax_ids (percent/fixed/division)
- Revenue account lookup (SKR03 8300 with fallbacks)
- amount_residual set on receivable line (enables reconciliation)
- qty_invoiced tracking on SO lines
- Line amount computes now include tax in price_total

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:25:32 +02:00
Marc
15cccce6d5 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>
2026-04-02 21:55:25 +02:00
Marc
03fd58a852 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>
2026-04-02 20:11:45 +02:00
Marc
b57176de2f Bring odoo-go to ~70%: read_group, record rules, admin, sessions
Phase 1: read_group/web_read_group with SQL GROUP BY, aggregates
  (sum/avg/min/max/count/array_agg/sum_currency), date granularity,
  M2O groupby resolution to [id, display_name].

Phase 2: Record rules with domain_force parsing (Python literal parser),
  global AND + group OR merging. Domain operators: child_of, parent_of,
  any, not any compiled to SQL hierarchy/EXISTS queries.

Phase 3: Button dispatch via /web/dataset/call_button, method return
  values interpreted as actions. Payment register wizard
  (account.payment.register) for sale→invoice→pay flow.

Phase 4: ir.filters, ir.default, product fields expanded, SO line
  product_id onchange, ir_model+ir_model_fields DB seeding.

Phase 5: CSV export (/web/export/csv), attachment upload/download
  via ir.attachment, fields_get with aggregator hints.

Admin/System: Session persistence (PostgreSQL-backed), ir.config_parameter
  with get_param/set_param, ir.cron, ir.logging, res.lang, res.config.settings
  with company-related fields, Settings form view. Technical menu with
  Views/Actions/Parameters/Security/Logging sub-menus. User change_password,
  preferences. Password never exposed in UI/API.

Bugfixes: false→nil for varchar/int fields, int32 in toInt64, call_button
  route with trailing slash, create_invoices returns action, search view
  always included, get_formview_action, name_create, ir.http stub.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:26:08 +02:00
Marc
70649c4b4e Fix P0-P2 bugs: sale.order M2M, display_name, DefaultGet
P0: Fix sale.order creation (was completely broken)
- Corrected M2M junction table name from sale_order_line_account_tax_rel
  to account_tax_sale_order_line_rel (ORM sorts alphabetically)
- Added fallback in BeforeCreate if sequence generation fails

P1: Add display_name as magic field on ALL models
- Added to addMagicFields() in pkg/orm/model.go (like Python BaseModel)
- Computed on-the-fly in Read() from recName field, no DB column
- Removed explicit display_name from res.partner (now auto-inherited)

P2: Add DefaultGet hooks for sale.order and purchase.order
- Sets company_id, currency_id, date_order/date_planned from environment
- Follows same pattern as account.move's DefaultGet

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 02:28:49 +02:00
Marc
9c444061fd Backend improvements: views, fields_get, session, RPC stubs
- Improved auto-generated list/form/search views with priority fields,
  two-column form layout, statusbar widget, notebook for O2M fields
- Enhanced fields_get with currency_field, compute, related metadata
- Fixed session handling: handleSessionInfo/handleSessionCheck use real
  session from cookie instead of hardcoded values
- Added read_progress_bar and activity_format RPC stubs
- Improved bootstrap translations with lang_parameters
- Added "contacts" to session modules list

Server starts successfully: 14 modules, 93 models, 378 XML templates,
503 JS modules transpiled — all from local frontend/ directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:16:26 +02:00
Marc
0ed29fe2fd Odoo ERP ported to Go — complete backend + original OWL frontend
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>
2026-03-31 01:45:09 +02:00