-
Notifications
You must be signed in to change notification settings - Fork 152
feat: persist rate card discounts #2588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughThis pull request integrates support for rate card discounts across the billing system. It adds new discount fields—namely Changes
Possibly related PRs
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (1.64.8)Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2 🔧 SQLFluff (3.3.0)tools/migrate/migrations/20250404145234_billing-line-ratecard-discounts.down.sqlUser Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects: tools/migrate/migrations/20250404145234_billing-line-ratecard-discounts.up.sqlUser Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects: ✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
5c92d3f to
e3cef1f
Compare
|
|
||
| TaxConfig *TaxConfig `json:"taxOverrides,omitempty"` | ||
| TaxConfig *TaxConfig `json:"taxOverrides,omitempty"` | ||
| RateCardDiscounts productcatalog.Discounts `json:"rateCardDiscounts,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would collide with the Line's Discounts, if we don't name it RateCardDiscounts. For now this is fine, but after the discount entity is there we need to refactor the internal Line entity, but that's a bigger lift.
f66be2a to
adf6375
Compare
adf6375 to
c62a113
Compare
d27dfb1 to
291ce35
Compare
291ce35 to
5fc8f56
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
openmeter/ent/db/billinginvoiceline_update.go (2)
355-365: Consider adding SetNillableRatecardDiscounts method for consistencyOther fields in this file follow a pattern of having both
Set*andSetNillable*methods (likeSetTaxConfig/SetNillableTaxConfig). For consistency, consider adding aSetNillableRatecardDiscountsmethod that only sets the value if the provided pointer is not nil.// SetRatecardDiscounts sets the "ratecard_discounts" field. func (bilu *BillingInvoiceLineUpdate) SetRatecardDiscounts(pr *productcatalog.Discounts) *BillingInvoiceLineUpdate { bilu.mutation.SetRatecardDiscounts(pr) return bilu } + // SetNillableRatecardDiscounts sets the "ratecard_discounts" field if the given value is not nil. + func (bilu *BillingInvoiceLineUpdate) SetNillableRatecardDiscounts(pr *productcatalog.Discounts) *BillingInvoiceLineUpdate { + if pr != nil { + bilu.SetRatecardDiscounts(pr) + } + return bilu + } // ClearRatecardDiscounts clears the value of the "ratecard_discounts" field. func (bilu *BillingInvoiceLineUpdate) ClearRatecardDiscounts() *BillingInvoiceLineUpdate { bilu.mutation.ClearRatecardDiscounts() return bilu }
1473-1483: Consider adding SetNillableRatecardDiscounts method for BillingInvoiceLineUpdateOneSimilar to the multi-entity update type, consider adding a
SetNillableRatecardDiscountsmethod to theBillingInvoiceLineUpdateOnetype for consistency with other fields.// SetRatecardDiscounts sets the "ratecard_discounts" field. func (biluo *BillingInvoiceLineUpdateOne) SetRatecardDiscounts(pr *productcatalog.Discounts) *BillingInvoiceLineUpdateOne { biluo.mutation.SetRatecardDiscounts(pr) return biluo } + // SetNillableRatecardDiscounts sets the "ratecard_discounts" field if the given value is not nil. + func (biluo *BillingInvoiceLineUpdateOne) SetNillableRatecardDiscounts(pr *productcatalog.Discounts) *BillingInvoiceLineUpdateOne { + if pr != nil { + biluo.SetRatecardDiscounts(pr) + } + return biluo + } // ClearRatecardDiscounts clears the value of the "ratecard_discounts" field. func (biluo *BillingInvoiceLineUpdateOne) ClearRatecardDiscounts() *BillingInvoiceLineUpdateOne { biluo.mutation.ClearRatecardDiscounts() return biluo }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tools/migrate/migrations/atlas.sumis excluded by!**/*.sum
📒 Files selected for processing (21)
openmeter/billing/adapter/invoicelinemapper.go(1 hunks)openmeter/billing/adapter/invoicelines.go(1 hunks)openmeter/billing/httpdriver/deprecations.go(4 hunks)openmeter/billing/httpdriver/invoiceline.go(8 hunks)openmeter/billing/invoiceline.go(3 hunks)openmeter/ent/db/billinginvoiceline.go(4 hunks)openmeter/ent/db/billinginvoiceline/billinginvoiceline.go(5 hunks)openmeter/ent/db/billinginvoiceline/where.go(1 hunks)openmeter/ent/db/billinginvoiceline_create.go(9 hunks)openmeter/ent/db/billinginvoiceline_update.go(4 hunks)openmeter/ent/db/migrate/schema.go(3 hunks)openmeter/ent/db/mutation.go(10 hunks)openmeter/ent/db/predicate/predicate.go(1 hunks)openmeter/ent/db/runtime.go(1 hunks)openmeter/ent/db/setorclear.go(1 hunks)openmeter/ent/schema/billing.go(1 hunks)openmeter/productcatalog/discount.go(5 hunks)openmeter/productcatalog/http/mapping.go(2 hunks)pkg/models/clonable.go(1 hunks)tools/migrate/migrations/20250404145234_billing-line-ratecard-discounts.down.sql(1 hunks)tools/migrate/migrations/20250404145234_billing-line-ratecard-discounts.up.sql(1 hunks)
🧰 Additional context used
🧬 Code Definitions (9)
openmeter/ent/schema/billing.go (3)
openmeter/productcatalog/discount.go (1)
Discounts(330-330)openmeter/ent/db/billinginvoiceline/billinginvoiceline.go (1)
ValueScanner(241-243)openmeter/ent/schema/productcatalog.go (1)
DiscountsValueScanner(217-217)
openmeter/ent/db/predicate/predicate.go (2)
openmeter/ent/schema/billing.go (5)
BillingInvoiceLine(284-286)BillingInvoiceLine(288-293)BillingInvoiceLine(295-390)BillingInvoiceLine(392-402)BillingInvoiceLine(404-439)openmeter/ent/db/billinginvoiceline.go (2)
BillingInvoiceLine(27-103)BillingInvoiceLine(226-251)
openmeter/billing/httpdriver/deprecations.go (2)
openmeter/productcatalog/discount.go (3)
Discounts(330-330)Discount(53-57)NewDiscountFrom(218-231)openmeter/productcatalog/http/mapping.go (2)
AsPercentageDiscount(665-669)AsDiscounts(624-663)
openmeter/billing/invoiceline.go (4)
api/api.gen.go (3)
TaxConfig(5709-5718)FlatPrice(2724-2730)Price(4874-4876)api/client/go/client.gen.go (2)
TaxConfig(5355-5364)FlatPrice(2468-2474)openmeter/productcatalog/discount.go (1)
Discounts(330-330)openmeter/productcatalog/price.go (3)
NewPriceFrom(338-360)FlatPrice(362-369)Price(80-87)
openmeter/ent/db/billinginvoiceline.go (2)
openmeter/productcatalog/discount.go (1)
Discounts(330-330)openmeter/ent/db/billinginvoiceline/billinginvoiceline.go (2)
FieldRatecardDiscounts(72-72)ValueScanner(241-243)
openmeter/ent/db/setorclear.go (2)
openmeter/ent/db/billinginvoiceline_update.go (2)
BillingInvoiceLineUpdate(29-33)BillingInvoiceLineUpdateOne(1152-1157)openmeter/productcatalog/discount.go (1)
Discounts(330-330)
openmeter/productcatalog/http/mapping.go (1)
openmeter/productcatalog/discount.go (2)
NewDiscountFrom(218-231)PercentageDiscount(239-242)
openmeter/productcatalog/discount.go (3)
pkg/models/clonable.go (1)
Clonable(3-5)api/api.gen.go (2)
Discount(1919-1921)Percentage(4623-4623)pkg/models/percentage.go (1)
Percentage(9-11)
openmeter/ent/db/migrate/schema.go (3)
openmeter/ent/db/billinginvoice/billinginvoice.go (1)
Columns(202-257)openmeter/ent/db/billinginvoiceline/billinginvoiceline.go (1)
Columns(165-198)openmeter/ent/db/billinginvoiceusagebasedlineconfig/billinginvoiceusagebasedlineconfig.go (1)
Columns(33-40)
⏰ Context from checks skipped due to timeout of 90000ms (9)
- GitHub Check: Quickstart
- GitHub Check: E2E
- GitHub Check: CI
- GitHub Check: Developer environment
- GitHub Check: Commit hooks
- GitHub Check: Lint
- GitHub Check: Test
- GitHub Check: Build
- GitHub Check: Analyze (go)
🔇 Additional comments (64)
pkg/models/clonable.go (1)
3-5: Clean, well-designed generic interfaceThe
Clonableinterface is concise and follows good interface design principles with a focused, single responsibility. Using Go generics with theanyconstraint is appropriate for a general cloning interface.tools/migrate/migrations/20250404145234_billing-line-ratecard-discounts.up.sql (1)
1-2: LGTM: Migration correctly adds the ratecard_discounts columnThe migration properly adds a nullable
jsonbcolumn to store discount information, which aligns with the PR objective of persisting rate card discounts.tools/migrate/migrations/20250404145234_billing-line-ratecard-discounts.down.sql (1)
1-2: LGTM: Down migration correctly reverts changesThe down migration properly removes the column added in the up migration, providing a clean rollback path.
openmeter/ent/schema/billing.go (1)
346-354: LGTM: Field definition follows best practicesThe field definition for
ratecard_discountsis well-structured:
- Uses appropriate custom Go type (
&productcatalog.Discounts{})- Configures proper PostgreSQL type (
jsonb)- Implements custom value scanner for JSON serialization/deserialization
- Correctly marked as both optional and nullable
This implementation aligns perfectly with the PR objective to persist rate card discounts.
openmeter/ent/db/predicate/predicate.go (1)
70-79: Well-structured error handling implementation added for BillingInvoiceLine predicatesThe implementation follows the established pattern used for other predicate error handlers in this file, providing a consistent approach for error handling in SQL selectors.
openmeter/billing/adapter/invoicelinemapper.go (1)
160-162: Rate card discounts field added correctlyThe addition of the
RateCardDiscountsfield and the reformatting ofTaxConfigline maintains consistency with the existing code structure. Thelo.FromPtrOrusage correctly handles null values from the database.openmeter/billing/adapter/invoicelines.go (1)
117-119: Rate card discounts persisting logic implemented properlyThe conditional check ensures that rate card discounts are only persisted when they exist, maintaining efficiency. The usage of
lo.ToPtrcorrectly converts the slice to a pointer as expected by the database schema.openmeter/ent/db/billinginvoiceline.go (4)
81-82: Rate card discounts field added to BillingInvoiceLine structThe field is correctly defined as a pointer to
productcatalog.Discountswith appropriate JSON field tag.
240-242: Scan value handler added for rate card discountsThe implementation correctly uses the
ValueScanner.RatecardDiscounts.ScanValue()to scan the database value into the struct field.
425-430: Assign values handler implemented for rate card discountsThe implementation correctly uses the
ValueScanner.RatecardDiscounts.FromValue()to assign database values to the struct field, with proper error handling.
651-655: String representation updated to include rate card discountsThe implementation correctly handles nil check before adding the field to the string representation, maintaining consistency with other fields.
openmeter/ent/db/setorclear.go (1)
1052-1064: Implementation correctly follows the SetOrClear patternThe added methods for
SetOrClearRatecardDiscountsfollow the established pattern in this file, properly handling nil checks and delegating to the appropriate Set/Clear methods. This implementation supports the PR objective of persisting rate card discounts into the database.openmeter/ent/db/billinginvoiceline/where.go (1)
1321-1329: Appropriate implementation of RatecardDiscounts predicates.These new functions correctly implement IsNil and NotNil predicates for the ratecard_discounts field, following the consistent pattern used throughout the file. This enables querying for billing invoice lines based on whether they have discount information or not.
openmeter/billing/httpdriver/invoiceline.go (8)
155-157: LGTM: RateCardDiscounts field added properly.The addition of
RateCardDiscountsfield to theLineBasestruct is properly populated fromrateCardParsed.Discounts. This change supports the PR objective of persisting rate card discounts.
199-201: LGTM: Consistent implementation for usage-based lines.The
RateCardDiscountsfield is consistently implemented in the usage-based line mapping function, maintaining parity with the flat fee implementation.
530-532: LGTM: Properly added to simulation flat fee line.The
RateCardDiscountsfield is correctly added to the simulation flat fee line entity mapping, ensuring consistent behavior between regular and simulation line operations.
579-581: LGTM: Properly added to simulation usage-based line.The
RateCardDiscountsfield is correctly added to the simulation usage-based line entity mapping, maintaining consistency across all line types.
648-649: LGTM: RateCardDiscounts added to flat fee line replace update.The
RateCardDiscountsfield is properly assigned when creating a new line from an invoice line replace update operation for flat fee lines.
691-692: LGTM: RateCardDiscounts added to usage-based line replace update.The
RateCardDiscountsfield is properly assigned when creating a new line from an invoice line replace update operation for usage-based lines.
743-743: LGTM: RateCardDiscounts properly handled in merge operation.The
RateCardDiscountsfield is correctly merged when updating an existing flat fee line, ensuring that discount information is preserved during updates.
787-787: LGTM: RateCardDiscounts properly handled in merge operation for usage-based lines.The
RateCardDiscountsfield is correctly merged when updating an existing usage-based line, ensuring consistent behavior across all line types.openmeter/ent/db/runtime.go (1)
485-487: Looks good - added proper runtime descriptor for RateCardDiscountsThis code correctly sets up the schema descriptor and value scanner for the new
ratecard_discountsfield in thebillinginvoicelinestructure, following the same pattern used throughout the file for other fields.openmeter/productcatalog/http/mapping.go (2)
656-657: Good refactoring of discount creation logic.The code now uses the new
AsPercentageDiscounthelper function instead of directly creating aPercentageDiscountobject. This promotes code reuse and encapsulates the creation logic, making future changes easier to implement.
665-669: Well-structured helper function for discount conversion.The new
AsPercentageDiscountfunction properly encapsulates the creation of aPercentageDiscountobject, following the pattern established in the rest of the codebase. This addition supports the overall goal of persisting rate card discounts.openmeter/billing/invoiceline.go (4)
154-155: Appropriate field naming for discount persistence.The new
RateCardDiscountsfield is correctly named to avoid collision with the existingDiscountsfield, as indicated in the previous review comments. The field properly uses theomitemptyJSON tag to make it optional in serialization.
223-224: Proper cloning of the new RateCardDiscounts field.The updated
Clonemethod correctly creates a deep copy of theRateCardDiscountsfield, ensuring that modifications to the cloned object don't affect the original.
482-489: Good validation for flat fee rate card discounts.The implementation correctly creates a price object from the flat fee properties and validates the discounts against it. This ensures that only compatible discounts can be applied to the flat fee.
495-497: Appropriate validation for usage-based rate card discounts.The implementation properly validates the discounts against the existing price object for usage-based lines. The error handling is consistent with the rest of the codebase.
openmeter/billing/httpdriver/deprecations.go (6)
101-102: Good addition of Discounts field to flatFeeRateCardParsed.The new
Discountsfield is properly added to theflatFeeRateCardParsedstruct, enabling discount information to be carried through the parsing process.
169-175: Well-implemented discount parsing for flat fee rate cards.The implementation correctly handles the optional nature of discounts by checking for nil before processing. It efficiently maps the API discount percentages to domain model discounts using the new
AsPercentageDiscountfunction.
181-182: Properly including discounts in the returned parsed structure.The implementation correctly includes the parsed discounts in the returned
flatFeeRateCardParsedstructure, ensuring that discount information is preserved throughout the process.
256-257: Good addition of Discounts field to usageBasedRateCardParsed.The new
Discountsfield is properly added to theusageBasedRateCardParsedstruct, enabling discount information to be carried through the parsing process consistently with the flat fee implementation.
298-307: Robust error handling for discount parsing in usage-based rate cards.The implementation correctly checks for nil discounts and provides proper error handling when parsing fails. The error message is clear and appropriately wrapped to indicate the source of the failure.
312-313: Properly including discounts in the returned parsed structure.The implementation correctly includes the parsed discounts in the returned
usageBasedRateCardParsedstructure, ensuring consistent handling of discount information across different rate card types.openmeter/ent/db/billinginvoiceline_update.go (4)
355-365: Methods added for rate card discounts management maintain consistency with other fieldsThese new methods enable setting and clearing rate card discounts on billing invoice lines, following the established pattern in the codebase. The implementation is clean and allows for proper persistence of discount information.
818-827: SQL save logic properly handles the new ratecard_discounts fieldThe implementation correctly handles conversion of the discount data structure to a database value and properly updates the SQL specification for both setting and clearing operations.
1473-1483: BillingInvoiceLineUpdateOne methods match the BillingInvoiceLineUpdate patternThe implementation for single entity updates maintains consistency with the multi-entity update methods. Both implementations follow the same pattern, ensuring consistency across the codebase.
1966-1975: SQL save logic for BillingInvoiceLineUpdateOne correctly implements the new fieldThe implementation correctly handles conversion of the discount data for single entity updates, maintaining consistency with the multi-entity update implementation.
openmeter/ent/db/billinginvoiceline/billinginvoiceline.go (5)
11-13: New imports added to support ratecard discounts.The addition of the field package and productcatalog imports are necessary to support the new RatecardDiscounts field being added to the BillingInvoiceLine struct.
71-72: Field constant added for ratecard_discounts.This constant properly follows the naming pattern of other field constants in the file, maintaining consistency in the codebase.
192-192: Column added to the Columns slice.The FieldRatecardDiscounts has been properly added to the Columns slice, which ensures it will be included in database operations.
240-243: New ValueScanner struct with RatecardDiscounts field.The ValueScanner struct is added to handle the scanning of productcatalog.Discounts values from the database. This follows the pattern used for other complex types in the codebase.
399-402: New ordering function for ratecard_discounts field.The ByRatecardDiscounts function enables ordering query results by the ratecard_discounts field, completing the full set of operations needed for this field.
openmeter/productcatalog/discount.go (8)
35-41: Updated discounter interface to include Clonable capability.Adding the Clonable interface requirement ensures that all discount implementations will support cloning, which is essential for persisting and manipulating discount data without unexpected side effects.
167-178: New Clone method for Discount type.The implementation correctly handles different discount types by delegating to their respective Clone methods. The default case provides a sensible fallback for uninitialized discounts.
233-237: Updated interface assertions for PercentageDiscount.The code correctly verifies that PercentageDiscount implements the Clonable interface, maintaining type safety.
266-270: Clone implementation for PercentageDiscount.The implementation creates a new instance with the same percentage value, which is appropriate since models.Percentage is likely immutable.
273-276: Updated interface assertions for UsageDiscount.Similar to PercentageDiscount, the code correctly verifies that UsageDiscount implements the Clonable interface.
319-323: Clone implementation for UsageDiscount.The implementation creates a new instance with the same quantity value, which is appropriate for decimal.Decimal which is likely immutable.
325-328: Updated interface assertions for Discounts.The code correctly verifies that Discounts implements both the Equaler and Clonable interfaces.
332-345: Clone implementation for Discounts slice.The implementation handles the empty case correctly by returning nil, which helps with testing comparisons. It also properly clones each individual discount in the slice, ensuring a deep copy.
openmeter/ent/db/mutation.go (4)
16372-16419: LGTM: Methods for ratecard_discounts field properly implementedThe implementation of the various methods for managing the
ratecard_discountsfield follows the consistent pattern used for other fields in theBillingInvoiceLineMutationstruct. The methods handle setting, retrieving, clearing, and resetting the field appropriately, with proper error handling in theOldRatecardDiscountsmethod.
17083-17083: Field capacity increased to accommodate new fieldThe initial capacity of the fields slice has been increased from its previous value to 32. This is appropriate given the addition of the new field, and it might help prevent future reallocations.
17159-17161: LGTM: Field methods updated for ratecard_discountsAll field-related methods (
Fields,Field,OldField,SetField,ClearedFields,ClearField, andResetField) have been consistently updated to handle the newratecard_discountsfield. The implementation follows the same pattern as other fields, ensuring consistent behavior.Also applies to: 17238-17239, 17311-17312, 17509-17515, 17606-17608, 17659-17661, 17763-17765
15260-15260:Details
✅ Verification successful
Double pointer type used for ratecard_discounts field
The
ratecard_discountsfield uses a double pointer (**productcatalog.Discounts). While this follows the pattern of other fields in this struct that need to be nullable but also store pointer values, confirm this is intentional, as double pointers can be error-prone and less intuitive to work with.
🏁 Script executed:
#!/bin/bash # Find similar field types in the codebase to verify consistency rg -A 1 "\*\*productcatalog\." --type goLength of output: 7053
Double Pointer Usage Confirmed
The investigation confirms that the use of a double pointer for the
ratecard_discountsfield is consistent with similar fields across the codebase (e.g., inopenmeter/ent/db/setorclear.go). This suggests that its implementation is intentional and in line with the project's established coding patterns.openmeter/ent/db/billinginvoiceline_create.go (6)
243-247: Good implementation of SetRatecardDiscounts method.The method correctly follows the established pattern for setting fields in this codebase, with proper method chaining.
594-597: Proper error handling added to sqlSave.Good enhancement to capture and return errors from createSpec. This ensures errors during ratecard_discounts field processing are properly propagated.
718-725: Well-implemented ratecard_discounts field handling.The implementation correctly:
- Uses the ValueScanner to convert the field value
- Sets the field in both the specification and node object
- Handles potential errors during value scanning
This is consistent with how other fields are handled in this function.
1229-1245: Complete set of methods added for BillingInvoiceLineUpsert.The implementation includes all necessary methods for field management (Set, Update, Clear) following the existing pattern in the codebase.
1751-1770: Good implementation of methods for BillingInvoiceLineUpsertOne.The methods correctly delegate to the corresponding BillingInvoiceLineUpsert methods while maintaining the proper return types for method chaining.
2464-2483: Complete implementation of methods for BillingInvoiceLineUpsertBulk.The implementation follows the established pattern for bulk operations, ensuring consistency across the codebase.
openmeter/ent/db/migrate/schema.go (3)
708-708: New column for persisting rate card discountsThe change adds a
ratecard_discountscolumn to theBillingInvoiceLinesColumnsarray, enabling persistence of rate card discounts in the database. This aligns with the PR objective to persist therateCard.discountsobject.
727-764: Foreign key indices appropriately updatedThe indices in foreign key references have been correctly incremented to account for the new column position. This is a necessary adjustment to maintain the correct references to other tables.
788-806: Index column references properly adjustedAll index column references have been correctly updated to account for the new column position, ensuring database referential integrity is maintained.
Overview
This patch ensures that we are persisting the line's
rateCard.discountsobject into the database.Summary by CodeRabbit