$content) { if (! is_dir(dirname($stage.'/'.$path))) { mkdir(dirname($stage.'/'.$path), 0700, true); } file_put_contents($stage.'/'.$path, $content); } require $stage.'/bootstrap.php'; $engine = new ReplenishmentProjection; $policy = ['daily_milli' => 10000, 'safety_milli' => 20000, 'target_milli' => 100000, 'maximum_milli' => 120000, 'lead_days' => 4, 'approval_days' => 1, 'minimum_milli' => 24000, 'pack_milli' => 12000, 'horizon_days' => 30]; $result = $engine->calculate($policy, 120000, '2026-11-01'); $rate = $engine->calculate([...$policy, 'horizon_days' => 3, 'daily_rate' => ['numerator_milli' => 1000, 'denominator_days' => 3]], 10000, '2026-11-01'); $lots = $engine->calculate([...$policy, 'horizon_days' => 2], 10000, '2026-11-01', [], [], 0, [], [['quantity' => 10000, 'last_usable_on' => '2026-11-01']]); if ($result['risk_date'] !== '2026-11-10' || $result['quantity_milli'] !== 84000 || array_column($rate['series'], 'demand_milli') !== [334, 333, 333] || $lots['series'][1]['expired_milli'] !== 0 || $lots['series'][1]['balance_milli'] !== -10000) { throw new RuntimeException('A versão candidata não preserva os resultados do contrato de integração.'); } $scenarios = ['manual', 'exact_historical_rate', 'lot_expiry']; if (in_array('procurement.unit_discounts', $checked['manifest']['module']['capabilities'], true)) { $pricing = new QuotationPricing; if ($pricing->unit('19.99', 'percent', '12.50')['net_unit_minor'] !== 1749 || $pricing->unit('0.03', 'percent', '50')['net_unit_minor'] !== 2) { throw new RuntimeException('Descontos incompatíveis com o contrato.'); } $scenarios[] = 'unit_discounts'; } if (in_array('procurement.proposal_scoring', $checked['manifest']['module']['capabilities'], true)) { $row = ['eligible' => true, 'subtotal_minor' => 10000, 'delivery_days' => 2, 'weights' => ['price' => 50, 'quality' => 50, 'delivery' => 0, 'history' => 0, 'payment' => 0], 'evaluation_count' => 2, 'qualified_evaluations' => array_fill(0, 2, ['quality' => '8', 'history' => '8', 'payment' => '8'])]; $ranking = (new ProposalScoring)->rank([['id' => 1, ...$row], ['id' => 2, ...$row]], 2); if ($ranking !== ['scores' => [1 => 900, 2 => 900], 'top_ids' => [1, 2]]) { throw new RuntimeException('Pontuação ou empates incompatíveis com o contrato.'); } $scenarios[] = 'proposal_scores_and_ties'; } echo json_encode(['version' => $checked['manifest']['version'], 'source_sha256' => $checked['manifest']['source_sha256'], 'runtime' => PHP_VERSION, 'scenarios' => $scenarios, 'passed' => true, 'database_connected' => false], JSON_THROW_ON_ERROR)."\n"; } catch (Throwable $error) { fwrite(STDERR, $error->getMessage()."\n"); $exitCode = 1; } finally { if ($stage !== null && is_dir($stage)) { $real = realpath($stage); $temporary = str_replace('\\', '/', realpath(sys_get_temp_dir())); if ($real !== false && str_starts_with(str_replace('\\', '/', $real), $temporary.'/sgc-purchasing-probe-')) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($real, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $file) { if ($file->isDir() && ! $file->isLink()) { rmdir($file->getPathname()); } else { unlink($file->getPathname()); } } rmdir($real); } } } exit($exitCode);