98 lines
3.1 KiB
PHP
98 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Sgc;
|
|
|
|
use App\Models\Sgc\Fatura;
|
|
use App\Models\Sgc\OrdemCompra;
|
|
use App\Models\Sgc\Recebimento;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class ThreeWayMatchService
|
|
{
|
|
private const TOLERANCIA_PERCENTUAL = 0.01; // 1%
|
|
private const TOLERANCIA_VALOR = 50.00; // 50 MT
|
|
|
|
/**
|
|
* Executa o 3-Way Match: OC + Recebimento + Fatura
|
|
*/
|
|
public function executarMatch(Fatura $fatura): array
|
|
{
|
|
$oc = $fatura->ordemCompra;
|
|
$recebimentos = $oc->recebimentos;
|
|
|
|
// Calcular total recebido
|
|
$valorTotalRecebido = $recebimentos->sum('valor_recebido');
|
|
$valorFatura = $fatura->valor_fatura;
|
|
$valorOC = $oc->valor_comprometido;
|
|
|
|
// Verificar divergências
|
|
$divergenciaOC = abs($valorFatura - $valorOC);
|
|
$divergenciaRecebimento = abs($valorFatura - $valorTotalRecebido);
|
|
|
|
// Aplicar tolerâncias
|
|
$toleranciaOC = max($valorOC * self::TOLERANCIA_PERCENTUAL, self::TOLERANCIA_VALOR);
|
|
$toleranciaRecebimento = max($valorTotalRecebido * self::TOLERANCIA_PERCENTUAL, self::TOLERANCIA_VALOR);
|
|
|
|
$matchOC = $divergenciaOC <= $toleranciaOC;
|
|
$matchRecebimento = $divergenciaRecebimento <= $toleranciaRecebimento;
|
|
|
|
// Determinar status
|
|
$status = 'Conforme';
|
|
$motivo = null;
|
|
|
|
if (!$matchOC && !$matchRecebimento) {
|
|
$status = 'Com Excecao';
|
|
$motivo = "Divergência com OC ({$divergenciaOC} MT) e Recebimento ({$divergenciaRecebimento} MT)";
|
|
} elseif (!$matchOC) {
|
|
$status = 'Com Excecao';
|
|
$motivo = "Divergência com OC: {$divergenciaOC} MT";
|
|
} elseif (!$matchRecebimento) {
|
|
$status = 'Com Excecao';
|
|
$motivo = "Divergência com Recebimento: {$divergenciaRecebimento} MT";
|
|
}
|
|
|
|
// Atualizar fatura
|
|
DB::transaction(function () use ($fatura, $status, $motivo) {
|
|
$fatura->update([
|
|
'status_3_way_match' => $status,
|
|
'motivo_excecao' => $motivo,
|
|
]);
|
|
});
|
|
|
|
Log::info('3-Way Match executado', [
|
|
'fatura_id' => $fatura->fatura_id,
|
|
'status' => $status,
|
|
'valor_fatura' => $valorFatura,
|
|
'valor_oc' => $valorOC,
|
|
'valor_recebido' => $valorTotalRecebido,
|
|
]);
|
|
|
|
return [
|
|
'status' => $status,
|
|
'motivo' => $motivo,
|
|
'valor_fatura' => $valorFatura,
|
|
'valor_oc' => $valorOC,
|
|
'valor_recebido' => $valorTotalRecebido,
|
|
'divergencia_oc' => $divergenciaOC,
|
|
'divergencia_recebimento' => $divergenciaRecebimento,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Processa todas as faturas pendentes de match
|
|
*/
|
|
public function processarPendentes(): int
|
|
{
|
|
$faturasPendentes = Fatura::where('status_3_way_match', 'Pendente')->get();
|
|
$processadas = 0;
|
|
|
|
foreach ($faturasPendentes as $fatura) {
|
|
$this->executarMatch($fatura);
|
|
$processadas++;
|
|
}
|
|
|
|
return $processadas;
|
|
}
|
|
}
|