PHPackages                             azaharizaman/nexus-account-variance-analysis - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. azaharizaman/nexus-account-variance-analysis

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

azaharizaman/nexus-account-variance-analysis
============================================

Variance analysis, trend analysis, and significance evaluation for financial accounts

v0.1.0-alpha1(2mo ago)00MITPHPPHP ^8.3

Since May 5Pushed 2mo agoCompare

[ Source](https://github.com/azaharizaman/nexus-account-variance-analysis)[ Packagist](https://packagist.org/packages/azaharizaman/nexus-account-variance-analysis)[ RSS](/packages/azaharizaman-nexus-account-variance-analysis/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (2)Versions (2)Used By (0)

Nexus\\AccountVarianceAnalysis
==============================

[](#nexusaccountvarianceanalysis)

**Framework-Agnostic Financial Variance Analysis Engine**

[![PHP Version](https://camo.githubusercontent.com/ef0054230522e542bc1f908ac005c6c75888dea255bac910f9015e12095e31d7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e332d626c7565)](https://www.php.net/)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](LICENSE)

Overview
--------

[](#overview)

`Nexus\AccountVarianceAnalysis` is a pure PHP package that provides the core engine for analyzing financial variances between actual results and budgets, forecasts, or prior periods. It calculates variances, identifies significant deviations, performs trend analysis, and provides attribution analysis to explain the drivers of variances.

This package is **framework-agnostic** and contains no database access, no HTTP controllers, and no framework-specific code. Consuming applications provide comparative data through injected interfaces.

Installation
------------

[](#installation)

```
composer require azaharizaman/nexus-account-variance-analysis
```

Package Responsibilities
------------------------

[](#package-responsibilities)

ResponsibilityDescription**Variance Calculation**Calculate differences between actual and budget/forecast**Significance Evaluation**Determine if variances exceed materiality thresholds**Trend Analysis**Identify patterns and trends over multiple periods**Attribution Analysis**Break down variances into contributing factors**Statistical Analysis**Provide statistical measures (std dev, moving averages)**Rolling Forecasts**Update forecasts based on actual resultsKey Concepts
------------

[](#key-concepts)

### Variance Types

[](#variance-types)

TypeComparisonUse Case**Budget Variance**Actual vs BudgetAnnual/quarterly budget comparison**Forecast Variance**Actual vs ForecastRolling forecast accuracy**Prior Period**Current vs PriorPeriod-over-period analysis**Year-over-Year**Current YTD vs Prior YTDAnnual trend analysis**Plan Variance**Actual vs Strategic PlanLong-term goal tracking### Significance Levels

[](#significance-levels)

- **Critical** - Variance exceeds 3x threshold
- **High** - Variance exceeds 2x threshold
- **Medium** - Variance exceeds 1.5x threshold
- **Low** - Variance exceeds threshold
- **Insignificant** - Within acceptable range

---

Architecture
------------

[](#architecture)

```
src/
├── Contracts/           # Interfaces defining the public API
├── ValueObjects/        # Immutable variance data structures
├── Enums/               # Variance types, statuses, directions
├── Services/            # Core variance calculation logic
└── Exceptions/          # Domain-specific errors

```

---

Contracts (Interfaces)
----------------------

[](#contracts-interfaces)

### Core Interfaces

[](#core-interfaces)

#### `VarianceCalculatorInterface`

[](#variancecalculatorinterface)

The main entry point for variance calculations.

```
interface VarianceCalculatorInterface
{
    /**
     * Calculate variance between actual and comparison values
     *
     * @param Money $actual The actual amount
     * @param Money $comparison The budget/forecast/prior amount
     * @param VarianceType $type The type of variance calculation
     * @return VarianceResult
     */
    public function calculate(
        Money $actual,
        Money $comparison,
        VarianceType $type = VarianceType::BUDGET
    ): VarianceResult;

    /**
     * Calculate variances for multiple accounts
     *
     * @param array $accounts
     * @return array
     */
    public function calculateBatch(array $accounts): array;

    /**
     * Calculate favorable/unfavorable direction
     * (Revenue: over = favorable; Expense: under = favorable)
     */
    public function determineDirection(
        VarianceResult $variance,
        AccountCategory $category
    ): VarianceDirection;
}
```

#### `TrendAnalyzerInterface`

[](#trendanalyzerinterface)

Analyzes trends across multiple periods.

```
interface TrendAnalyzerInterface
{
    /**
     * Analyze trend for an account over multiple periods
     *
     * @param array $periodValues Historical values by period
     * @param int $periodsForward Periods to project forward
     * @return TrendData
     */
    public function analyze(array $periodValues, int $periodsForward = 3): TrendData;

    /**
     * Detect trend direction (up, down, stable)
     */
    public function detectTrendDirection(array $periodValues): TrendDirection;

    /**
     * Calculate moving average
     */
    public function calculateMovingAverage(
        array $periodValues,
        int $periods = 3
    ): array;

    /**
     * Identify seasonality patterns
     */
    public function detectSeasonality(
        array $monthlyValues,
        int $yearsOfData = 2
    ): SeasonalityPattern;
}
```

#### `SignificanceEvaluatorInterface`

[](#significanceevaluatorinterface)

Evaluates whether variances are significant.

```
interface SignificanceEvaluatorInterface
{
    /**
     * Evaluate significance of a variance
     *
     * @param VarianceResult $variance The calculated variance
     * @param SignificanceThreshold $threshold Threshold configuration
     * @return SignificanceLevel
     */
    public function evaluate(
        VarianceResult $variance,
        SignificanceThreshold $threshold
    ): SignificanceLevel;

    /**
     * Check if variance exceeds any threshold
     */
    public function isSignificant(
        VarianceResult $variance,
        SignificanceThreshold $threshold
    ): bool;

    /**
     * Get all variances exceeding threshold
     *
     * @param array $variances
     * @return array
     */
    public function filterSignificant(
        array $variances,
        SignificanceThreshold $threshold
    ): array;
}
```

#### `AttributionAnalyzerInterface`

[](#attributionanalyzerinterface)

Breaks down variances into contributing factors.

```
interface AttributionAnalyzerInterface
{
    /**
     * Attribute variance to contributing factors
     *
     * @param VarianceResult $variance The total variance
     * @param array $factors Factor data for attribution
     * @return VarianceAttribution
     */
    public function attribute(
        VarianceResult $variance,
        array $factors
    ): VarianceAttribution;

    /**
     * Perform price/volume variance analysis
     * (Common for revenue and cost analysis)
     */
    public function priceVolumeAnalysis(
        float $actualPrice,
        float $budgetPrice,
        float $actualVolume,
        float $budgetVolume
    ): PriceVolumeBreakdown;

    /**
     * Attribute to organizational units
     */
    public function attributeByDimension(
        VarianceResult $variance,
        array $dimensionData,
        string $dimensionName
    ): array;
}
```

#### `VarianceDataProviderInterface`

[](#variancedataproviderinterface)

Contract for consuming applications to provide data.

```
interface VarianceDataProviderInterface
{
    /**
     * Get actual account balances for a period
     */
    public function getActualBalances(
        string $tenantId,
        string $periodId
    ): array;

    /**
     * Get budget amounts for a period
     */
    public function getBudgetAmounts(
        string $tenantId,
        string $periodId
    ): array;

    /**
     * Get forecast amounts for a period
     */
    public function getForecastAmounts(
        string $tenantId,
        string $periodId
    ): array;

    /**
     * Get prior period balances
     */
    public function getPriorPeriodBalances(
        string $tenantId,
        string $periodId,
        int $periodsBack = 1
    ): array;

    /**
     * Get historical values for trend analysis
     */
    public function getHistoricalValues(
        string $tenantId,
        string $accountId,
        int $periods = 12
    ): array;
}
```

---

Value Objects
-------------

[](#value-objects)

### `VarianceResult`

[](#varianceresult)

```
final readonly class VarianceResult
{
    public function __construct(
        public string $accountId,
        public string $accountName,
        public Money $actualAmount,
        public Money $comparisonAmount,
        public Money $varianceAmount,
        public float $variancePercentage,
        public VarianceType $type,
        public VarianceStatus $status,
        public bool $isFavorable
    ) {}

    public function isOverBudget(): bool
    {
        return $this->varianceAmount->isPositive();
    }

    public function isUnderBudget(): bool
    {
        return $this->varianceAmount->isNegative();
    }
}
```

### `TrendData`

[](#trenddata)

```
final readonly class TrendData
{
    public function __construct(
        public string $accountId,
        public TrendDirection $direction,
        public float $averageGrowthRate,
        public float $standardDeviation,
        public array $movingAverages,
        public array $projectedValues,
        public float $rSquared,
        public float $trendSlope
    ) {}

    public function isVolatile(float $threshold = 0.15): bool
    {
        return $this->standardDeviation > $threshold;
    }
}
```

### `SignificanceThreshold`

[](#significancethreshold)

```
final readonly class SignificanceThreshold
{
    public function __construct(
        public float $percentageThreshold = 10.0,
        public Money $absoluteThreshold = null,
        public bool $usePercentage = true,
        public bool $useAbsolute = false,
        public bool $requireBoth = false
    ) {}

    public static function percentage(float $percent): self
    {
        return new self(percentageThreshold: $percent, usePercentage: true);
    }

    public static function absolute(Money $amount): self
    {
        return new self(absoluteThreshold: $amount, usePercentage: false, useAbsolute: true);
    }
}
```

### `VarianceAttribution`

[](#varianceattribution)

```
final readonly class VarianceAttribution
{
    public function __construct(
        public VarianceResult $totalVariance,
        public array $attributions,
        public float $explainedPercentage,
        public Money $unexplainedAmount
    ) {}

    /**
     * @return array
     */
    public function getTopContributors(int $count = 5): array
    {
        // Return top N contributing factors
    }
}
```

### `AccountVariance`

[](#accountvariance)

```
final readonly class AccountVariance
{
    public function __construct(
        public string $accountId,
        public string $accountCode,
        public string $accountName,
        public AccountCategory $category,
        public Money $actualAmount,
        public Money $budgetAmount,
        public ?Money $priorPeriodAmount = null,
        public ?Money $forecastAmount = null
    ) {}
}
```

### `ForecastVariance`

[](#forecastvariance)

```
final readonly class ForecastVariance
{
    public function __construct(
        public string $accountId,
        public Money $originalForecast,
        public Money $revisedForecast,
        public Money $actualToDate,
        public float $forecastAccuracy,
        public string $revisionReason
    ) {}
}
```

---

Enums
-----

[](#enums)

### `VarianceType`

[](#variancetype)

```
enum VarianceType: string
{
    case BUDGET = 'budget';
    case FORECAST = 'forecast';
    case PRIOR_PERIOD = 'prior_period';
    case YEAR_OVER_YEAR = 'year_over_year';
    case PLAN = 'plan';
}
```

### `VarianceStatus`

[](#variancestatus)

```
enum VarianceStatus: string
{
    case FAVORABLE = 'favorable';
    case UNFAVORABLE = 'unfavorable';
    case ON_TARGET = 'on_target';
    case NOT_CALCULATED = 'not_calculated';
}
```

### `TrendDirection`

[](#trenddirection)

```
enum TrendDirection: string
{
    case INCREASING = 'increasing';
    case DECREASING = 'decreasing';
    case STABLE = 'stable';
    case VOLATILE = 'volatile';
}
```

### `SignificanceLevel`

[](#significancelevel)

```
enum SignificanceLevel: string
{
    case CRITICAL = 'critical';      // > 3x threshold
    case HIGH = 'high';              // > 2x threshold
    case MEDIUM = 'medium';          // > 1.5x threshold
    case LOW = 'low';                // > 1x threshold
    case INSIGNIFICANT = 'insignificant';
}
```

---

Services
--------

[](#services)

### `VarianceCalculator`

[](#variancecalculator)

Core variance calculation logic:

- Amount variance (Actual - Budget)
- Percentage variance ((Actual - Budget) / Budget × 100)
- Favorable/unfavorable determination by account type
- Batch calculations for efficiency

### `TrendAnalyzer`

[](#trendanalyzer)

Trend analysis capabilities:

- Linear regression for trend line
- Moving average calculations (3, 6, 12 period)
- Growth rate calculations
- Seasonality detection
- Future value projections

### `SignificanceEvaluator`

[](#significanceevaluator)

Threshold evaluation:

- Percentage-based thresholds
- Absolute amount thresholds
- Combined threshold logic
- Significance level assignment

### `AttributionAnalyzer`

[](#attributionanalyzer)

Variance attribution:

- Price/Volume analysis
- Mix variance
- Rate/Efficiency analysis
- Multi-dimensional attribution

### `StatisticalCalculator`

[](#statisticalcalculator)

Statistical functions:

- Standard deviation
- Coefficient of variation
- Correlation analysis
- R-squared calculation

### `RollingForecastCalculator`

[](#rollingforecastcalculator)

Forecast updates:

- Reforecast based on actuals
- Remaining period projections
- Accuracy tracking

---

Exceptions
----------

[](#exceptions)

ExceptionWhen Thrown`VarianceCalculationException`Variance calculation fails (division by zero, etc.)`InsufficientDataException`Not enough data points for trend analysis`InvalidThresholdException`Threshold configuration is invalid---

Usage Example
-------------

[](#usage-example)

```
use Nexus\AccountVarianceAnalysis\Contracts\VarianceCalculatorInterface;
use Nexus\AccountVarianceAnalysis\Contracts\SignificanceEvaluatorInterface;
use Nexus\AccountVarianceAnalysis\ValueObjects\SignificanceThreshold;
use Nexus\AccountVarianceAnalysis\Enums\VarianceType;

final readonly class BudgetVarianceReportService
{
    public function __construct(
        private VarianceCalculatorInterface $calculator,
        private SignificanceEvaluatorInterface $evaluator,
        private VarianceDataProviderInterface $dataProvider
    ) {}

    public function generateReport(string $tenantId, string $periodId): array
    {
        // Get actual and budget data
        $actuals = $this->dataProvider->getActualBalances($tenantId, $periodId);
        $budgets = $this->dataProvider->getBudgetAmounts($tenantId, $periodId);

        // Define significance threshold
        $threshold = SignificanceThreshold::percentage(10.0);

        $variances = [];
        $significantVariances = [];

        foreach ($actuals as $accountId => $actual) {
            $budget = $budgets[$accountId] ?? null;
            if ($budget === null) continue;

            // Calculate variance
            $variance = $this->calculator->calculate(
                actual: $actual,
                comparison: $budget,
                type: VarianceType::BUDGET
            );

            $variances[] = $variance;

            // Check significance
            if ($this->evaluator->isSignificant($variance, $threshold)) {
                $significantVariances[] = $variance;
            }
        }

        return [
            'all_variances' => $variances,
            'significant_variances' => $significantVariances,
            'total_favorable' => $this->sumFavorable($variances),
            'total_unfavorable' => $this->sumUnfavorable($variances),
        ];
    }
}
```

---

Variance Analysis Formulas
--------------------------

[](#variance-analysis-formulas)

### Basic Variance

[](#basic-variance)

```
Variance Amount = Actual - Budget
Variance % = ((Actual - Budget) / Budget) × 100

```

### Favorable/Unfavorable Logic

[](#favorableunfavorable-logic)

Account TypeOver BudgetUnder BudgetRevenueFavorable ✅Unfavorable ❌ExpenseUnfavorable ❌Favorable ✅AssetContextualContextualLiabilityContextualContextual### Price/Volume Analysis

[](#pricevolume-analysis)

```
Total Variance = (Actual Price × Actual Volume) - (Budget Price × Budget Volume)

Price Variance = (Actual Price - Budget Price) × Actual Volume
Volume Variance = (Actual Volume - Budget Volume) × Budget Price
Mix Variance = Difference (if present)

```

---

Integration with Other Packages
-------------------------------

[](#integration-with-other-packages)

PackageIntegration`Nexus\Finance`Provides actual GL balances`Nexus\Budget`Provides budget amounts`Nexus\FinancialStatements`Variance data in statement notes`Nexus\Notifier`Alert on significant variances`Nexus\AuditLogger`Log variance analysis events---

Related Documentation
---------------------

[](#related-documentation)

- [ARCHITECTURE.md](../../ARCHITECTURE.md) - Overall system architecture
- [CODING\_GUIDELINES.md](../../CODING_GUIDELINES.md) - Coding standards
- [Nexus Packages Reference](../../docs/NEXUS_PACKAGES_REFERENCE.md) - All available packages

---

License
-------

[](#license)

MIT License - See [LICENSE](LICENSE) for details.

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance84

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

81d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/117408?v=4)[Azahari Zaman](/maintainers/azaharizaman)[@azaharizaman](https://github.com/azaharizaman)

---

Top Contributors

[![azaharizaman](https://avatars.githubusercontent.com/u/117408?v=4)](https://github.com/azaharizaman "azaharizaman (5 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/azaharizaman-nexus-account-variance-analysis/health.svg)

```
[![Health](https://phpackages.com/badges/azaharizaman-nexus-account-variance-analysis/health.svg)](https://phpackages.com/packages/azaharizaman-nexus-account-variance-analysis)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
