Skip to content

refactor: totals mixins v2#3940

Merged
turip merged 1 commit into
mainfrom
refactor/totals-mixin-v2
Mar 13, 2026
Merged

refactor: totals mixins v2#3940
turip merged 1 commit into
mainfrom
refactor/totals-mixin-v2

Conversation

@turip
Copy link
Copy Markdown
Member

@turip turip commented Mar 13, 2026

Overview

This patch moves the totals mixin to a seperate package while allowing adapters to reuse the set/map functions.

The motivation is twofold:

  • Adding credits totals was a mess due to a lot of places containing totals mixin references.
  • charges will require realizations as mixins as they will be used at different locations in the database. This approach gives us the flexibility required to maintain a consistent schema and logic on the code level.

Notes for reviewer

Summary by CodeRabbit

Release Notes

  • Refactor
    • Consolidated billing totals handling by introducing a centralized totals package with helper functions and utilities, replacing scattered per-field assignments throughout invoice creation and updates.
    • Improved code maintainability through unified totals mapping, calculation, and mutation patterns using new helpers and Ent mixin accessors.

This patch moves the totals mixin to a seperate package while allowing
adapters to reuse the set/map functions.
@turip turip requested a review from a team as a code owner March 13, 2026 09:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 13, 2026

📝 Walkthrough

Walkthrough

This PR refactors the Totals type out of the billing package into a dedicated openmeter/billing/models/totals package and introduces mixin helpers (Set, FromDB, Sum) for cleaner totals handling. It updates type references across 20+ files and adds an Ent framework extension for generating mixin accessor methods.

Changes

Cohort / File(s) Summary
Totals Package Extraction
openmeter/billing/models/totals/model.go, openmeter/billing/models/totals/mixin.go
New totals package with Totals struct, Mutator/TotalsGetter interfaces, and helper functions (Set, FromDB, Sum) for fluent totals manipulation via Ent mixins.
Ent Framework Extension
pkg/framework/entutils/entmixinaccessor/entmixinaccessor.go, pkg/framework/entutils/entmixinaccessor/mixinaccessor.tpl
New Ent extension generating accessor methods for mixin-added fields; registered in openmeter/ent/entc.go.
Invoice Adapter Refactoring
openmeter/billing/adapter/invoice.go, openmeter/billing/adapter/stdinvoicelinemapper.go, openmeter/billing/adapter/stdinvoicelines.go
Replace inline Totals field assignments with totals.Set and totals.FromDB helpers during invoice/line creation and updates.
Charge Service Updates
openmeter/billing/charges/adapter/mapper.go, openmeter/billing/charges/adapter/stdinvoice.go, openmeter/billing/charges/chargeflatfee.go, openmeter/billing/charges/stdinvoice.go
Update Totals type references from billing.Totals to totals.Totals and apply totals.Set helper in accrued usage creation.
Type Reference Updates
openmeter/billing/stdinvoice.go, openmeter/billing/stdinvoiceline.go, openmeter/billing/invoicedetailedline.go, openmeter/billing/derived.gen.go
Update public struct fields and function signatures to use totals.Totals instead of billing.Totals; regenerate derived equality helpers.
Service Layer Updates
openmeter/billing/service/invoicecalc/details.go, openmeter/billing/service/lineservice/detailedlines.go, openmeter/billing/service/lineservice/linebase.go, openmeter/billing/service/lineservice/service.go
Replace inline totals accumulation with totals.Sum helper; update function return types to totals.Totals.
Ent Schema Consolidation
openmeter/ent/schema/billing.go, openmeter/ent/schema/charges.go
Remove local TotalsMixin declaration and update all schemas to use external totals.Mixin.
Test Updates
openmeter/billing/service/lineservice/usagebasedline_test.go, test/billing/invoice_test.go
Update test helpers and fixtures to reference totals.Totals type.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

release-note/misc, kind/refactor, area/billing

Suggested reviewers

  • chrisgacsal
  • tothandras
  • GAlexIHU
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: refactoring the totals mixin to a separate package and exposing helper functions for adapter reuse.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/totals-mixin-v2
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
openmeter/billing/service/lineservice/detailedlines.go (1)

202-231: Variable shadows package name - consider renaming for clarity.

The local variable totals on line 210 shadows the imported totals package. While this works correctly (all subsequent uses like totals.CalculateTotal() refer to the local struct's method, not a package function), it can be confusing to readers.

🔧 Suggested rename for clarity
-func calculateDetailedLineTotals(line billing.DetailedLine) (totals.Totals, error) {
+func calculateDetailedLineTotals(line billing.DetailedLine) (totals.Totals, error) {
 	// Calculate the line totals
 	calc, err := line.Currency.Calculator()
 	if err != nil {
 		return totals.Totals{}, err
 	}

 	// Calculate the line totals
-	totals := totals.Totals{
+	result := totals.Totals{
 		DiscountsTotal: line.AmountDiscounts.SumAmount(calc),
 		CreditsTotal:   line.CreditsApplied.SumAmount(calc),

 		// TODO[OM-979]: implement taxes
 		TaxesInclusiveTotal: alpacadecimal.Zero,
 		TaxesExclusiveTotal: alpacadecimal.Zero,
 		TaxesTotal:          alpacadecimal.Zero,
 	}

 	amount := calc.RoundToPrecision(line.PerUnitAmount.Mul(line.Quantity))

 	switch line.Category {
 	case billing.FlatFeeCategoryCommitment:
-		totals.ChargesTotal = amount
+		result.ChargesTotal = amount
 	default:
-		totals.Amount = amount
+		result.Amount = amount
 	}

-	totals.Total = totals.CalculateTotal()
+	result.Total = result.CalculateTotal()

-	return totals, nil
+	return result, nil
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openmeter/billing/service/lineservice/detailedlines.go` around lines 202 -
231, In calculateDetailedLineTotals, the local variable named totals shadows the
imported totals package; rename the local variable (e.g., lineTotals or
totalsStruct) and update all references inside calculateDetailedLineTotals
(fields like DiscountsTotal, CreditsTotal, ChargesTotal/Amount/Total and the
call to CalculateTotal()) to use the new name so there is no confusion between
the package and the local struct.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@openmeter/billing/service/lineservice/detailedlines.go`:
- Around line 202-231: In calculateDetailedLineTotals, the local variable named
totals shadows the imported totals package; rename the local variable (e.g.,
lineTotals or totalsStruct) and update all references inside
calculateDetailedLineTotals (fields like DiscountsTotal, CreditsTotal,
ChargesTotal/Amount/Total and the call to CalculateTotal()) to use the new name
so there is no confusion between the package and the local struct.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b660ba5f-1451-44b1-858c-397df6217745

📥 Commits

Reviewing files that changed from the base of the PR and between 699c828 and e973957.

⛔ Files ignored due to path filters (1)
  • openmeter/ent/db/entmixinaccessor.go is excluded by !**/ent/db/**
📒 Files selected for processing (25)
  • openmeter/billing/adapter/invoice.go
  • openmeter/billing/adapter/stdinvoicelinemapper.go
  • openmeter/billing/adapter/stdinvoicelines.go
  • openmeter/billing/charges/adapter/mapper.go
  • openmeter/billing/charges/adapter/stdinvoice.go
  • openmeter/billing/charges/chargeflatfee.go
  • openmeter/billing/charges/stdinvoice.go
  • openmeter/billing/derived.gen.go
  • openmeter/billing/httpdriver/invoice.go
  • openmeter/billing/invoicedetailedline.go
  • openmeter/billing/models/totals/mixin.go
  • openmeter/billing/models/totals/model.go
  • openmeter/billing/service/invoicecalc/details.go
  • openmeter/billing/service/lineservice/detailedlines.go
  • openmeter/billing/service/lineservice/linebase.go
  • openmeter/billing/service/lineservice/service.go
  • openmeter/billing/service/lineservice/usagebasedline_test.go
  • openmeter/billing/stdinvoice.go
  • openmeter/billing/stdinvoiceline.go
  • openmeter/ent/entc.go
  • openmeter/ent/schema/billing.go
  • openmeter/ent/schema/charges.go
  • pkg/framework/entutils/entmixinaccessor/entmixinaccessor.go
  • pkg/framework/entutils/entmixinaccessor/mixinaccessor.tpl
  • test/billing/invoice_test.go

@turip turip added area/billing release-note/misc Miscellaneous changes labels Mar 13, 2026
@turip turip merged commit 3028994 into main Mar 13, 2026
28 of 31 checks passed
@turip turip deleted the refactor/totals-mixin-v2 branch March 13, 2026 10:12
@coderabbitai coderabbitai Bot mentioned this pull request Mar 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants