$ok ? $r['cashback']['gross'] : null, 'cashbackNet' => $ok ? $r['cashback']['net'] : null, 'giroNet' => $pr['giro']['bungaNet'], 'simanjaNet' => $pr['simanja']['bungaNet'], 'simpedaNet' => $pr['simpeda']['bungaNet'], 'depositoNet' => $r['deposito']['net'], 'depositoGross' => $r['deposito']['gross'], 'rateDeposito' => $r['deposito']['rate'], 'totalGiro' => $ok ? $by['giro']['total'] : null, 'totalSimanja' => $ok ? $by['simanja']['total'] : null, 'totalSimpeda' => $ok ? $by['simpeda']['total'] : null, 'totalDeposito' => $r['deposito']['net'], 'rateGiro' => $pr['giro']['rate'], 'rateSimanja' => $pr['simanja']['rate'], 'rateSimpeda' => $pr['simpeda']['rate'], 'equiv' => $ok ? $r['cashback']['equiv'] : null, 'totalRateGiro' => $ok ? $by['giro']['totalRate'] : null, 'totalRateSimanja' => $ok ? $by['simanja']['totalRate'] : null, 'totalRateSimpeda' => $ok ? $by['simpeda']['totalRate'] : null, 'penaltyRefund' => $ok ? $r['penalty']['refund'] : null, 'penaltyTax' => $ok ? $r['penalty']['tax'] : null, 'penaltyFee' => $ok ? $r['penalty']['fee'] : null, 'penaltyTotal' => $ok ? $r['penalty']['total'] : null, 'shareNasabah' => $ok ? $r['share'] : null, 'shareBank' => $ok ? $r['shareBank'] : null, 'income' => $r['fund']['income'], 'puabIncome' => $r['fund']['puabIncome'], 'creditIncome' => $r['fund']['creditIncome'], 'spreadSimanja' => $pr['simanja']['spread'], 'spreadSimpeda' => $pr['simpeda']['spread'], 'spreadGiro' => $pr['giro']['spread'], ]; } $checks = 0; $failures = []; foreach ($fixtures['cases'] as $c) { $got = engine_view(engine_calculate($params, (float)$c['nominal'], (int)$c['tenor'], 'perorangan')); foreach ($c as $field => $expected) { if ($field === 'nominal' || $field === 'tenor' || !array_key_exists($field, $got)) { continue; } $checks++; $actual = $got[$field]; if ($expected === null) { $pass = $actual === null; } elseif ($actual === null) { $pass = false; } elseif (in_array($field, $rateFields, true)) { $pass = abs($actual - $expected) < 1e-9; } else { $pass = round($actual) == round($expected) && abs($actual - $expected) < 0.01; } if (!$pass) { $failures[] = sprintf('%s / %d bln / %s: excel=%s app=%s', $c['nominal'], $c['tenor'], $field, var_export($expected, true), var_export($actual, true)); } } } printf("PHP engine: %d/%d checks match Excel over %d cases\n", $checks - count($failures), $checks, count($fixtures['cases'])); foreach (array_slice($failures, 0, 20) as $f) { echo " FAIL $f\n"; } exit($failures ? 1 : 0);