Skip to content

feat: robust Transaction model — five polymorphic roles, full monetary breakdown, lifecycle timestamps#197

Open
roncodes wants to merge 2 commits intomainfrom
feat/robust-transaction-model
Open

feat: robust Transaction model — five polymorphic roles, full monetary breakdown, lifecycle timestamps#197
roncodes wants to merge 2 commits intomainfrom
feat/robust-transaction-model

Conversation

@roncodes
Copy link
Member

@roncodes roncodes commented Mar 2, 2026

Overview

Upgrades the transactions table and Transaction model to serve as the platform-wide financial transaction primitive.

Key Changes

Five agnostic polymorphic roles

  • subject — primary owner of the transaction record
  • payer — funds flow FROM
  • payee — funds flow TO
  • initiator — what triggered or authorised the transaction
  • context — related business object (Order, Invoice, etc.)

owner_uuid/owner_type and customer_uuid/customer_type are kept as deprecated nullable aliases, backfilled from the new columns.

Monetary breakdown (all integers in cents)

fee_amount, tax_amount, net_amount, exchange_rate, settled_currency, settled_amount, balance_after

Idempotency and linkage

reference (unique idempotency key), parent_transaction_uuid (self-referential FK for refunds/reversals/splits)

Gateway enrichment

gateway_response JSON, payment_method, payment_method_last4, payment_method_brand

Traceability

ip_address, notes, failure_reason, failure_code

Reporting

period (YYYY-MM, denormalised), tags JSON

Lifecycle timestamps

settled_at, voided_at, reversed_at, expires_at

Model additions

  • SoftDeletes trait (was missing)
  • DIRECTION_*, STATUS_*, TYPE_* constants
  • Five polymorphic relationships + parentTransaction + childTransactions
  • Scopes: credits, debits, successful, pending, failed, ofType, forPeriod, forSubject, forPayer, forPayee, forContext, refunds
  • Helpers: isCredit, isDebit, isSuccessful, isPending, isFailed, isRefund, isVoided, isReversed, isSettled, isExpired

TransactionItem improvements

  • Add HasPublicId, SoftDeletes
  • Fix amount type: string → integer (cents)
  • Add quantity, unit_price, tax_rate, tax_amount, description, sort_order
  • Add transaction() BelongsTo, getLineTotal(), calculateTax()

Breaking Changes

None — all changes are additive. Deprecated columns remain in place.

Fleetbase Dev added 2 commits March 1, 2026 20:05
…y breakdown, lifecycle timestamps

- Add five agnostic polymorphic roles: subject, payer, payee, initiator, context
  (replaces owner_uuid/owner_type and customer_uuid/customer_type)
- Add direction (credit|debit), balance_after (wallet running balance snapshot)
- Add monetary breakdown: fee_amount, tax_amount, net_amount (all in cents)
- Add multi-currency settlement: exchange_rate, settled_currency, settled_amount
- Add idempotency: reference (unique), parent_transaction_uuid (refund/reversal linkage)
- Add gateway enrichment: gateway_response JSON, payment_method, last4, brand
- Add traceability: ip_address, notes, failure_reason, failure_code
- Add reporting: period (YYYY-MM), tags JSON
- Add lifecycle timestamps: settled_at, voided_at, reversed_at, expires_at
- Add SoftDeletes trait (was missing from model despite column existing in migration)
- Add STATUS_*, DIRECTION_*, TYPE_* constants covering platform-wide taxonomy
- Add scopeCredits, scopeDebits, scopeSuccessful, scopePending, scopeFailed,
  scopeOfType, scopeForPeriod, scopeForSubject, scopeForPayer, scopeForPayee,
  scopeForContext, scopeRefunds
- Add isCredit, isDebit, isSuccessful, isPending, isFailed, isRefund, isVoided,
  isReversed, isSettled, isExpired helpers
- Add formatted_amount accessor
- Add parentTransaction BelongsTo and childTransactions HasMany relationships
- Backfill subject_* from owner_*, payer_* from customer_*, period from created_at
- Deprecate owner() and customer() relationships (kept for backward compat)
- Improve TransactionItem: add HasPublicId, SoftDeletes, quantity, unit_price,
  tax_rate, tax_amount, description, sort_order; fix amount type string -> integer;
  add transaction() BelongsTo, getLineTotal(), calculateTax() helpers
…ed_amount getters

- Replace 'integer' cast with Fleetbase\Casts\Money on all monetary columns
  (amount, fee_amount, tax_amount, net_amount, balance_after, settled_amount
  on Transaction; amount, unit_price, tax_amount on TransactionItem)
- Remove getFormattedAmountAttribute() from both models
- Remove 'formatted_amount' from $appends on both models
- Money cast handles all currency symbol stripping and integer normalisation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant