Varios cambios Co-authored-by: Juan Pablo Vial <jpvialb@incoviba.cl> Reviewed-on: #25
303 lines
12 KiB
PHP
303 lines
12 KiB
PHP
<?php
|
|
namespace Incoviba\Service\Venta\MediosPago\Toku;
|
|
|
|
use PDO;
|
|
use PDOException;
|
|
use Psr\Http\Client\ClientInterface;
|
|
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
|
use Incoviba\Common\Implement\Exception\EmptyResult;
|
|
use Incoviba\Exception\ServiceAction\Read;
|
|
use Incoviba\Model\Venta;
|
|
use Incoviba\Repository;
|
|
use Incoviba\Service;
|
|
use Incoviba\Service\Venta\MediosPago\AbstractEndPoint;
|
|
|
|
class Subscription extends AbstractEndPoint
|
|
{
|
|
public function __construct(ClientInterface $client,
|
|
protected Repository\Venta\MediosPago\Toku\Subscription $subscriptionRepsitory,
|
|
protected Service\Venta $ventaService)
|
|
{
|
|
parent::__construct($client);
|
|
}
|
|
|
|
public function getById(string $id): array
|
|
{
|
|
return $this->doGetById([$this->subscriptionRepsitory, 'fetchByVenta'], $id, "No existe toku_id para Venta {$id}");
|
|
}
|
|
public function getByExternalId(string $id): array
|
|
{
|
|
return $this->doGetById([$this->subscriptionRepsitory, 'fetchByTokuId'], $id, "No existe Subscription para toku_id {$id}");
|
|
}
|
|
|
|
public function get(string $id): array
|
|
{
|
|
$request_uri = "/subscriptions/{$id}";
|
|
return $this->sendGet($request_uri, [200], [401, 404, 422]);
|
|
}
|
|
public function add(array $data, ?string $accountKey = null): bool
|
|
{
|
|
$request_uri = '/subscriptions';
|
|
return $this->sendAdd($request_uri, $data, [200, 201], [401, 404, 409, 422], $accountKey);
|
|
}
|
|
public function edit(string $id, array $data, ?string $accountKey = null): bool
|
|
{
|
|
$request_uri = "/subscriptions/{$id}";
|
|
return $this->sendEdit($request_uri, $data, [200], [401, 404, 409, 422], $accountKey);
|
|
}
|
|
public function delete(string $id): void
|
|
{
|
|
$request_uri = "/subscriptions/{$id}";
|
|
$this->sendDelete($request_uri, [204], [404, 409]);
|
|
}
|
|
public function reset(array $skip = []): array
|
|
{
|
|
try {
|
|
$tokuIds = $this->subscriptionRepsitory->fetchAllTokuIds();
|
|
$tokuIds = array_filter($tokuIds, function (string $tokuId) use ($skip) {
|
|
return !in_array($tokuId, $skip);
|
|
});
|
|
} catch (EmptyResult $exception) {
|
|
$this->logger->warning($exception);
|
|
return [];
|
|
}
|
|
foreach ($tokuIds as $tokuId) {
|
|
try {
|
|
$this->delete($tokuId);
|
|
$this->subscriptionRepsitory->removeByTokuId($tokuId);
|
|
} catch (EmptyResponse | PDOException $exception) {
|
|
$this->logger->warning($exception, ['subscription->toku_id' => $tokuId]);
|
|
}
|
|
}
|
|
return $tokuIds;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
* @throws Read
|
|
*/
|
|
public function check(): array
|
|
{
|
|
$ventas = $this->ventaService->getAllWithCuotaPending();
|
|
$ids = array_column($ventas, 'id');
|
|
$existingSubscriptions = [];
|
|
try {
|
|
$existingSubscriptions = $this->subscriptionRepsitory->fetchByVentas($ids);
|
|
array_walk($existingSubscriptions, function(&$subscription) {
|
|
$subscription->venta = $this->ventaService->getById($subscription->venta->id);
|
|
});
|
|
} catch (EmptyResult) {}
|
|
if (count($existingSubscriptions) === 0) {
|
|
$missingVentas = $ventas;
|
|
} else {
|
|
$missingVentas = array_filter($ventas, function($venta) use ($existingSubscriptions) {
|
|
return !array_any($existingSubscriptions, fn($subscription) => $subscription->venta->id === $venta->id);
|
|
});
|
|
}
|
|
return compact('existingSubscriptions', 'missingVentas');
|
|
}
|
|
public function queue(int $venta_id): bool
|
|
{
|
|
try {
|
|
$venta = $this->ventaService->getById($venta_id);
|
|
} catch (Read $exception) {
|
|
$this->logger->warning($exception);
|
|
return false;
|
|
}
|
|
try {
|
|
$subscription = $this->subscriptionRepsitory->fetchByVenta($venta_id);
|
|
return false;
|
|
} catch (EmptyResult) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array $idsData
|
|
* @return array
|
|
* @throws EmptyResult
|
|
* @throws EmptyResponse
|
|
*/
|
|
public function update(array $idsData): array
|
|
{
|
|
$tokuIds = array_column($idsData, 'toku_id');
|
|
$oldPids = array_column($idsData, 'product_id');
|
|
|
|
$placeholders = array_map(fn($id) => "id{$id}", array_keys($oldPids));
|
|
$placeholdersString = implode(', ', array_map(fn($id) => ":{$id}", $placeholders));
|
|
$query = $this->ventaService->getRepository()->getConnection()->getQueryBuilder()
|
|
->select('venta.id, CONCAT_WS("-", unidad.descripcion, CONCAT_WS("-", propietario.rut, propietario.dv)) AS old_pid')
|
|
->from('venta')
|
|
->joined('JOIN propietario ON propietario.rut = venta.propietario')
|
|
->joined('JOIN propiedad_unidad pu ON pu.propiedad = venta.propiedad')
|
|
->joined('JOIN unidad ON pu.unidad = unidad.id')
|
|
->having("old_pid IN ({$placeholdersString})");
|
|
$values = array_combine($placeholders, $oldPids);
|
|
try {
|
|
$statement = $this->ventaService->getRepository()->getConnection()->execute($query, $values);
|
|
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $exception) {
|
|
$this->logger->error($exception->getMessage(), [
|
|
'query' => $query,
|
|
'values' => $values,
|
|
'ids' => $idsData,
|
|
'exception' => $exception]);
|
|
throw new EmptyResult($query, $exception);
|
|
}
|
|
|
|
$accountKeys = $this->getAccountKey(array_column($results, 'id'));
|
|
|
|
$newPids = [];
|
|
$keys = [];
|
|
foreach ($results as $result) {
|
|
$idx = array_search($result['old_pid'], $oldPids);
|
|
$newPids[$idx] = $result['id'];
|
|
if (array_key_exists($result['id'], $accountKeys)) {
|
|
$keys[$idx] = $accountKeys[$result['id']];
|
|
}
|
|
}
|
|
$output = [];
|
|
foreach ($tokuIds as $idx => $tokuId) {
|
|
if (!isset($newPids[$idx])) {
|
|
continue;
|
|
}
|
|
$data = [
|
|
'product_id' => $newPids[$idx],
|
|
];
|
|
try {
|
|
if (!$this->edit($tokuId, $data, array_key_exists($idx, $keys) ? $keys[$idx] : null)) {
|
|
$this->logger->error('Error while updating Toku', [
|
|
'toku_id' => $tokuId,
|
|
'old_pid' => $oldPids[$idx],
|
|
'product_id' => $newPids[$idx],
|
|
'account_key' => array_key_exists($idx, $keys) ? $keys[$idx] : null]);
|
|
$output[] = [
|
|
'toku_id' => $tokuId,
|
|
'old_pid' => $oldPids[$idx],
|
|
'product_id' => $newPids[$idx],
|
|
'account_key' => array_key_exists($idx, $keys) ? $keys[$idx] : null,
|
|
'error' => 'Error while updating Toku'
|
|
];
|
|
continue;
|
|
}
|
|
} catch (EmptyResponse $exception) {
|
|
$this->logger->error($exception->getMessage(), [
|
|
'toku_id' => $tokuId,
|
|
'old_pid' => $oldPids[$idx],
|
|
'product_id' => $newPids[$idx],
|
|
'account_key' => array_key_exists($idx, $keys) ? $keys[$idx] : null,
|
|
'exception' => $exception]);
|
|
$output[] = [
|
|
'toku_id' => $tokuId,
|
|
'old_pid' => $oldPids[$idx],
|
|
'product_id' => $newPids[$idx],
|
|
'account_key' => array_key_exists($idx, $keys) ? $keys[$idx] : null,
|
|
'error' => $exception->getMessage()
|
|
];
|
|
continue;
|
|
}
|
|
$output[] = [
|
|
'toku_id' => $tokuId,
|
|
'old_pid' => $oldPids[$idx],
|
|
'product_id' => $newPids[$idx],
|
|
'account_key' => array_key_exists($idx, $keys) ? $keys[$idx] : null
|
|
];
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
public function save(array $data): bool
|
|
{
|
|
return $this->doSave($this->subscriptionRepsitory, $data);
|
|
}
|
|
protected function mapParams(array $data): array
|
|
{
|
|
$paramsMap = [
|
|
'customer' => 'customer',
|
|
'product_id' => 'product_id',
|
|
'pac_mandate_id' => null,
|
|
'is_recurring' => null,
|
|
'due_day' => null,
|
|
'amount' => 'pieValor',
|
|
'receipt_product_code' => null,
|
|
'metadata' => 'datosVenta'
|
|
];
|
|
|
|
$params = [];
|
|
foreach ($paramsMap as $key => $ref) {
|
|
if ($ref === null) {
|
|
continue;
|
|
}
|
|
if ($ref === 'pieValor' and array_key_exists('venta', $data)) {
|
|
$params[$key] = $data['venta']?->formaPago()?->pie?->valor ?? 0;
|
|
continue;
|
|
}
|
|
if ($ref === 'datosVenta' and array_key_exists('venta', $data)) {
|
|
$params[$key] = $this->datosVenta($data['venta']);
|
|
continue;
|
|
}
|
|
if (array_key_exists($ref, $data) and $data[$ref] !== '' and $data[$ref] !== null) {
|
|
$params[$key] = $data[$ref];
|
|
}
|
|
}
|
|
|
|
return $params;
|
|
}
|
|
protected function mapSave(array $data): array
|
|
{
|
|
$responseMap = [
|
|
'product_id' => 'venta_id',
|
|
'id' => 'toku_id'
|
|
];
|
|
$mappedData = [];
|
|
foreach ($responseMap as $responseKey => $dataKey) {
|
|
if (isset($data[$responseKey])) {
|
|
$mappedData[$dataKey] = $data[$responseKey];
|
|
}
|
|
}
|
|
return $mappedData;
|
|
}
|
|
protected function datosVenta(Venta $venta): array
|
|
{
|
|
return [
|
|
'Proyecto' => $venta->proyecto()->descripcion,
|
|
'Unidades' => $venta->propiedad()->summary()
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array $ventaIds
|
|
* @return array
|
|
* @throws EmptyResult
|
|
*/
|
|
protected function getAccountKey(array $ventaIds): array
|
|
{
|
|
$placeholders = array_map(fn($id) => "id{$id}", array_keys($ventaIds));
|
|
$placeholdersString = implode(', ', array_map(fn($id) => ":{$id}", $placeholders));
|
|
$query = $this->ventaService->getRepository()->getConnection()->getQueryBuilder()
|
|
->select('account_key, venta.id AS venta_id')
|
|
->from('toku_accounts')
|
|
->joined('JOIN proyecto ON proyecto.inmobiliaria = toku_accounts.sociedad_rut')
|
|
->joined('JOIN proyecto_tipo_unidad ptu ON ptu.proyecto = proyecto.id')
|
|
->joined('JOIN unidad ON unidad.pt = ptu.id')
|
|
->joined('JOIN propiedad_unidad pu ON pu.unidad = unidad.id')
|
|
->joined('JOIN venta ON venta.propiedad = pu.propiedad')
|
|
->where("venta.id IN ({$placeholdersString}) AND toku_accounts.enabled = 1");
|
|
$values = array_combine($placeholders, $ventaIds);
|
|
try {
|
|
$statement = $this->ventaService->getRepository()->getConnection()->execute($query, $values);
|
|
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $exception) {
|
|
$this->logger->error($exception->getMessage(), [
|
|
'query' => $query,
|
|
'values' => $values,
|
|
'exception' => $exception]);
|
|
throw new EmptyResult($query, $exception);
|
|
}
|
|
$keys = array_column($results, 'account_key');
|
|
$ids = array_column($results, 'venta_id');
|
|
return array_combine($ids, $keys);
|
|
}
|
|
}
|