public function confirmed($project = null, $id = null, $reward = null) { if (empty($id)) { Message::Error(Text::get('invest-data-error')); throw new Redirection('/', Redirection::TEMPORARY); } // el aporte $invest = Model\Invest::get($id); $projectData = Model\Project::getMedium($invest->project); // para evitar las duplicaciones de feed y email if (isset($_SESSION['invest_' . $invest->id . '_completed'])) { Message::Info(Text::get('invest-process-completed')); throw new Redirection($retUrl); } // segun método if ($invest->method == 'tpv') { // si el aporte no está en estado "cobrado por goteo" (1) if ($invest->status != '1') { @mail('*****@*****.**', 'Aporte tpv no pagado ' . $invest->id, 'Ha llegado a invest/confirm el aporte ' . $invest->id . ' mediante tpv sin estado cobrado (llega con estado ' . $invest->status . ')'); // mandarlo a la pagina de aportar para que lo intente de nuevo // si es de Bazar, a la del producto del catálogo if ($project == 'bazargoteo') { throw new Redirection("/bazaar/{$reward}/fail"); } else { throw new Redirection("/project/{$invest->project}/invest/?confirm=fail"); } } } // Paypal solo disponible si activado if ($invest->method == 'paypal') { // hay que cambiarle el status a 0 $invest->setStatus('0'); // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Aporte PayPal', '/admin/invests', \vsprintf("%s ha aportado %s al proyecto %s mediante PayPal", array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('money', $invest->amount . ' €'), Feed::item('project', $projectData->name, $projectData->id)))); $log->doAdmin('money'); // evento público $log_html = Text::html('feed-invest', Feed::item('money', $invest->amount . ' €'), Feed::item('project', $projectData->name, $projectData->id)); if ($invest->anonymous) { $log->populate(Text::get('regular-anonymous'), '/user/profile/anonymous', $log_html, 1); } else { $log->populate($_SESSION['user']->name, '/user/profile/' . $_SESSION['user']->id, $log_html, $_SESSION['user']->avatar->id); } $log->doPublic('community'); unset($log); } // fin segun metodo // Feed del aporte de la campaña if (!empty($invest->droped) && $drop instanceof Model\Invest && is_object($callData)) { // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Aporte riego ' . $drop->method, '/admin/invests', \vsprintf("%s ha aportado %s de %s al proyecto %s a través de la campaña %s", array(Feed::item('user', $callData->user->name, $callData->user->id), Feed::item('money', $drop->amount . ' €'), Feed::item('drop', 'Capital Riego', '/service/resources'), Feed::item('project', $projectData->name, $projectData->id), Feed::item('call', $callData->name, $callData->id)))); $log->doAdmin('money'); // evento público $log->populate($callData->user->name, '/user/profile/' . $callData->user->id, Text::html('feed-invest', Feed::item('money', $drop->amount . ' €') . ' de ' . Feed::item('drop', 'Capital Riego', '/service/resources'), Feed::item('project', $projectData->name, $projectData->id) . ' a través de la campaña ' . Feed::item('call', $callData->name, $callData->id)), $callData->user->avatar->id); $log->doPublic('community'); unset($log); } // texto recompensa // @TODO quitar esta lacra de N recompensas porque ya es solo una recompensa siempre $rewards = $invest->rewards; array_walk($rewards, function (&$reward) { $reward = $reward->reward; }); $txt_rewards = implode(', ', $rewards); // recaudado y porcentaje $amount = $projectData->invested; $percent = floor($projectData->invested / $projectData->mincost * 100); // email de agradecimiento al cofinanciador // primero monto el texto de recompensas //@TODO el concepto principal sería 'renuncia' (porque todos los aportes son donativos) if ($invest->resign) { // Plantilla de donativo segun la ronda if ($projectData->round == 2) { $template = Template::get(36); // en segunda ronda } else { $template = Template::get(28); // en primera ronda } } else { // plantilla de agradecimiento segun la ronda if ($projectData->round == 2) { $template = Template::get(34); // en segunda ronda } else { $template = Template::get(10); // en primera ronda } } // Dirección en el mail (y version para regalo) $txt_address = Text::get('invest-address-address-field') . ' ' . $invest->address->address; $txt_address .= '<br> ' . Text::get('invest-address-zipcode-field') . ' ' . $invest->address->zipcode; $txt_address .= '<br> ' . Text::get('invest-address-location-field') . ' ' . $invest->address->location; $txt_address .= '<br> ' . Text::get('invest-address-country-field') . ' ' . $invest->address->country; $txt_destaddr = $txt_address; $txt_address = Text::get('invest-mail_info-address') . '<br>' . $txt_address; // Agradecimiento al cofinanciador // Sustituimos los datos $subject = str_replace('%PROJECTNAME%', $projectData->name, $template->title); // En el contenido: $search = array('%USERNAME%', '%PROJECTNAME%', '%PROJECTURL%', '%AMOUNT%', '%REWARDS%'); $replace = array($_SESSION['user']->name, $projectData->name, SITE_URL . '/project/' . $projectData->id, $confirm->amount, $txt_rewards); $content = \str_replace($search, $replace, $template->text); $mailHandler = new Mail(); $mailHandler->reply = GOTEO_CONTACT_MAIL; $mailHandler->replyName = GOTEO_MAIL_NAME; $mailHandler->to = $_SESSION['user']->email; $mailHandler->toName = $_SESSION['user']->name; $mailHandler->subject = $subject; $mailHandler->content = $content; $mailHandler->html = true; $mailHandler->template = $template->id; if ($mailHandler->send($errors)) { Message::Info(Text::get('project-invest-thanks_mail-success')); } else { Message::Error(Text::get('project-invest-thanks_mail-fail')); Message::Error(implode('<br />', $errors)); } unset($mailHandler); // Notificación al autor $template = Template::get(29); // Sustituimos los datos $subject = str_replace('%PROJECTNAME%', $projectData->name, $template->title); // En el contenido: $search = array('%OWNERNAME%', '%USERNAME%', '%PROJECTNAME%', '%SITEURL%', '%AMOUNT%', '%MESSAGEURL%'); $replace = array($projectData->user->name, $_SESSION['user']->name, $projectData->name, SITE_URL, $invest->amount, SITE_URL . '/user/profile/' . $_SESSION['user']->id . '/message'); $content = \str_replace($search, $replace, $template->text); $mailHandler = new Mail(); $mailHandler->to = $projectData->user->email; $mailHandler->toName = $projectData->user->name; $mailHandler->subject = $subject; $mailHandler->content = $content; $mailHandler->html = true; $mailHandler->template = $template->id; $mailHandler->send(); unset($mailHandler); // marcar que ya se ha completado el proceso de aportar $_SESSION['invest_' . $invest->id . '_completed'] = true; // log Model\Invest::setDetail($invest->id, 'confirmed', 'El usuario regresó a /invest/confirmed'); if ($confirm->method == 'paypal') { // hay que cambiarle el status a 0 $confirm->setStatus('0'); /* * Evento Feed */ $log = new Feed(); $log->title = 'Aporte PayPal'; $log->url = '/admin/invests'; $log->type = 'money'; $log_text = "%s ha aportado %s al proyecto %s mediante PayPal"; $items = array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('money', $confirm->amount . ' €'), Feed::item('project', $projectData->name, $projectData->id)); $log->html = \vsprintf($log_text, $items); $log->add($errors); // evento público if ($confirm->anonymous) { $log->title = Text::get('regular-anonymous'); $log->url = '/user/profile/anonymous'; $log->image = 1; } else { $log->title = $_SESSION['user']->name; $log->url = '/user/profile/' . $_SESSION['user']->id; $log->image = $_SESSION['user']->avatar->id; } $log->scope = 'public'; $log->type = 'community'; $log->html = Text::html('feed-invest', Feed::item('money', $confirm->amount . ' €'), Feed::item('project', $projectData->name, $projectData->id)); $log->add($errors); unset($log); } // mandarlo a la pagina de gracias throw new Redirection("/project/{$project}/invest/?confirm=ok", Redirection::TEMPORARY); }
public static function cancelPreapproval($invest, &$errors = array(), $fail = false) { try { if (empty($invest->preapproval)) { $invest->cancel($fail); return true; } $CPRequest = new \CancelPreapprovalRequest(); $CPRequest->requestEnvelope = new \RequestEnvelope(); $CPRequest->requestEnvelope->errorLanguage = "es_ES"; $CPRequest->preapprovalKey = $invest->preapproval; $ap = new \AdaptivePayments(); $response = $ap->CancelPreapproval($CPRequest); if (strtoupper($ap->isSuccess) == 'FAILURE') { Invest::setDetail($invest->id, 'paypal-cancel-fail', 'Ha fallado al cancelar el preapproval. Proceso libary/paypal::cancelPreapproval'); $errors[] = 'Preapproval cancel failed.' . $ap->getLastError(); @mail(\GOTEO_FAIL_MAIL, 'Fallo al cancelar preapproval Paypal API', 'ERROR en ' . __FUNCTION__ . '<br /><pre>' . print_r($ap->getLastError(), 1) . '</pre>'); return false; } else { Invest::setDetail($invest->id, 'paypal-cancel', 'El Preapproval se ha cancelado y con ello el aporte. Proceso libary/paypal::cancelPreapproval'); $invest->cancel($fail); return true; } } catch (Exception $ex) { $fault = new \FaultMessage(); $errorData = new \ErrorData(); $errorData->errorId = $ex->getFile(); $errorData->message = $ex->getMessage(); $fault->error = $errorData; Invest::setDetail($invest->id, 'paypal-cancel-fail', 'Ha fallado al cancelar el preapproval. Proceso libary/paypal::cancelPreapproval'); $errors[] = 'Error fatal en la comunicación con Paypal, se ha reportado la incidencia. Disculpe las molestias.'; @mail(\GOTEO_FAIL_MAIL, 'Error fatal en comunicacion Paypal API', 'ERROR en ' . __FUNCTION__ . '<br /><pre>' . print_r($fault, 1) . '</pre>'); return false; } }
public static function process($action = 'list', $id = null, $filters = array()) { $errors = array(); // reubicando aporte, if ($action == 'move') { // el aporte original $original = Model\Invest::get($id); $userData = Model\User::getMini($original->user); $projectData = Model\Project::getMini($original->project); //el original tiene que ser de tpv o cash y estar como 'cargo ejecutado' if ($original->method == 'paypal' || $original->status != 1) { Message::Error('No se puede reubicar este aporte!'); throw new Redirection('/admin/accounts'); } // generar aporte manual y caducar el original if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['move'])) { // si falta proyecto, error $projectNew = $_POST['project']; // @TODO a saber si le toca dinero de alguna convocatoria $campaign = null; $invest = new Model\Invest(array('amount' => $original->amount, 'user' => $original->user, 'project' => $projectNew, 'account' => $userData->email, 'method' => 'cash', 'status' => '1', 'invested' => date('Y-m-d'), 'charged' => $original->charged, 'anonymous' => $original->anonymous, 'resign' => $original->resign, 'admin' => $_SESSION['user']->id, 'campaign' => $campaign)); //@TODO si el proyecto seleccionado if ($invest->save($errors)) { //recompensas que le tocan (si no era resign) if (!$original->resign) { // sacar recompensas $rewards = Model\Project\Reward::getAll($projectNew, 'individual'); foreach ($rewards as $rewId => $rewData) { $invest->setReward($rewId); //asignar } } // cambio estado del aporte original a 'Reubicado' (no aparece en cofinanciadores) // si tuviera que aparecer lo marcaríamos como caducado if ($original->setStatus('5')) { // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Aporte reubicado', '/admin/accounts', \vsprintf("%s ha aportado %s al proyecto %s en nombre de %s", array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('money', $_POST['amount'] . ' €'), Feed::item('project', $projectData->name, $projectData->id), Feed::item('user', $userData->name, $userData->id)))); $log->doAdmin('money'); unset($log); Message::Info('Aporte reubicado correctamente'); throw new Redirection('/admin/accounts'); } else { $errors[] = 'A fallado al cambiar el estado del aporte original (' . $original->id . ')'; } } else { $errors[] = 'Ha fallado algo al reubicar el aporte'; } } $viewData = array('folder' => 'accounts', 'file' => 'move', 'original' => $original, 'user' => $userData, 'project' => $projectData); return new View('view/admin/index.html.php', $viewData); // fin de la historia dereubicar } // cambiando estado del aporte aporte, if ($action == 'update') { // el aporte original $invest = Model\Invest::get($id); if (!$invest instanceof Model\Invest) { Message::Error('No tenemos registro del aporte ' . $id); throw new Redirection('/admin/accounts'); } $status = Model\Invest::status(); $new = isset($_POST['status']) ? $_POST['status'] : null; if ($invest->issue && $_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['update']) && $_POST['resolve'] == 1) { Model\Invest::unsetIssue($id); Model\Invest::setDetail($id, 'issue-solved', 'La incidencia se ha dado por resuelta por el usuario ' . $_SESSION['user']->name); Message::Info('La incidencia se ha dado por resuelta'); } if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['update']) && isset($new) && isset($status[$new])) { if ($new != $invest->status) { if (Model\Invest::query("UPDATE invest SET status=:status WHERE id=:id", array(':id' => $id, ':status' => $new))) { Model\Invest::setDetail($id, 'status-change' . rand(0, 9999), 'El admin ' . $_SESSION['user']->name . ' ha cambiado el estado del apote a ' . $status[$new]); Message::Info('Se ha actualizado el estado del aporte'); } else { Message::Error('Ha fallado al actualizar el estado del aporte'); } } else { Message::Error('No se ha cambiado el estado'); } throw new Redirection('/admin/accounts/details/' . $id); } return new View('view/admin/index.html.php', array('folder' => 'accounts', 'file' => 'update', 'invest' => $invest, 'status' => $status)); // fin de la historia actualizar estado } // resolviendo incidencias if ($action == 'solve') { // el aporte original $invest = Model\Invest::get($id); if (!$invest instanceof Model\Invest) { Message::Error('No tenemos registro del aporte ' . $id); throw new Redirection('/admin/accounts'); } $projectData = Model\Project::getMini($invest->project); $errors = array(); // primero cancelar switch ($invest->method) { case 'paypal': $err = array(); if (Paypal::cancelPreapproval($invest, $err)) { $errors[] = 'Preaproval paypal cancelado.'; $log_text = "El admin %s ha cancelado aporte y preapproval de %s de %s mediante PayPal (id: %s) al proyecto %s del dia %s"; } else { $txt_errors = implode('; ', $err); $errors[] = 'Fallo al cancelar el preapproval en paypal: ' . $txt_errors; $log_text = "El admin %s ha fallado al cancelar el aporte de %s de %s mediante PayPal (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: {$txt_errors}"; if ($invest->cancel()) { $errors[] = 'Aporte cancelado'; } else { $errors[] = 'Fallo al cancelar el aporte'; } } break; case 'tpv': $err = array(); if (Tpv::cancelPreapproval($invest, $err)) { $txt_errors = implode('; ', $err); $errors[] = 'Aporte cancelado correctamente. ' . $txt_errors; $log_text = "El admin %s ha anulado el cargo tpv de %s de %s mediante TPV (id: %s) al proyecto %s del dia %s"; } else { $txt_errors = implode('; ', $err); $errors[] = 'Fallo en la operación. ' . $txt_errors; $log_text = "El admin %s ha fallado al solicitar la cancelación del cargo tpv de %s de %s mediante TPV (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: {$txt_errors}"; } break; case 'cash': if ($invest->cancel()) { $log_text = "El admin %s ha cancelado aporte manual de %s de %s (id: %s) al proyecto %s del dia %s"; $errors[] = 'Aporte cancelado'; } else { $log_text = "El admin %s ha fallado al cancelar el aporte manual de %s de %s (id: %s) al proyecto %s del dia %s. "; $errors[] = 'Fallo al cancelar el aporte'; } break; } // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Cargo cancelado manualmente (admin)', '/admin/accounts', \vsprintf($log_text, array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $projectData->name, $projectData->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin(); unset($log); // luego resolver if ($invest->solve($errors)) { // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Incidencia resuelta (admin)', '/admin/accounts', \vsprintf("El admin %s ha dado por resuelta la incidencia con el botón \"Nos han hecho la transferencia\" para el aporte %s", array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('system', $id, 'accounts/details/' . $id)))); $log->doAdmin('admin'); unset($log); Message::Info('La incidencia se ha dado por resuelta, el aporte se ha pasado a manual y cobrado'); throw new Redirection('/admin/accounts'); } else { // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Fallo al resolver incidencia (admin)', '/admin/accounts', \vsprintf("Al admin %s le ha fallado el botón \"Nos han hecho la transferencia\" para el aporte %s", array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('system', $id, 'accounts/details/' . $id)))); $log->doAdmin('admin'); unset($log); Message::Error('Ha fallado al resolver la incidencia: ' . implode(',', $errors)); throw new Redirection('/admin/accounts/details/' . $id); } } // aportes manuales, cargamos la lista completa de usuarios, proyectos y campañas if ($action == 'add') { // listado de proyectos en campaña $projects = Model\Project::active(false, true); // usuarios $users = Model\User::getAllMini(); // campañas //@CALLSYS $calls = array(); // generar aporte manual if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['add'])) { $userData = Model\User::getMini($_POST['user']); $projectData = Model\Project::getMini($_POST['project']); $invest = new Model\Invest(array('amount' => $_POST['amount'], 'user' => $userData->id, 'project' => $projectData->id, 'account' => $userData->email, 'method' => 'cash', 'status' => '1', 'invested' => date('Y-m-d'), 'charged' => date('Y-m-d'), 'anonymous' => $_POST['anonymous'], 'resign' => 1, 'admin' => $_SESSION['user']->id)); //@CALLSYS if ($invest->save($errors)) { // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Aporte manual (admin)', '/admin/accounts', \vsprintf("%s ha aportado %s al proyecto %s en nombre de %s", array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('money', $_POST['amount'] . ' €'), Feed::item('project', $projectData->name, $projectData->id), Feed::item('user', $userData->name, $userData->id)))); $log->doAdmin('money'); unset($log); Model\Invest::setDetail($invest->id, 'admin-created', 'Este aporte ha sido creado manualmente por el admin ' . $_SESSION['user']->name); Message::Info('Aporte manual creado correctamente, seleccionar recompensa y dirección de entrega.'); throw new Redirection('/admin/rewards/edit/' . $invest->id); } else { $errors[] = 'Ha fallado algo al crear el aporte manual'; } } $viewData = array('folder' => 'accounts', 'file' => 'add', 'autocomplete' => true, 'users' => $users, 'projects' => $projects, 'calls' => $calls); return new View('view/admin/index.html.php', $viewData); // fin de la historia } // Informe de la financiación de un proyecto if ($action == 'report') { // estados de aporte $project = Model\Project::get($id); if (!$project instanceof Model\Project) { Message::Error('Instancia de proyecto no valida'); throw new Redirection('/admin/accounts'); } $invests = Model\Invest::getAll($id); $project->investors = Model\Invest::investors($id, false, true); $users = $project->agregateInvestors(); $investStatus = Model\Invest::status(); // Datos para el informe de transacciones correctas $Data = Model\Invest::getReportData($project->id, $project->status, $project->round, $project->passed); return new View('view/admin/index.html.php', array('folder' => 'accounts', 'file' => 'report', 'invests' => $invests, 'project' => $project, 'status' => $status, 'users' => $users, 'investStatus' => $investStatus, 'Data' => $Data)); } // cancelar aporte antes de ejecución, solo aportes no cargados if ($action == 'cancel') { $invest = Model\Invest::get($id); if (!$invest instanceof Model\Invest) { Message::Error('No tenemos objeto para el aporte ' . $id); throw new Redirection('/admin/accounts'); } $project = Model\Project::get($invest->project); $userData = Model\User::get($invest->user); if ($project->status > 3 && $project->status < 6) { $errors[] = 'No debería poderse cancelar un aporte cuando el proyecto ya está financiado. Si es imprescindible, hacerlo desde el panel de paypal o tpv'; break; } switch ($invest->method) { case 'paypal': $err = array(); if (Paypal::cancelPreapproval($invest, $err)) { $errors[] = 'Preaproval paypal cancelado.'; $log_text = "El admin %s ha cancelado aporte y preapproval de %s de %s mediante PayPal (id: %s) al proyecto %s del dia %s"; } else { $txt_errors = implode('; ', $err); $errors[] = 'Fallo al cancelar el preapproval en paypal: ' . $txt_errors; $log_text = "El admin %s ha fallado al cancelar el aporte de %s de %s mediante PayPal (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: {$txt_errors}"; if ($invest->cancel()) { $errors[] = 'Aporte cancelado'; } else { $errors[] = 'Fallo al cancelar el aporte'; } } break; case 'tpv': $err = array(); if (Tpv::cancelPreapproval($invest, $err)) { $txt_errors = implode('; ', $err); $errors[] = 'Aporte cancelado correctamente. ' . $txt_errors; $log_text = "El admin %s ha anulado el cargo tpv de %s de %s mediante TPV (id: %s) al proyecto %s del dia %s"; } else { $txt_errors = implode('; ', $err); $errors[] = 'Fallo en la operación. ' . $txt_errors; $log_text = "El admin %s ha fallado al solicitar la cancelación del cargo tpv de %s de %s mediante TPV (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: {$txt_errors}"; } break; case 'cash': if ($invest->cancel()) { $log_text = "El admin %s ha cancelado aporte manual de %s de %s (id: %s) al proyecto %s del dia %s"; $errors[] = 'Aporte cancelado'; } else { $log_text = "El admin %s ha fallado al cancelar el aporte manual de %s de %s (id: %s) al proyecto %s del dia %s. "; $errors[] = 'Fallo al cancelar el aporte'; } break; } // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Cargo cancelado manualmente (admin)', '/admin/accounts', \vsprintf($log_text, array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin(); Model\Invest::setDetail($invest->id, 'manually-canceled', $log->html); unset($log); } // ejecutar cargo ahora!!, solo aportes no ejecutados // si esta pendiente, ejecutar el cargo ahora (como si fuera final de ronda), deja pendiente el pago secundario if ($action == 'execute' && $invest->status == 0) { $invest = Model\Invest::get($id); if (!$invest instanceof Model\Invest) { Message::Error('No tenemos objeto para el aporte ' . $id); throw new Redirection('/admin/accounts'); } $project = Model\Project::get($invest->project); $userData = Model\User::get($invest->user); switch ($invest->method) { case 'paypal': // a ver si tiene cuenta paypal $projectAccount = Model\Project\Account::get($invest->project); if (empty($projectAccount->paypal)) { // Erroraco! $errors[] = 'El proyecto no tiene cuenta paypal!!, ponersela en la seccion Contrato del dashboard del autor'; $log_text = null; // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('proyecto sin cuenta paypal (admin)', '/admin/projects', \vsprintf('El proyecto %s aun no ha puesto su %s !!!', array(Feed::item('project', $project->name, $project->id), Feed::item('relevant', 'cuenta PayPal')))); $log->doAdmin('project'); unset($log); break; } $invest->account = $projectAccount->paypal; if (Paypal::pay($invest, $errors)) { $errors[] = 'Cargo paypal correcto'; $log_text = "El admin %s ha ejecutado el cargo a %s por su aporte de %s mediante PayPal (id: %s) al proyecto %s del dia %s"; $invest->status = 1; // si era incidencia la desmarcamos if ($invest->issue) { Model\Invest::unsetIssue($invest->id); Model\Invest::setDetail($invest->id, 'issue-solved', 'La incidencia se ha dado por resuelta al ejecutar el aporte manualmente por el admin ' . $_SESSION['user']->name); } } else { $txt_errors = implode('; ', $errors); $errors[] = 'Fallo al ejecutar cargo paypal: ' . $txt_errors . '<strong>POSIBLE INCIDENCIA NO COMUNICADA Y APORTE NO CANCELADO, HAY QUE TRATARLA MANUALMENTE</strong>'; $log_text = "El admin %s ha fallado al ejecutar el cargo a %s por su aporte de %s mediante PayPal (id: %s) al proyecto %s del dia %s. <br />Se han dado los siguientes errores: {$txt_errors}"; } break; case 'tpv': if (Tpv::pay($invest, $errors)) { $errors[] = 'Cargo sermepa correcto'; $log_text = "El admin %s ha ejecutado el cargo a %s por su aporte de %s mediante TPV (id: %s) al proyecto %s del dia %s"; $invest->status = 1; } else { $txt_errors = implode('; ', $errors); $errors[] = 'Fallo al ejecutar cargo sermepa: ' . $txt_errors; $log_text = "El admin %s ha fallado al ejecutar el cargo a %s por su aporte de %s mediante TPV (id: %s) al proyecto %s del dia %s <br />Se han dado los siguientes errores: {$txt_errors}"; } break; case 'cash': $invest->setStatus('1'); $errors[] = 'Aporte al contado, nada que ejecutar.'; $log_text = "El admin %s ha dado por ejecutado el aporte manual a nombre de %s por la cantidad de %s (id: %s) al proyecto %s del dia %s"; $invest->status = 1; break; } if (!empty($log_text)) { // Evento Feed $log = new Feed(); $log->setTarget($project->id); $log->populate('Cargo ejecutado manualmente (admin)', '/admin/accounts', \vsprintf($log_text, array(Feed::item('user', $_SESSION['user']->name, $_SESSION['user']->id), Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('system', $invest->id), Feed::item('project', $project->name, $project->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin(); Model\Invest::setDetail($invest->id, 'manually-executed', $log->html); unset($log); } } // visor de logs if ($action == 'viewer') { return new View('view/admin/index.html.php', array('folder' => 'accounts', 'file' => 'viewer')); } if ($action == 'resign' && !empty($id) && $_GET['token'] == md5('resign')) { if ($invest->setResign(true)) { Model\Invest::setDetail($invest->id, 'manually-resigned', 'Se ha marcado como donativo independientemente de las recompensas'); throw new Redirection('/admin/accounts/detail/' . $invest->id); } else { $errors[] = 'Ha fallado al marcar donativo'; } } if (!empty($errors)) { Message::Error(implode('<br />', $errors)); } // tipos de aporte $methods = Model\Invest::methods(); // estados del proyecto $status = Model\Project::status(); $procStatus = Model\Project::procStatus(); // estados de aporte $investStatus = Model\Invest::status(); // listado de proyectos $projects = Model\Invest::projects(); // usuarios cofinanciadores $users = Model\Invest::users(true); // campañas que tienen aportes $calls = Model\Invest::calls(); // extras $types = array('donative' => 'Solo los donativos', 'anonymous' => 'Solo los anónimos', 'manual' => 'Solo los manuales', 'campaign' => 'Solo con riego'); // filtros de revisión de proyecto $review = array('collect' => 'Recaudado', 'paypal' => 'Rev. PayPal', 'tpv' => 'Rev. TPV', 'online' => 'Pagos Online'); $issue = array('show' => 'Solamente las incidencias', 'hide' => 'Ocultar las incidencias'); /// detalles de una transaccion if ($action == 'details') { $invest = Model\Invest::get($id); $project = Model\Project::get($invest->project); $userData = Model\User::get($invest->user); return new View('view/admin/index.html.php', array('folder' => 'accounts', 'file' => 'details', 'invest' => $invest, 'project' => $project, 'user' => $userData, 'details' => $details, 'status' => $status, 'investStatus' => $investStatus)); } // listado de aportes if ($filters['filtered'] == 'yes') { $list = Model\Invest::getList($filters, null, 999); } else { $list = array(); } $viewData = array('folder' => 'accounts', 'file' => 'list', 'list' => $list, 'filters' => $filters, 'users' => $users, 'projects' => $projects, 'calls' => $calls, 'review' => $review, 'methods' => $methods, 'types' => $types, 'status' => $status, 'procStatus' => $procStatus, 'issue' => $issue, 'investStatus' => $investStatus); return new View('view/admin/index.html.php', $viewData); }
public function dopay($project) { die('Ya no realizamos pagos secundarios mediante sistema'); if (\defined('CRON_EXEC')) { die('Este proceso no necesitamos lanzarlo automaticamente'); } @mail(\GOTEO_FAIL_MAIL, 'Se ha lanzado el cron ' . __FUNCTION__ . ' en ' . SITE_URL, 'Se ha lanzado manualmente el cron ' . __FUNCTION__ . ' para el proyecto ' . $project . ' en ' . SITE_URL . ' a las ' . date('H:i:s') . ' Usuario ' . $_SESSION['user']->id); // a ver si existe el bloqueo $block_file = GOTEO_PATH . 'logs/cron-' . __FUNCTION__ . '.block'; if (file_exists($block_file)) { echo 'Ya existe un archivo de log ' . date('Ymd') . '_' . __FUNCTION__ . '.log<br />'; $block_content = \file_get_contents($block_file); echo 'El contenido del bloqueo es: ' . $block_content; // lo escribimos en el log $log_file = GOTEO_PATH . 'logs/cron/' . date('Ymd') . '_' . __FUNCTION__ . '.log'; \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND); \chmod($log_file, 0777); /* @mail(\GOTEO_FAIL_MAIL, 'Cron '. __FUNCTION__ .' bloqueado en ' . SITE_URL, 'Se ha encontrado con que el cron '. __FUNCTION__ .' está bloqueado el '.date('d-m-Y').' a las ' . date ('H:i:s') . ' El contenido del bloqueo es: '. $block_content); */ die; } else { $block = 'Bloqueo ' . $block_file . ' activado el ' . date('d-m-Y') . ' a las ' . date('H:i:s') . '<br />'; if (\file_put_contents($block_file, $block, FILE_APPEND)) { \chmod($block_file, 0777); echo $block; } else { echo 'No se ha podido crear el archivo de bloqueo<br />'; @mail(\GOTEO_FAIL_MAIL, 'Cron ' . __FUNCTION__ . ' no se ha podido bloquear en ' . SITE_URL, 'No se ha podido crear el archivo ' . $block_file . ' el ' . date('d-m-Y') . ' a las ' . date('H:i:s')); } } $projectData = Model\Project::getMini($project); // necesitamos la cuenta del proyecto y que sea la misma que cuando el preapproval $projectAccount = Model\Project\Account::get($project); if (empty($projectAccount->paypal)) { // iniciamos mail $mailHandler = new Mail(); $mailHandler->to = \GOTEO_MAIL; $mailHandler->toName = 'Goteo.org'; $mailHandler->subject = 'El proyecto ' . $projectData->name . ' no tiene cuenta PayPal'; $mailHandler->content = 'Hola Goteo, el proyecto ' . $projectData->name . ' no tiene cuenta PayPal y se estaba intentando realizar pagos secundarios.'; $mailHandler->html = false; $mailHandler->template = null; $mailHandler->send(); unset($mailHandler); die('El proyecto ' . $projectData->name . ' no tiene la cuenta PayPal!!'); } // tratamiento de aportes pendientes $query = Model\Project::query("\n SELECT *\n FROM invest\n WHERE invest.status = 1\n AND invest.method = 'paypal'\n AND invest.project = ?\n ", array($project)); $invests = $query->fetchAll(\PDO::FETCH_CLASS, '\\Goteo\\Model\\Invest'); echo 'Vamos a tratar ' . count($invests) . ' aportes para el proyecto ' . $projectData->name . '<br />'; foreach ($invests as $key => $invest) { $errors = array(); $userData = Model\User::getMini($invest->user); echo 'Tratando: Aporte (id: ' . $invest->id . ') de ' . $userData->name . ' [' . $userData->email . ']<br />'; if (Paypal::doPay($invest, $errors)) { echo 'Aporte (id: ' . $invest->id . ') pagado al proyecto. Ver los detalles en la <a href="/admin/accounts/details/' . $invest->id . '">gestion de transacciones</a><br />'; $log_text = Text::_("Se ha realizado el pago de %s PayPal al proyecto %s por el aporte de %s (id: %s) del dia %s"); Model\Invest::setDetail($invest->id, 'payed', 'Se ha realizado el pago secundario al proyecto. Proceso cron/doPay'); } else { echo 'Fallo al pagar al proyecto el aporte (id: ' . $invest->id . '). Ver los detalles en la <a href="/admin/accounts/details/' . $invest->id . '">gestion de transacciones</a><br />' . implode('<br />', $errors); $log_text = Text::_("Ha fallado al realizar el pago de %s PayPal al proyecto %s por el aporte de %s (id: %s) del dia %s"); Model\Invest::setDetail($invest->id, 'pay-failed', 'Fallo al realizar el pago secundario: ' . implode('<br />', $errors) . '. Proceso cron/doPay'); } // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Pago al proyecto encadenado-secundario (cron)', '/admin/accounts', \vsprintf($log_text, array(Feed::item('money', $invest->amount . ' ¥'), Feed::item('project', $projectData->name, $project), Feed::item('user', $userData->name, $userData->id), Feed::item('system', $invest->id), Feed::item('system', date('d/m/Y', strtotime($invest->invested)))))); $log->doAdmin(); unset($log); echo '<hr />'; } // desbloqueamos if (unlink($block_file)) { echo 'Cron ' . __FUNCTION__ . ' desbloqueado<br />'; } else { echo 'ALERT! Cron ' . __FUNCTION__ . ' no se ha podido desbloquear<br />'; if (file_exists($block_file)) { echo 'El archivo ' . $block_file . ' aun existe!<br />'; } else { echo 'No hay archivo de bloqueo ' . $block_file . '!<br />'; } } // recogemos el buffer para grabar el log $log_file = GOTEO_PATH . 'logs/cron/' . date('Ymd') . '_' . __FUNCTION__ . '.log'; \file_put_contents($log_file, \ob_get_contents(), FILE_APPEND); \chmod($log_file, 0777); }
public static function process($action = 'list', $id = null, $filters = array()) { $node = isset($_SESSION['admin_node']) ? $_SESSION['admin_node'] : \GOTEO_NODE; // métodos de pago $methods = Model\Invest::methods(); // estados del proyecto $status = Model\Project::status(); // estados de aporte $investStatus = Model\Invest::status(); // listado de proyectos $projects = Model\Invest::projects(false, $node); // usuarios cofinanciadores $users = Model\Invest::users(true); // campañas que tienen aportes $calls = Model\Invest::calls(); // extras $types = array('donative' => 'Solo los donativos', 'anonymous' => 'Solo los anónimos', 'manual' => 'Solo los manuales', 'campaign' => 'Solo con riego'); if ($action == 'csv') { $invest = Model\Invest::getPreapproval($id); foreach ($invest as $value) { $csv[] = array($value->id, $value->amount); } $fileName = "axes_" . date("YmdHis") . ".csv"; header("Content-Disposition: attachment; filename=\"{$filename}\""); header("Content-type: application/octet-stream"); header("Pragma: no-cache"); header("Expires: 0"); $fp = fopen('php://output', 'w'); foreach ($csv as $fields) { fputcsv($fp, $fields); } fclose($fp); exit; } if ($action == 'dopay') { $query = \Goteo\Core\Model::query("\n SELECT *\n FROM invest\n WHERE invest.project = ?\n AND (invest.status = 0\n OR (invest.method = 'tpv'\n AND invest.status = 1\n )\n OR (invest.method = 'cash'\n AND invest.status = 1\n )\n )\n AND (invest.campaign IS NULL OR invest.campaign = 0)\n ", array($id)); $invests = $query->fetchAll(\PDO::FETCH_CLASS, '\\Goteo\\Model\\Invest'); foreach ($invests as $key => $invest) { if ($invest->setPayment(date("YmdHis"))) { $invest->setStatus(1); Model\Invest::setDetail($invest->id, 'executed', 'Preapproval has been executed, has initiated the chained payment. Process cron / execute'); if ($invest->issue) { Model\Invest::unsetIssue($invest->id); Model\Invest::setDetail($invest->id, 'issue-solved', 'The incidence has been resolved upon success by the automatic process'); } } } Message::Info("処理しました"); throw new Redirection('/admin/projects/list'); exit; } // detalles del aporte if ($action == 'details') { $invest = Model\Invest::get($id); $project = Model\Project::get($invest->project); $userData = Model\User::get($invest->user); if (!empty($invest->droped)) { $droped = Model\Invest::get($invest->droped); } else { $droped = null; } if ($project->node != $node) { throw new Redirection('/admin/invests'); } return new View('view/admin/index.html.php', array('folder' => 'invests', 'file' => 'details', 'invest' => $invest, 'project' => $project, 'user' => $userData, 'status' => $status, 'investStatus' => $investStatus, 'droped' => $droped, 'calls' => $calls)); } // listado de aportes if ($filters['filtered'] == 'yes') { if (!empty($filters['calls'])) { $filters['types'] = ''; } $list = Model\Invest::getList($filters, $node, 999); } else { $list = array(); } $viewData = array('folder' => 'invests', 'file' => 'list', 'list' => $list, 'filters' => $filters, 'projects' => $projects, 'users' => $users, 'calls' => $calls, 'methods' => $methods, 'types' => $types, 'investStatus' => $investStatus); return new View('view/admin/index.html.php', $viewData); }
public static function cancelPay($invest, &$errors = array(), $fail = false) { if (\GOTEO_FREE) { $errors[] = Text::_('Bank not implemented. Contact us for development services or make it work somehow'); return false; } try { if (empty($invest->payment)) { $invest->cancel($fail); return true; } //echo \trace($datos); return false; } catch (Exception $ex) { Invest::setDetail($invest->id, 'tpv-cancel-conection-fail', 'Ha fallado la comunicacion con el tpv al anular la operacion. Proceso libary/tpv::cancelPay'); $errors[] = Text::_('Error fatal en la comunicación con el TPV, se ha reportado la incidencia. Disculpe las molestias.'); @mail(\GOTEO_FAIL_MAIL, 'Error fatal en comunicacion TPV Sermepa', 'ERROR en ' . __FUNCTION__ . '<br /><pre>' . print_r($handler, 1) . '</pre>'); return false; } }
public function paid($id = null) { if ($_GET['result'] != 'ok') { die; } $id = $_GET['sendid']; if (empty($id)) { die; } // el aporte $invest = Model\Invest::get($id); if ($invest->status != "-1") { die; } $projectData = Model\Project::getMedium($invest->project); // para evitar las duplicaciones de feed y email if (isset($_SESSION['invest_' . $invest->id . '_completed'])) { die; } $user = Model\User::get($invest->user); // Paypal solo disponible si activado if ($invest->method == 'axes') { // hay que cambiarle el status a 0 $invest->setStatus('0'); // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Aporte Axes', '/admin/invests', \vsprintf("%s ha aportado %s al proyecto %s mediante PayPal", array(Feed::item('user', $user->name, $user->id), Feed::item('money', $invest->amount . ' ¥'), Feed::item('project', $projectData->name, $projectData->id)))); $log->doAdmin('money'); // evento público $log_html = Text::html('feed-invest', Feed::item('money', $invest->amount . ' ¥'), Feed::item('project', $projectData->name, $projectData->id)); if ($invest->anonymous) { $log->populate(Text::get('regular-anonymous'), '/user/profile/anonymous', $log_html, 1); } else { $log->populate($user->name, '/user/profile/' . $user->id, $log_html, $user->avatar->id); } $log->doPublic('community'); unset($log); } // fin segun metodo // texto recompensa // @TODO quitar esta lacra de N recompensas porque ya es solo una recompensa siempre $rewards = $invest->rewards; array_walk($rewards, function (&$reward) { $reward = $reward->reward; }); $txt_rewards = implode(', ', $rewards); // recaudado y porcentaje $amount = $projectData->invested; $percent = floor($projectData->invested / $projectData->mincost * 100); // email de agradecimiento al cofinanciador // primero monto el texto de recompensas //@TODO el concepto principal sería 'renuncia' (porque todos los aportes son donativos) if ($invest->resign) { // Plantilla de donativo segun la ronda if ($projectData->round == 2) { $template = Template::get(36); // en segunda ronda } else { $template = Template::get(28); // en primera ronda } } else { // plantilla de agradecimiento segun la ronda if ($projectData->round == 2) { $template = Template::get(34); // en segunda ronda } else { $template = Template::get(10); // en primera ronda } } // Dirección en el mail (y version para regalo) $txt_address = Text::get('invest-address-address-field') . ' ' . $invest->address->address; $txt_address .= '<br> ' . Text::get('invest-address-zipcode-field') . ' ' . $invest->address->zipcode; // $txt_address .= '<br> ' . Text::get('invest-address-location-field') . ' ' . $invest->address->location; // $txt_address .= '<br> ' . Text::get('invest-address-country-field') . ' ' . $invest->address->country; $txt_destaddr = $txt_address; $txt_address = Text::get('invest-mail_info-address') . '<br>' . $txt_address; // Agradecimiento al cofinanciador // Sustituimos los datos $subject = str_replace('%PROJECTNAME%', $projectData->name, $template->title); // En el contenido: $search = array('%USERNAME%', '%PROJECTNAME%', '%PROJECTURL%', '%AMOUNT%', '%REWARDS%', '%ADDRESS%'); $replace = array($user->name, $projectData->name, SITE_URL . '/project/' . $projectData->id, $confirm->amount, $txt_rewards, $txt_address); $content = \str_replace($search, $replace, $template->text); $mailHandler = new Mail(); $mailHandler->reply = GOTEO_CONTACT_MAIL; $mailHandler->replyName = GOTEO_MAIL_NAME; $mailHandler->to = $user->email; $mailHandler->toName = $user->name; $mailHandler->subject = $subject; $mailHandler->content = $content; $mailHandler->html = true; $mailHandler->template = $template->id; if ($mailHandler->send($errors)) { Message::Info(Text::get('project-invest-thanks_mail-success')); } else { Message::Error(Text::get('project-invest-thanks_mail-fail')); Message::Error(implode('<br />', $errors)); } unset($mailHandler); // Notificación al autor $template = Template::get(29); // Sustituimos los datos $subject = str_replace('%PROJECTNAME%', $projectData->name, $template->title); // En el contenido: $search = array('%OWNERNAME%', '%USERNAME%', '%PROJECTNAME%', '%SITEURL%', '%AMOUNT%', '%MESSAGEURL%'); $replace = array($projectData->user->name, $user->name, $projectData->name, SITE_URL, $invest->amount, SITE_URL . '/user/profile/' . $user->id . '/message'); $content = \str_replace($search, $replace, $template->text); $mailHandler = new Mail(); $mailHandler->to = $projectData->user->email; $mailHandler->toName = $projectData->user->name; $mailHandler->subject = $subject; $mailHandler->content = $content; $mailHandler->html = true; $mailHandler->template = $template->id; $mailHandler->send(); unset($mailHandler); // marcar que ya se ha completado el proceso de aportar $_SESSION['invest_' . $invest->id . '_completed'] = true; // log Model\Invest::setDetail($invest->id, 'confirmed', 'El usuario regresó a /invest/confirmed'); }
public function comunication() { @mail(\GOTEO_FAIL_MAIL, 'Comunicacion online', 'Este GET<pre>' . print_r($_GET, 1) . '</pre> y este POST:<pre>' . print_r($_POST, 1) . '</pre>'); if (isset($_POST['__expected_field___'])) { $_POST['invest'] = $id = $_POST['__expected_field___']; $invest = Invest::get($id); $userData = User::getMini($invest->user); $projectData = Project::getMini($invest->project); $response = ''; foreach ($_POST as $n => $v) { $response .= "{$n}:'{$v}'; "; } $conf = array('mode' => 0600, 'timeFormat' => '%X %x'); $logger =& \Log::singleton('file', 'logs/' . date('Ymd') . '_invest.log', 'caller', $conf); $logger->log("response: {$response}"); $logger->log('##### END TPV [' . $id . '] ' . date('d/m/Y') . ' ' . $_POST['__expected_field___'] . '#####'); $logger->close(); if (!empty($_POST['__expected_field___'])) { try { $tpvRef = $_POST['__expected_field___']; $tpvAut = $_POST['__expected_field___']; $values = array(':id' => $invest->id, ':payment' => $tpvRef, ':transaction' => $tpvAut, ':charged' => date('Y-m-d')); $sql = "UPDATE invest\n SET\n status = 1,\n payment = :payment,\n charged = :charged,\n transaction = :transaction\n WHERE id = :id"; if (Invest::query($sql, $values)) { Invest::setDetail($invest->id, 'tpv-response', 'La comunicación online del tpv se a completado correctamente. Proceso controller/tpv'); } else { @mail(\GOTEO_FAIL_MAIL, 'Error db en comunicacion online', 'En la grabación de referencia, num auth. y estado. Ha fallado: ' . $sql . ' ' . print_r($values, 1) . '<hr /><pre>' . print_r($invest, 1) . '</pre>'); } // CALLSYS } catch (\PDOException $e) { @mail(\GOTEO_FAIL_MAIL, 'Error db en comunicacion online', 'En la grabación de referencia, num auth. y estado. Ha dado un PDO::Exception<br /><pre>' . print_r($invest, 1) . '</pre>'); } $_POST['result'] = 'Transaccion ok'; $log_text = "%s ha aportado %s al proyecto %s mediante TPV"; $doPublic = true; echo '$*$OKY$*$'; } else { $Cerr = (string) $_POST['Codigo_error']; $errTxt = self::$errcode[$Cerr]; Invest::setDetail($invest->id, 'tpv-response-error', 'El tpv ha comunicado el siguiente Codigo error: ' . $Cerr . ' - ' . $errTxt . '. El aporte a quedado \'En proceso\'. Proceso controller/tpv'); @mail(\GOTEO_FAIL_MAIL, 'Error en TPV', 'Codigo error: ' . $Cerr . ' ' . $errTxt . '<br /><pre>' . print_r($_POST, 1) . '</pre>'); $invest->cancel('ERR ' . $Cerr); $_POST['result'] = 'Fail'; $log_text = 'Ha habido un <span class="red">ERROR de TPV (Codigo: ' . $Cerr . ' ' . $errTxt . ')</span> en el aporte de %s de %s al proyecto %s mediante TPV'; $doPublic = false; } // Evento Feed $log = new Feed(); $log->setTarget($projectData->id); $log->populate('Aporte TPV', '/admin/invests', \vsprintf($log_text, $log_items = array(Feed::item('user', $userData->name, $userData->id), Feed::item('money', $invest->amount . ' €'), Feed::item('project', $projectData->name, $projectData->id)))); $log->doAdmin('money'); if ($doPublic) { // evento público $log_html = Text::html('feed-invest', Feed::item('money', $invest->amount . ' €'), Feed::item('project', $projectData->name, $projectData->id)); if ($invest->anonymous) { $log->populate(Text::get('regular-anonymous'), '/user/profile/anonymous', $log_html, 1); } else { $log->populate($userData->name, '/user/profile/' . $userData->id, $log_html, $userData->avatar->id); } $log->doPublic('community'); } unset($log); } else { echo 'Se esperaban recibir datos de comunicación online del TPV.'; @mail(\GOTEO_FAIL_MAIL, 'Comunicacion online sin datos', 'Este GET<pre>' . print_r($_GET, 1) . '</pre> y este POST:<pre>' . print_r($_POST, 1) . '</pre>'); // throw new Redirection('/', Error::BAD_REQUEST); } die; }