UnknownSec Bypass
403
:
/
mnt
/
lmsestudio-instance-vol002
/
lms_8167adff8173
/
app
/
Console
/
Commands
/ [
drwxr-xr-x
]
Menu
Upload
Mass depes
Mass delete
Terminal
Info server
About
name :
UpdateRecurringFees.php
<?php namespace EstudioLMS\Console\Commands; use Carbon\Carbon; use EstudioLMS\Repositories\Financial\RecurringInterface; use EstudioLMS\Services\PagarMeService; use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; /** * Class UpdateRecurringFees * @package EstudioLMS\Console\Commands * * Comando para atualizar retroativamente as taxas (fee_amount e net_amount) * das recorrências que foram processadas mas não tiveram as taxas calculadas. */ class UpdateRecurringFees extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'recurring:update-fees {--date= : Data inicial para buscar recorrências (formato: YYYY-MM-DD)} {--limit= : Limite de recorrências a processar por execução (padrão: 100)} {--dry-run : Simula a execução sem fazer alterações no banco}'; /** * The console command description. * * @var string */ protected $description = 'Atualiza retroativamente as taxas das recorrências pagas que não possuem fee_amount calculado'; /** * @var RecurringInterface */ private $recurring; /** * @var PagarMeService */ private $pagarMeService; /** * Create a new command instance. * * @param RecurringInterface $recurring * @param PagarMeService $pagarMeService */ public function __construct( RecurringInterface $recurring, PagarMeService $pagarMeService ) { parent::__construct(); $this->recurring = $recurring; $this->pagarMeService = $pagarMeService; } /** * Execute the console command. * * @return void */ public function handle() { // Verificar se extensão curl está disponível if (!function_exists('curl_init')) { $this->error('========================================'); $this->error('❌ ERRO: Extensão CURL não está habilitada'); $this->error('========================================'); $this->line(''); $this->warn('A extensão PHP CURL é necessária para este comando funcionar.'); $this->warn('Esta extensão é usada para fazer requisições à API do PagarMe.'); $this->line(''); $this->info('Para instalar a extensão CURL, execute:'); $this->line(' sudo apt-get install php7.1-curl'); $this->line(' sudo service apache2 restart # ou nginx restart'); $this->line(''); $this->info('Ou, se usar PHP-FPM:'); $this->line(' sudo service php7.1-fpm restart'); $this->line(''); $this->error('Comando abortado.'); Log::error('Comando recurring:update-fees falhou - extensão curl não disponível'); return 1; } $startDate = $this->option('date') ?: '2024-01-01'; $limit = $this->option('limit') ?: 100; $dryRun = $this->option('dry-run'); $this->info('========================================'); $this->info('ATUALIZAÇÃO RETROATIVA DE TAXAS'); $this->info('========================================'); $this->info('Data inicial: ' . $startDate); $this->info('Limite: ' . $limit . ' recorrências'); $this->info('Modo: ' . ($dryRun ? 'SIMULAÇÃO (dry-run)' : 'EXECUÇÃO REAL')); $this->info('========================================'); $this->line(''); if ($dryRun) { $this->warn('⚠️ MODO SIMULAÇÃO - Nenhuma alteração será feita no banco de dados'); $this->line(''); } Log::info('Iniciando atualização retroativa de taxas de recorrências', [ 'start_date' => $startDate, 'limit' => $limit, 'dry_run' => $dryRun ]); // Buscar recorrências pagas sem taxas calculadas $recurrings = $this->recurring->scopeQuery(function($query) use ($startDate, $limit) { return $query->where('status', '=', 1) // Apenas pagas ->where(function($q) { $q->where('fee_amount', '=', 0) ->orWhere('fee_amount', '=', 0.00) ->orWhereNull('fee_amount'); }) ->where('payment_code', '!=', '') ->whereNotNull('payment_code') ->where('payment_date', '>=', $startDate) ->orderBy('payment_date', 'asc') ->limit($limit); })->all(); $total = count($recurrings); if ($total === 0) { $this->info('✅ Nenhuma recorrência encontrada para atualizar.'); Log::info('Nenhuma recorrência encontrada para atualizar taxas'); return; } $this->info("📋 Encontradas {$total} recorrências para processar\n"); $bar = $this->output->createProgressBar($total); $bar->setFormat('verbose'); $successCount = 0; $errorCount = 0; $skippedCount = 0; $errors = []; foreach ($recurrings as $recurring) { try { $result = $this->processRecurring($recurring, $dryRun); if ($result['success']) { $successCount++; if (!$dryRun) { $this->line("\n✅ Recorrência #{$recurring->id} atualizada - Taxa: R$ " . number_format($result['fee_amount'], 2, ',', '.')); } else { $this->line("\n🔍 [DRY-RUN] Recorrência #{$recurring->id} - Taxa calculada: R$ " . number_format($result['fee_amount'], 2, ',', '.')); } } elseif ($result['skipped']) { $skippedCount++; $this->line("\n⏭️ Recorrência #{$recurring->id} ignorada - " . $result['reason']); } else { $errorCount++; $error = "Recorrência #{$recurring->id}: " . $result['error']; $errors[] = $error; $this->line("\n❌ {$error}"); } } catch (\Exception $e) { $errorCount++; $error = "Recorrência #{$recurring->id}: " . $e->getMessage(); $errors[] = $error; $this->error("\n❌ {$error}"); Log::error('Erro ao processar recorrência', [ 'recurring_id' => $recurring->id, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); } $bar->advance(); // Pequeno delay para não sobrecarregar a API usleep(200000); // 200ms } $bar->finish(); $this->line("\n"); $this->line('========================================'); $this->info('RESUMO DA EXECUÇÃO'); $this->line('========================================'); $this->info("Total processado: {$total}"); $this->info("✅ Sucesso: {$successCount}"); if ($skippedCount > 0) { $this->warn("⏭️ Ignorados: {$skippedCount}"); } if ($errorCount > 0) { $this->error("❌ Erros: {$errorCount}"); if (count($errors) > 0 && count($errors) <= 10) { $this->line("\nErros encontrados:"); foreach ($errors as $error) { $this->error(" - {$error}"); } } elseif (count($errors) > 10) { $this->line("\nPrimeiros 10 erros:"); for ($i = 0; $i < 10; $i++) { $this->error(" - {$errors[$i]}"); } $this->error(" ... e mais " . (count($errors) - 10) . " erros"); } } $this->line('========================================'); Log::info('Atualização retroativa de taxas concluída', [ 'total' => $total, 'success' => $successCount, 'errors' => $errorCount, 'skipped' => $skippedCount, 'dry_run' => $dryRun ]); } /** * Processa uma recorrência individual * * @param object $recurring * @param bool $dryRun * @return array */ private function processRecurring($recurring, $dryRun = false) { // Validar se tem payment_code if (empty($recurring->payment_code)) { return [ 'success' => false, 'skipped' => true, 'reason' => 'Sem payment_code' ]; } // Tentar extrair charge_id do payment_code $chargeId = $this->extractChargeId($recurring->payment_code); if (!$chargeId) { return [ 'success' => false, 'skipped' => true, 'reason' => "Payment code inválido: {$recurring->payment_code}" ]; } Log::info('Processando recorrência para atualização de taxas', [ 'recurring_id' => $recurring->id, 'payment_code' => $recurring->payment_code, 'charge_id' => $chargeId, 'payment_date' => $recurring->payment_date, 'gross_amount' => $recurring->gross_amount ]); // Buscar taxas via PagarMeService try { $feeAmount = $this->pagarMeService->calculateFeeAmountPublic($chargeId); if ($feeAmount === false || $feeAmount === null) { return [ 'success' => false, 'error' => 'Não foi possível calcular fee_amount via API' ]; } $netAmount = $recurring->gross_amount - $feeAmount; Log::info('Taxas calculadas para recorrência', [ 'recurring_id' => $recurring->id, 'fee_amount' => $feeAmount, 'net_amount' => $netAmount, 'gross_amount' => $recurring->gross_amount ]); // Se não for dry-run, atualizar o banco if (!$dryRun) { $recurring->fee_amount = $feeAmount; $recurring->net_amount = $netAmount; $recurring->save(); Log::info('Recorrência atualizada com sucesso', [ 'recurring_id' => $recurring->id, 'fee_amount' => $feeAmount, 'net_amount' => $netAmount ]); } return [ 'success' => true, 'fee_amount' => $feeAmount, 'net_amount' => $netAmount ]; } catch (\Exception $e) { Log::error('Erro ao calcular taxas para recorrência', [ 'recurring_id' => $recurring->id, 'charge_id' => $chargeId, 'error' => $e->getMessage() ]); return [ 'success' => false, 'error' => $e->getMessage() ]; } } /** * Extrai o charge_id do payment_code * * Payment code pode ser: * - Order ID (or_xxxxx) - precisa buscar o charge * - Charge ID (ch_xxxxx) - usar direto * * @param string $paymentCode * @return string|null */ private function extractChargeId($paymentCode) { if (empty($paymentCode)) { return null; } // Se já é um charge_id, retornar direto if (strpos($paymentCode, 'ch_') === 0) { return $paymentCode; } // Se é um order_id, buscar o charge via API if (strpos($paymentCode, 'or_') === 0) { try { $order = $this->pagarMeService->getOrder($paymentCode); if (isset($order['charges']) && !empty($order['charges'])) { $charge = $order['charges'][0]; return $charge['id']; } } catch (\Exception $e) { Log::error('Erro ao buscar order para extrair charge_id', [ 'order_id' => $paymentCode, 'error' => $e->getMessage() ]); return null; } } return null; } }
Copyright © 2026 - UnknownSec