Updates
This commit is contained in:
@ -1,11 +1,13 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\API\Admin;
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Controller\API\withJson;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Exception\ServiceAction\Update;
|
||||
use Incoviba\Exception\ServiceAction\Delete;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Users
|
||||
@ -27,4 +29,34 @@ class Users
|
||||
} catch (EmptyResult) {}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function edit(ServerRequestInterface $request, ResponseInterface $response,
|
||||
Service\Login $loginService, int $user_id): ResponseInterface
|
||||
{
|
||||
$input = $request->getParsedBody();
|
||||
$output = [
|
||||
'input' => array_filter($input, fn($key) => $key !== 'password', ARRAY_FILTER_USE_KEY),
|
||||
'success' => false,
|
||||
'user' => null
|
||||
];
|
||||
try {
|
||||
$user = $loginService->editUser($user_id, $input);
|
||||
$output['success'] = true;
|
||||
$output['user'] = $user;
|
||||
} catch (Read|Update) {}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
public function delete(ServerRequestInterface $request, ResponseInterface $response,
|
||||
Service\Login $loginService, int $user_id): ResponseInterface
|
||||
{
|
||||
$output = [
|
||||
'success' => false,
|
||||
'user' => null
|
||||
];
|
||||
try {
|
||||
$user = $loginService->deleteUser($user_id);
|
||||
$output['success'] = true;
|
||||
$output['user'] = $user;
|
||||
} catch (Read|Delete) {}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\API;
|
||||
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Login
|
||||
class Login extends Ideal\Controller
|
||||
{
|
||||
use withJson;
|
||||
|
||||
@ -27,7 +27,13 @@ class Login
|
||||
$loginService->login($user);
|
||||
$output['token'] = $loginService->getToken();
|
||||
}
|
||||
} catch (EmptyResult) {}
|
||||
} catch (EmptyResult $exception) {
|
||||
$output['error'] = [
|
||||
'code' => $exception->getCode(),
|
||||
'message' => $exception->getMessage(),
|
||||
'stackTrace' => $exception->getTraceAsString()
|
||||
];
|
||||
}
|
||||
return $this->withJson($response, $output);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class Toku extends Controller
|
||||
$body = $request->getBody();
|
||||
$input = json_decode($body->getContents(), true);
|
||||
try {
|
||||
if ($tokuService->updatePago($input['payment_intent'])) {
|
||||
if ($tokuService->successEvent($input)) {
|
||||
return $responseFactory->createResponse(204);
|
||||
}
|
||||
return $responseFactory->createResponse(409, 'Payment could not be updated');
|
||||
|
@ -27,7 +27,7 @@ class API
|
||||
}
|
||||
try {
|
||||
$key = $this->apiService->getKey($request);
|
||||
} catch (MissingAuthorizationHeader $exception) {
|
||||
} catch (MissingAuthorizationHeader) {
|
||||
return $this->responseFactory->createResponse(401);
|
||||
}
|
||||
if ($this->validateSimpleKey($request, $key)) {
|
||||
|
@ -38,7 +38,7 @@ class Job extends Ideal\Service
|
||||
public function getPending(): array
|
||||
{
|
||||
try {
|
||||
return array_merge([$this, 'process'],$this->jobRepository->fetchPending());
|
||||
return array_map([$this, 'process'],$this->jobRepository->fetchPending());
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ use DateTimeImmutable;
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Delete;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Exception\ServiceAction\Update;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
@ -40,6 +44,11 @@ class Login
|
||||
} catch (PDOException|EmptyResult) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Model\User
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getUser(): Model\User
|
||||
{
|
||||
$login = $this->repository->fetchActiveBySelector($this->selector);
|
||||
@ -57,20 +66,90 @@ class Login
|
||||
return $this->cookie_separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\User
|
||||
* @throws Create
|
||||
* @throws Read
|
||||
*/
|
||||
public function addUser(array $data): Model\User
|
||||
{
|
||||
try {
|
||||
return $this->userRepository->fetchByName($data['name']);
|
||||
} catch (EmptyResult) {
|
||||
list($passphrase, $encrypted) = $this->splitPassword($data['password']);
|
||||
$password = $this->cryptoJs_aes_decrypt($encrypted, $passphrase);
|
||||
try {
|
||||
$password = $this->cryptoJs_aes_decrypt($encrypted, $passphrase);
|
||||
} catch (Exception $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
$password = password_hash($password, PASSWORD_DEFAULT);
|
||||
$user = $this->userRepository->create([
|
||||
'name' => $data['name'],
|
||||
'password' => $password,
|
||||
'enabled' => $data['enabled'] ?? 1
|
||||
]);
|
||||
return $this->userRepository->save($user);
|
||||
try {
|
||||
return $this->userRepository->save($user);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @param array $data
|
||||
* @return Model\User
|
||||
* @throws Read
|
||||
* @throws Update
|
||||
*/
|
||||
public function editUser(int $user_id, array $data): Model\User
|
||||
{
|
||||
try {
|
||||
$user = $this->userRepository->fetchById($user_id);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
if (!isset($data['force']) and !$user->validate($data['old_password'])) {
|
||||
throw new Read(__CLASS__);
|
||||
}
|
||||
list($passphrase, $encrypted) = $this->splitPassword($data['password']);
|
||||
try {
|
||||
$password = $this->cryptoJs_aes_decrypt($encrypted, $passphrase);
|
||||
} catch (Exception $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
$password = password_hash($password, PASSWORD_DEFAULT);
|
||||
$userData = [
|
||||
'password' => $password
|
||||
];
|
||||
try {
|
||||
$user = $this->userRepository->edit($user, $userData);
|
||||
} catch (PDOException | EmptyResult $exception) {
|
||||
throw new Update(__CLASS__, $exception);
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @return Model\User
|
||||
* @throws Delete
|
||||
* @throws Read
|
||||
*/
|
||||
public function deleteUser(int $user_id): Model\User
|
||||
{
|
||||
try {
|
||||
$user = $this->userRepository->fetchById($user_id);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$this->userRepository->remove($user);
|
||||
return $user;
|
||||
} catch (PDOException | EmptyResult $exception) {
|
||||
throw new Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
public function validateUser(Model\User $user, string $encryptedPassword): bool
|
||||
@ -88,7 +167,8 @@ class Login
|
||||
try {
|
||||
$login = $this->repository->fetchActiveByUser($user->id);
|
||||
$this->logout($login->user);
|
||||
} catch (PDOException|EmptyResult) {
|
||||
} catch (PDOException | EmptyResult $exception) {
|
||||
error_log($exception, 3, '/logs/exception.log');
|
||||
}
|
||||
|
||||
try {
|
||||
@ -104,7 +184,8 @@ class Login
|
||||
$this->repository->save($login);
|
||||
$this->saveCookie($selector, $token, $login->dateTime->add(new DateInterval("PT{$this->max_login_time}H")));
|
||||
return true;
|
||||
} catch (PDOException|Exception) {
|
||||
} catch (PDOException | Exception $exception) {
|
||||
error_log($exception, 3, '/logs/exception.log');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class Queue extends Ideal\Service
|
||||
return false;
|
||||
}
|
||||
|
||||
$status = true;
|
||||
$errors = [];
|
||||
foreach ($jobs as $job) {
|
||||
$type = 'default';
|
||||
if (isset($job->configuration['type'])) {
|
||||
@ -57,13 +57,15 @@ class Queue extends Ideal\Service
|
||||
$worker = $this->workers[$type];
|
||||
|
||||
try {
|
||||
$status &= $worker->run($job);
|
||||
if (!$worker->execute($job)) {
|
||||
$errors []= $job->id;
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
$final = new Exception("Could not run job", 0, $exception);
|
||||
$this->logger->warning($final);
|
||||
$status &= false;
|
||||
$errors []= $job->id;
|
||||
}
|
||||
}
|
||||
return $status;
|
||||
return count($errors) === 0;
|
||||
}
|
||||
}
|
||||
|
@ -131,12 +131,36 @@ class Toku extends Ideal\Service
|
||||
return $invoices;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $input
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function successEvent(array $input): bool
|
||||
{
|
||||
$validEvents = ['payment_intent.succeeded', 'payment.succeeded', 'transaction.success',
|
||||
'transaction.bulk_success', 'payment_intent.succeeded_batch'];
|
||||
if (!in_array($input['event_type'], $validEvents)) {
|
||||
throw new InvalidResult("{$input['event_type']} is not a valid event", 422);
|
||||
}
|
||||
switch ($input['event_type']) {
|
||||
case 'payment_intent.succeeded_batch':
|
||||
case 'transaction.bulk_success':
|
||||
return $this->successBulk($input);
|
||||
case 'transaction.success':
|
||||
return $this->successTransaction($input);
|
||||
default:
|
||||
$paymentData = $this->mapEventData($input);
|
||||
return $this->updatePago($paymentData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $request
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function updatePago(array $request): bool
|
||||
protected function updatePago(array $request): bool
|
||||
{
|
||||
# If $customer is not found, it will throw an exception and stop
|
||||
$customer = $this->customer->getByExternalId($request['customer']);
|
||||
@ -144,4 +168,104 @@ class Toku extends Ideal\Service
|
||||
|
||||
return $this->invoice->update($invoice['id'], $request);
|
||||
}
|
||||
protected function successTransaction(array $input): bool
|
||||
{
|
||||
$intents = $this->mapMultiplePaymentIntentsData($input);
|
||||
$errors = [];
|
||||
foreach ($intents as $intent) {
|
||||
if (!$this->updatePago($intent)) {
|
||||
$errors []= $intent;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('wallet_movements', $input)) {
|
||||
foreach ($input['wallet_movements'] as $walletMovement) {
|
||||
if (array_key_exists('type', $walletMovement) and $walletMovement['type'] === 'SURPLUS') {
|
||||
$this->logger->alert('Revisar el envío de cuotas de la Venta ' . $walletMovement['product_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return count($errors) === 0;
|
||||
}
|
||||
/**
|
||||
* @param array $input
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
protected function successBulk(array $input): bool
|
||||
{
|
||||
return match($input['event_type']) {
|
||||
'payment_intent.succeeded_batch' => $this->successBulkPaymentIntent($input),
|
||||
'transaction.bulk_success' => $this->successBulkTransaction($input),
|
||||
default => false
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param array $input
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
protected function successBulkTransaction(array $input): bool
|
||||
{
|
||||
$errors = [];
|
||||
foreach($input['events'] as $event) {
|
||||
$event['event_type'] = 'transaction.success';
|
||||
if (!$this->successEvent($event)) {
|
||||
$errors []= $event;
|
||||
}
|
||||
}
|
||||
return count($errors) === 0;
|
||||
}
|
||||
/**
|
||||
* @param array $input
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
protected function successBulkPaymentIntent(array $input): bool
|
||||
{
|
||||
$errors = [];
|
||||
foreach($input['payment_intent'] as $intent) {
|
||||
$intent['event_type'] = 'payment_intent.succeeded';
|
||||
$intent['payment_intent'] = $input['payment_intents'];
|
||||
unset($intent['payment_intents']);
|
||||
if (!$this->successEvent($intent)) {
|
||||
$errors []= $intent;
|
||||
}
|
||||
}
|
||||
return count($errors) === 0;
|
||||
}
|
||||
protected function mapEventData(array $input): array
|
||||
{
|
||||
return match ($input['event_type']) {
|
||||
'payment_intent.succeeded' => $this->mapPaymentIntentData($input),
|
||||
'payment.succeeded' => $this->mapPaymentEventData($input),
|
||||
default => [],
|
||||
};
|
||||
}
|
||||
protected function mapMultiplePaymentIntentsData(array $input): array
|
||||
{
|
||||
$output = [];
|
||||
foreach ($input['payment_intents'] as $intent) {
|
||||
$intent['transaction_date'] = $input['transaction']['transaction_date'];
|
||||
$intent['customer'] = $input['customer']['id'];
|
||||
$intent['invoice'] = $intent['id_invoice'];
|
||||
$intent['subscription'] = $intent['id_subscription'];
|
||||
$intent['cuota_id'] = $intent['invoice_external_id'];
|
||||
$o = $this->mapPaymentIntentData($intent);
|
||||
$output []= $o;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
protected function mapPaymentEventData(array $input): array
|
||||
{
|
||||
$data = $input['payment'];
|
||||
$data['status'] = 'AUTHORIZED';
|
||||
$data['date'] = $data['payment_date'];
|
||||
return $data;
|
||||
}
|
||||
protected function mapPaymentIntentData(array $input): array
|
||||
{
|
||||
$data = $input['payment_intent'];
|
||||
$data['date'] = $data['transaction_date'];
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@ -66,14 +66,15 @@ class Invoice extends AbstractEndPoint
|
||||
if ($data['status'] !== 'AUTHORIZED') {
|
||||
throw new InvalidResult("Pago no autorizado", 422);
|
||||
}
|
||||
$dateString = $data['date'];
|
||||
try {
|
||||
$date = new DateTimeImmutable($data['transaction_date']);
|
||||
$date = new DateTimeImmutable($dateString);
|
||||
} catch (DateMalformedStringException $exception) {
|
||||
throw new InvalidResult("Fecha no válida: {$data['transaction_date']}", 422, $exception);
|
||||
throw new InvalidResult("Fecha no válida: {$dateString}", 422, $exception);
|
||||
}
|
||||
$uf = $this->ufService->get($date);
|
||||
if ($uf === 0.0) {
|
||||
throw new InvalidResult("No hay UF para la fecha: {$data['transaction_date']}", 422);
|
||||
throw new InvalidResult("No hay UF para la fecha: {$dateString}", 422);
|
||||
}
|
||||
$valor = $data['amount'] / $uf;
|
||||
if (abs($valor - $invoice->cuota->pago->valor()) >= 0.0001) {
|
||||
|
@ -2,13 +2,14 @@
|
||||
namespace Incoviba\Service\Worker;
|
||||
|
||||
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
||||
use Incoviba\Service\Worker;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Request extends Ideal\Service
|
||||
class Request extends Ideal\Service implements Worker
|
||||
{
|
||||
public function __construct(LoggerInterface $logger, protected ClientInterface $client)
|
||||
{
|
||||
|
Reference in New Issue
Block a user