Skip to main content

O quê / quando

Autorizador indisponível: registre o Evento Prévio de Emissão em Contingência (EPEC) e emita via SVC (SvcRs ou SvcSp), conforme a UF.

Registrar EPEC isolado

use Suot\Fiscal\Core\Exception\InfrastructureException;
use Suot\Fiscal\Core\Result\RetryMode;
use Suot\Fiscal\Core\ValueObject\Uf;
use Suot\Fiscal\Cte\ValueObject\CteEpecPayload;
use Suot\Fiscal\Cte\ValueObject\CteEpecTaker;

$payload = new CteEpecPayload(
    justification: 'Indisponibilidade operacional do autorizador em homologacao',
    icmsValue: '12.00',
    totalValue: '100.00',
    cargoValue: '1000.00',
    taker: new CteEpecTaker(
        role: '0',
        uf: 'RS',
        document: $cnpjTomador,
        ie: $ieTomador,
    ),
    originUf: 'RS',
    destinationUf: 'SP',
);

try {
    $epecResult = $cte->registerEpec()
        ->forOperation('epec-1')
        ->inHomologation()
        ->issuerUf(new Uf('RS'))
        ->accessKey($chave44)
        ->emitterCnpj($cnpj)
        ->epec($payload)
        ->handle();
} catch (InfrastructureException $e) {
    $failure = $e->toFailure('register_epec');
    // Host: alertar; filar retry conforme $failure->retryPolicy
    throw $e;
}

if (! $epecResult->isRejected()) {
    // Host: persistir protocolo do EPEC, responseXml, accessKey, operationId
}

if ($epecResult->isRejected()) {
    $failure = $epecResult->failure();
    $policy = $epecResult->retryPolicy();
    match ($policy?->mode) {
        RetryMode::AfterCorrection => /* corrigir payload/chave e registrar de novo */,
        RetryMode::AfterDelay, RetryMode::Immediate => /* filar conforme política */,
        RetryMode::QueryBeforeRetry => /* reconciliar antes de reenviar */,
        RetryMode::Never, null => /* definitivo; não reenviar */,
    };
}

Emissão em contingência (EPEC + SVC)

issueInContingency()->issue($command) exige um IssueCteCommand. Materialize com $cte->issue()…->build() e orquestre:
use Suot\Fiscal\Core\Exception\InfrastructureException;
use Suot\Fiscal\Core\Result\RetryMode;
use Suot\Fiscal\Cte\ValueObject\CteEmissionType;

$issueCommand = $cte->issue()
    ->forOperation('ot-123-contingency')
    ->inHomologation()
    // … mesma cadeia tipada da emissão normal …
    ->build();

try {
    $result = $cte->issueInContingency()
        ->issue($issueCommand)
        ->withEpec($payload)
        ->viaSvc(CteEmissionType::SvcRs) // ou SvcSp
        ->handle();
} catch (InfrastructureException $e) {
    $failure = $e->toFailure('issue_in_contingency');
    // Host: alertar; timeout ambíguo → QueryBeforeRetry antes de reemitir
    throw $e;
}

if ($result->isAuthorized()) {
    // Host: persistir artefatos de $result->issueResult e $result->epecResult
}

if ($result->isRejected()) {
    $failure = $result->failure();
    $policy = $result->retryPolicy();
    match ($policy?->mode) {
        RetryMode::AfterCorrection => /* corrigir dados; novo forOperation + build() + contingency */,
        RetryMode::QueryBeforeRetry => /* byAccessKey() antes de reemitir */,
        RetryMode::AfterDelay, RetryMode::Immediate => /* filar conforme política */,
        RetryMode::Never, null => /* definitivo; não reenviar */,
    };
}
Também é válido $cte->issueInContingency()->issue($cmd)->viaSvc(CteEmissionType::SvcSp)->handle() quando o fluxo de SVC não embute o EPEC no mesmo comando (conforme seu caso). Ver Emissão e Resultados.