Updates
This commit is contained in:
@ -1,11 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Incoviba\Controller\API\Admin;
|
namespace Incoviba\Controller\API\Admin;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||||
use Incoviba\Controller\API\withJson;
|
use Incoviba\Controller\API\withJson;
|
||||||
|
use Incoviba\Exception\ServiceAction\Read;
|
||||||
|
use Incoviba\Exception\ServiceAction\Update;
|
||||||
|
use Incoviba\Exception\ServiceAction\Delete;
|
||||||
use Incoviba\Service;
|
use Incoviba\Service;
|
||||||
|
|
||||||
class Users
|
class Users
|
||||||
@ -27,4 +29,34 @@ class Users
|
|||||||
} catch (EmptyResult) {}
|
} catch (EmptyResult) {}
|
||||||
return $this->withJson($response, $output);
|
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
|
<?php
|
||||||
namespace Incoviba\Controller\API;
|
namespace Incoviba\Controller\API;
|
||||||
|
|
||||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||||
|
use Incoviba\Common\Ideal;
|
||||||
use Incoviba\Repository;
|
use Incoviba\Repository;
|
||||||
use Incoviba\Service;
|
use Incoviba\Service;
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
|
|
||||||
class Login
|
class Login extends Ideal\Controller
|
||||||
{
|
{
|
||||||
use withJson;
|
use withJson;
|
||||||
|
|
||||||
@ -27,7 +27,13 @@ class Login
|
|||||||
$loginService->login($user);
|
$loginService->login($user);
|
||||||
$output['token'] = $loginService->getToken();
|
$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);
|
return $this->withJson($response, $output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class Toku extends Controller
|
|||||||
$body = $request->getBody();
|
$body = $request->getBody();
|
||||||
$input = json_decode($body->getContents(), true);
|
$input = json_decode($body->getContents(), true);
|
||||||
try {
|
try {
|
||||||
if ($tokuService->updatePago($input['payment_intent'])) {
|
if ($tokuService->successEvent($input)) {
|
||||||
return $responseFactory->createResponse(204);
|
return $responseFactory->createResponse(204);
|
||||||
}
|
}
|
||||||
return $responseFactory->createResponse(409, 'Payment could not be updated');
|
return $responseFactory->createResponse(409, 'Payment could not be updated');
|
||||||
|
@ -27,7 +27,7 @@ class API
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$key = $this->apiService->getKey($request);
|
$key = $this->apiService->getKey($request);
|
||||||
} catch (MissingAuthorizationHeader $exception) {
|
} catch (MissingAuthorizationHeader) {
|
||||||
return $this->responseFactory->createResponse(401);
|
return $this->responseFactory->createResponse(401);
|
||||||
}
|
}
|
||||||
if ($this->validateSimpleKey($request, $key)) {
|
if ($this->validateSimpleKey($request, $key)) {
|
||||||
|
@ -38,7 +38,7 @@ class Job extends Ideal\Service
|
|||||||
public function getPending(): array
|
public function getPending(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return array_merge([$this, 'process'],$this->jobRepository->fetchPending());
|
return array_map([$this, 'process'],$this->jobRepository->fetchPending());
|
||||||
} catch (EmptyResult $exception) {
|
} catch (EmptyResult $exception) {
|
||||||
throw new Read(__CLASS__, $exception);
|
throw new Read(__CLASS__, $exception);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,10 @@ use DateTimeImmutable;
|
|||||||
use DateInterval;
|
use DateInterval;
|
||||||
use Exception;
|
use Exception;
|
||||||
use PDOException;
|
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\Common\Implement\Exception\EmptyResult;
|
||||||
use Incoviba\Repository;
|
use Incoviba\Repository;
|
||||||
use Incoviba\Model;
|
use Incoviba\Model;
|
||||||
@ -40,6 +44,11 @@ class Login
|
|||||||
} catch (PDOException|EmptyResult) {}
|
} catch (PDOException|EmptyResult) {}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Model\User
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public function getUser(): Model\User
|
public function getUser(): Model\User
|
||||||
{
|
{
|
||||||
$login = $this->repository->fetchActiveBySelector($this->selector);
|
$login = $this->repository->fetchActiveBySelector($this->selector);
|
||||||
@ -57,20 +66,90 @@ class Login
|
|||||||
return $this->cookie_separator;
|
return $this->cookie_separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return Model\User
|
||||||
|
* @throws Create
|
||||||
|
* @throws Read
|
||||||
|
*/
|
||||||
public function addUser(array $data): Model\User
|
public function addUser(array $data): Model\User
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return $this->userRepository->fetchByName($data['name']);
|
return $this->userRepository->fetchByName($data['name']);
|
||||||
} catch (EmptyResult) {
|
} catch (EmptyResult) {
|
||||||
list($passphrase, $encrypted) = $this->splitPassword($data['password']);
|
list($passphrase, $encrypted) = $this->splitPassword($data['password']);
|
||||||
|
try {
|
||||||
$password = $this->cryptoJs_aes_decrypt($encrypted, $passphrase);
|
$password = $this->cryptoJs_aes_decrypt($encrypted, $passphrase);
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
throw new Read(__CLASS__, $exception);
|
||||||
|
}
|
||||||
$password = password_hash($password, PASSWORD_DEFAULT);
|
$password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
$user = $this->userRepository->create([
|
$user = $this->userRepository->create([
|
||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'password' => $password,
|
'password' => $password,
|
||||||
'enabled' => $data['enabled'] ?? 1
|
'enabled' => $data['enabled'] ?? 1
|
||||||
]);
|
]);
|
||||||
|
try {
|
||||||
return $this->userRepository->save($user);
|
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
|
public function validateUser(Model\User $user, string $encryptedPassword): bool
|
||||||
@ -88,7 +167,8 @@ class Login
|
|||||||
try {
|
try {
|
||||||
$login = $this->repository->fetchActiveByUser($user->id);
|
$login = $this->repository->fetchActiveByUser($user->id);
|
||||||
$this->logout($login->user);
|
$this->logout($login->user);
|
||||||
} catch (PDOException|EmptyResult) {
|
} catch (PDOException | EmptyResult $exception) {
|
||||||
|
error_log($exception, 3, '/logs/exception.log');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -104,7 +184,8 @@ class Login
|
|||||||
$this->repository->save($login);
|
$this->repository->save($login);
|
||||||
$this->saveCookie($selector, $token, $login->dateTime->add(new DateInterval("PT{$this->max_login_time}H")));
|
$this->saveCookie($selector, $token, $login->dateTime->add(new DateInterval("PT{$this->max_login_time}H")));
|
||||||
return true;
|
return true;
|
||||||
} catch (PDOException|Exception) {
|
} catch (PDOException | Exception $exception) {
|
||||||
|
error_log($exception, 3, '/logs/exception.log');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ class Queue extends Ideal\Service
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$status = true;
|
$errors = [];
|
||||||
foreach ($jobs as $job) {
|
foreach ($jobs as $job) {
|
||||||
$type = 'default';
|
$type = 'default';
|
||||||
if (isset($job->configuration['type'])) {
|
if (isset($job->configuration['type'])) {
|
||||||
@ -57,13 +57,15 @@ class Queue extends Ideal\Service
|
|||||||
$worker = $this->workers[$type];
|
$worker = $this->workers[$type];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$status &= $worker->run($job);
|
if (!$worker->execute($job)) {
|
||||||
|
$errors []= $job->id;
|
||||||
|
}
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
$final = new Exception("Could not run job", 0, $exception);
|
$final = new Exception("Could not run job", 0, $exception);
|
||||||
$this->logger->warning($final);
|
$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;
|
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
|
* @param array $request
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws InvalidResult
|
* @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
|
# If $customer is not found, it will throw an exception and stop
|
||||||
$customer = $this->customer->getByExternalId($request['customer']);
|
$customer = $this->customer->getByExternalId($request['customer']);
|
||||||
@ -144,4 +168,104 @@ class Toku extends Ideal\Service
|
|||||||
|
|
||||||
return $this->invoice->update($invoice['id'], $request);
|
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') {
|
if ($data['status'] !== 'AUTHORIZED') {
|
||||||
throw new InvalidResult("Pago no autorizado", 422);
|
throw new InvalidResult("Pago no autorizado", 422);
|
||||||
}
|
}
|
||||||
|
$dateString = $data['date'];
|
||||||
try {
|
try {
|
||||||
$date = new DateTimeImmutable($data['transaction_date']);
|
$date = new DateTimeImmutable($dateString);
|
||||||
} catch (DateMalformedStringException $exception) {
|
} 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);
|
$uf = $this->ufService->get($date);
|
||||||
if ($uf === 0.0) {
|
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;
|
$valor = $data['amount'] / $uf;
|
||||||
if (abs($valor - $invoice->cuota->pago->valor()) >= 0.0001) {
|
if (abs($valor - $invoice->cuota->pago->valor()) >= 0.0001) {
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
namespace Incoviba\Service\Worker;
|
namespace Incoviba\Service\Worker;
|
||||||
|
|
||||||
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
||||||
|
use Incoviba\Service\Worker;
|
||||||
use Psr\Http\Client\ClientExceptionInterface;
|
use Psr\Http\Client\ClientExceptionInterface;
|
||||||
use Psr\Http\Client\ClientInterface;
|
use Psr\Http\Client\ClientInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Incoviba\Common\Ideal;
|
use Incoviba\Common\Ideal;
|
||||||
use Incoviba\Model;
|
use Incoviba\Model;
|
||||||
|
|
||||||
class Request extends Ideal\Service
|
class Request extends Ideal\Service implements Worker
|
||||||
{
|
{
|
||||||
public function __construct(LoggerInterface $logger, protected ClientInterface $client)
|
public function __construct(LoggerInterface $logger, protected ClientInterface $client)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user