PSA/docs/billing/credits_and_reconciliation.md
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

14 KiB

Credits and Credit Reconciliation System

Table of Contents

  1. Introduction
  2. Credit System Architecture
  3. Credit Reconciliation System
  4. Reconciliation Resolution Workflow
  5. User Interface Components
  6. Technical Implementation

Introduction

The credit system allows companies to maintain prepaid balances that can be applied to invoices. The credit reconciliation system ensures the integrity of these balances by detecting and reporting discrepancies between the expected and actual credit balances, as well as issues with credit tracking entries.

This document provides a comprehensive overview of how credits and credit reconciliation work in the system, including the underlying architecture, reconciliation process, and resolution workflow.

Credit System Architecture

Data Model

The credit system is built around several key data structures:

  1. Company Credit Balance: Each company has a credit_balance field that stores the total available credit.

  2. Credit Tracking Entries: The credit_tracking table maintains detailed records of all credits, including:

    • Original amount
    • Remaining amount
    • Creation date
    • Expiration date
    • Link to the originating transaction
  3. Transactions: The transactions table records all credit-related activities with types:

    • credit_issuance: Initial credit creation
    • credit_issuance_from_negative_invoice: Credits created from negative invoices
    • credit_application: Credits applied to invoices
    • credit_adjustment: Adjustments to credit balances
    • credit_expiration: Credits that have expired
    • credit_transfer: Credits transferred between companies
  4. Credit Allocations: The credit_allocations table links credit applications to specific invoices.

  5. Credit Reconciliation Reports: The credit_reconciliation_reports table stores detected discrepancies.

Credit Creation

Credits can be created through several mechanisms:

  1. Prepayment Invoices: The primary method for creating credits is through prepayment invoices. These are special invoices with no billing cycle that represent funds added to a company's account.

    // Creating a prepayment invoice
    const prepaymentInvoice = await createPrepaymentInvoice(
      companyId,
      amount,
      expirationDate // Optional
    );
    
    // Finalizing the invoice to create the credit
    await finalizeInvoice(prepaymentInvoice.invoice_id);
    
  2. Negative Invoices: When an invoice has a negative balance (e.g., due to refunds or adjustments), it can generate credits.

  3. Manual Adjustments: Administrators can manually add credits through credit adjustment transactions.

When credits are created:

  • A credit_issuance transaction is recorded
  • A credit tracking entry is created with the full amount as the remaining amount
  • The company's credit balance is increased

Credit Application

Credits are applied to invoices during the finalization process:

  1. Automatic Application: When an invoice is finalized, available credits are automatically applied up to the invoice total.

  2. Manual Application: Credits can also be manually applied to specific invoices.

    // Applying credit to an invoice
    await applyCreditToInvoice(companyId, invoiceId, amount);
    

The credit application process:

  1. Retrieves available (non-expired) credit tracking entries
  2. Prioritizes credits by expiration date (oldest first)
  3. Creates credit_application and credit_adjustment transactions
  4. Updates the remaining amount in credit tracking entries
  5. Updates the company's credit balance
  6. Creates credit allocation records linking transactions to invoices

Credit Expiration

Credits can have expiration dates, after which they are no longer available for use:

  1. Expiration Configuration: Companies can configure:

    • Whether credits expire (enable_credit_expiration)
    • How many days until expiration (credit_expiration_days)
    • When to send notifications before expiration (credit_expiration_notification_days)
  2. Expiration Process:

    • Expired credits have their remaining amount set to zero
    • A credit_expiration transaction is created
    • The company's credit balance is reduced by the expired amount
  3. Scheduled Job: A daily job runs to process expired credits automatically.

Credit Transfers

Credits can be transferred between companies:

  1. The source company's credit tracking entry is updated to reduce the remaining amount
  2. A credit_transfer transaction is created for the source company (negative amount)
  3. The source company's credit balance is reduced
  4. A new credit_transfer transaction is created for the target company (positive amount)
  5. The target company's credit balance is increased
  6. A new credit tracking entry is created for the target company

Credit Reconciliation System

Reconciliation Philosophy

The credit reconciliation system is designed around these key principles:

  1. Separation of Detection and Correction: The system detects discrepancies without automatically correcting them, ensuring all financial corrections are explicitly reviewed and approved.

  2. Transparency: All discrepancies are reported with detailed information about the expected and actual values.

  3. Manual Resolution: Authorized users must manually review and resolve discrepancies, maintaining financial integrity.

  4. Comprehensive Audit Trail: All detections and resolutions are logged for accountability.

Types of Discrepancies

The system detects three main types of discrepancies:

  1. Credit Balance Discrepancies: Differences between the expected credit balance (calculated from transactions) and the actual credit balance stored in the company record.

  2. Missing Credit Tracking Entries: Transactions that should have corresponding credit tracking entries but don't.

  3. Inconsistent Remaining Amounts: Credit tracking entries where the remaining amount doesn't match the expected value based on transaction history.

Reconciliation Process

The credit reconciliation process involves these steps:

  1. Balance Validation:

    • Calculate the expected credit balance by summing all credit-related transactions
    • Compare with the actual credit balance in the company record
    • Create a reconciliation report if there's a discrepancy
  2. Credit Tracking Validation:

    • Identify transactions that should have credit tracking entries but don't
    • Calculate the expected remaining amount for each credit tracking entry
    • Compare with the actual remaining amount
    • Create reconciliation reports for any discrepancies
  3. Report Creation:

    • Store detailed information about each discrepancy
    • Include metadata specific to the discrepancy type
    • Set the status to 'open'

Scheduled Validation

Credit reconciliation runs automatically through scheduled jobs:

  1. Daily Validation: A scheduled job runs daily at 2:00 AM to validate all companies.

  2. Company-Specific Validation: Administrators can also trigger validation for specific companies through the UI.

  3. Tenant-Aware: The validation process respects tenant boundaries, ensuring data isolation.

Reconciliation Resolution Workflow

Resolution Options

Discrepancies can be resolved through several methods, depending on the type:

  1. For Credit Balance Discrepancies:

    • Apply the recommended adjustment to match the expected balance
    • Apply a custom adjustment amount
    • Mark as resolved without action (if determined to be a false positive)
  2. For Missing Credit Tracking Entries:

    • Create the missing credit tracking entry
    • Apply a custom credit adjustment
    • Mark as resolved without action
  3. For Inconsistent Remaining Amounts:

    • Update the remaining amount to match the expected value
    • Apply a custom credit adjustment
    • Mark as resolved without action

Audit Trail

All reconciliation activities are logged for accountability:

  1. Detection Logging: When discrepancies are detected, detailed information is logged.

  2. Resolution Logging: When discrepancies are resolved, the resolution method, user, and notes are logged.

  3. Transaction Records: All corrections create transaction records for financial traceability.

User Interface Components

Reconciliation Dashboard

The reconciliation dashboard provides an overview of all credit discrepancies:

  1. Summary Statistics:

    • Total discrepancies
    • Total discrepancy amount
    • Open issues count
  2. Filtering Options:

    • By company
    • By status (open, in review, resolved)
    • By date range
  3. Tabular View:

    • Company name
    • Discrepancy amount
    • Detection date
    • Status
    • Expected and actual balances
    • Action buttons
  4. Company-Specific Reconciliation:

    • Dropdown to select a company
    • Button to run reconciliation for the selected company

Discrepancy Detail View

The discrepancy detail view provides comprehensive information about a specific discrepancy:

  1. Basic Information:

    • Company details
    • Discrepancy amount
    • Detection date
    • Status
  2. Balance Comparison:

    • Expected balance
    • Actual balance
    • Difference
  3. Related Data:

    • Transaction history
    • Credit tracking entries
    • Issue-specific details
  4. Recommended Fix Panel:

    • Suggested resolution options
    • Impact summary
    • Resolution form

Resolution Workflow

The resolution workflow guides users through the process of resolving discrepancies:

  1. Fix Selection:

    • Recommended fix based on discrepancy type
    • Alternative fix options
    • Option to mark as resolved without action
  2. Resolution Form:

    • Notes field for explaining the resolution
    • Custom amount field for custom adjustments
    • Impact summary showing the effect of the resolution
  3. Confirmation:

    • Review of the resolution details
    • Final confirmation before applying the fix

Technical Implementation

Server Actions

The credit reconciliation system is implemented through several server actions:

  1. Validation Actions:

    • validateCreditBalanceWithoutCorrection(): Validates credit balance without making corrections
    • validateCreditTrackingEntries(): Validates credit tracking entries
    • validateCreditTrackingRemainingAmounts(): Validates remaining amounts
    • validateAllCreditTracking(): Runs both tracking validations
    • runScheduledCreditBalanceValidation(): Runs validation for all companies or a specific company
  2. Resolution Actions:

    • resolveReconciliationReport(): Resolves a reconciliation report
    • createMissingCreditTrackingEntry(): Creates a missing credit tracking entry
    • updateCreditTrackingRemainingAmount(): Updates a credit tracking entry's remaining amount
    • applyCustomCreditAdjustment(): Applies a custom credit adjustment
    • markReportAsResolvedNoAction(): Marks a report as resolved without action
  3. Reporting Actions:

    • fetchReconciliationReports(): Retrieves reconciliation reports with filtering
    • fetchReconciliationStats(): Retrieves summary statistics

Scheduled Jobs

The credit reconciliation system uses scheduled jobs for automation:

  1. Credit Reconciliation Job:

    • Runs daily at 2:00 AM
    • Validates all companies in a tenant
    • Creates reconciliation reports for any discrepancies
  2. Expired Credits Job:

    • Runs daily at 1:00 AM
    • Processes expired credits
    • Updates credit tracking entries and company balances
  3. Expiring Credits Notification Job:

    • Runs daily at 9:00 AM
    • Sends notifications about credits that will expire soon

Database Schema

The credit reconciliation system uses these key database tables:

  1. credit_reconciliation_reports:

    • report_id: Unique identifier
    • company_id: The company with the discrepancy
    • expected_balance: The calculated correct balance
    • actual_balance: The stored balance
    • difference: The discrepancy amount
    • detection_date: When the discrepancy was detected
    • status: open, in_review, or resolved
    • resolution_date: When the discrepancy was resolved
    • resolution_user: Who resolved the discrepancy
    • resolution_notes: Notes explaining the resolution
    • resolution_transaction_id: The transaction that resolved the discrepancy
    • metadata: Additional information specific to the discrepancy type
  2. transactions:

    • Records all credit-related activities
    • Includes credit adjustments from reconciliation resolutions
  3. credit_tracking:

    • Stores detailed information about each credit
    • Updated during reconciliation resolution