feature/cierres (#25)
Varios cambios Co-authored-by: Juan Pablo Vial <jpvialb@incoviba.cl> Reviewed-on: #25
This commit is contained in:
@ -1,12 +1,15 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use DateMalformedStringException;
|
||||
use Exception;
|
||||
use DateTimeImmutable;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use PDOException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Service;
|
||||
@ -41,26 +44,44 @@ class Credito extends Ideal\Service
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @param array $data
|
||||
* @return Model\Venta\Credito
|
||||
* @throws Create
|
||||
*/
|
||||
public function add(array $data): Model\Venta\Credito
|
||||
{
|
||||
$fecha = new DateTimeImmutable($data['fecha']);
|
||||
try {
|
||||
$fecha = new DateTimeImmutable($data['fecha']);
|
||||
} catch (DateMalformedStringException) {
|
||||
$fecha = new DateTimeImmutable();
|
||||
}
|
||||
$uf = $this->valorService->clean($data['uf']) ?? $this->moneyService->getUF($fecha);
|
||||
$tipoPago = $this->tipoPagoRepository->fetchByDescripcion('carta de resguardo');
|
||||
try {
|
||||
$tipoPago = $this->tipoPagoRepository->fetchByDescripcion('carta de resguardo');
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
$valor = $this->valorService->clean($data['valor']);
|
||||
$pago = $this->pagoService->add([
|
||||
'fecha' => $fecha->format('Y-m-d'),
|
||||
'valor' => $valor * $uf,
|
||||
'valor' => round($valor * $uf),
|
||||
'uf' => $uf,
|
||||
'tipo' => $tipoPago->id
|
||||
]);
|
||||
$credito = $this->creditoRepository->create([
|
||||
'valor' => $valor,
|
||||
'fecha' => $fecha->format('Y-m-d'),
|
||||
'pago' => $pago->id
|
||||
]);
|
||||
return $this->creditoRepository->save($credito);
|
||||
try {
|
||||
$credito = $this->creditoRepository->create([
|
||||
'valor' => $valor,
|
||||
'fecha' => $fecha->format('Y-m-d'),
|
||||
'pago' => $pago->id
|
||||
]);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
return $this->creditoRepository->save($credito);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,12 +1,15 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use PDOException;
|
||||
use DateTimeImmutable;
|
||||
use DateInterval;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use IntlDateFormatter;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
|
||||
@ -21,6 +24,20 @@ class Cuota extends Ideal\Service
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $cuota_id
|
||||
* @return Model\Venta\Cuota
|
||||
* @throws Read
|
||||
*/
|
||||
public function getById(int $cuota_id): Model\Venta\Cuota
|
||||
{
|
||||
try {
|
||||
return $this->process($this->cuotaRepository->fetchById($cuota_id));
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function pendientes(): array
|
||||
{
|
||||
$cuotas = $this->cuotaRepository->fetchPendientes();
|
||||
@ -92,9 +109,18 @@ class Cuota extends Ideal\Service
|
||||
return $this->cuotaRepository->fetchVigenteByPie($pie_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Cuota
|
||||
* @throws Create
|
||||
*/
|
||||
public function add(array $data): Model\Venta\Cuota
|
||||
{
|
||||
$tipoPago = $this->tipoPagoRepository->fetchByDescripcion('cheque');
|
||||
try {
|
||||
$tipoPago = $this->tipoPagoRepository->fetchByDescripcion('cheque');
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
$fields = array_flip([
|
||||
'fecha',
|
||||
'banco',
|
||||
@ -112,8 +138,16 @@ class Cuota extends Ideal\Service
|
||||
$mapped_data = $filtered_data;
|
||||
$mapped_data['valor_$'] = $mapped_data['valor'];
|
||||
unset($mapped_data['valor']);
|
||||
$cuota = $this->cuotaRepository->create($mapped_data);
|
||||
$this->cuotaRepository->save($cuota);
|
||||
try {
|
||||
$cuota = $this->cuotaRepository->create($mapped_data);
|
||||
return $this->cuotaRepository->save($cuota);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
protected function process(Model\Venta\Cuota $cuota): Model\Venta\Cuota
|
||||
{
|
||||
return $cuota;
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use Error;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service\Valor;
|
||||
@ -53,6 +55,10 @@ class FormaPago extends Ideal\Service
|
||||
return $formaPago;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\FormaPago
|
||||
*/
|
||||
public function add(array $data): Model\Venta\FormaPago
|
||||
{
|
||||
$fields = [
|
||||
@ -68,6 +74,9 @@ class FormaPago extends Ideal\Service
|
||||
$method = 'add' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
|
||||
$obj = $this->{$method}($data);
|
||||
$forma_pago->{$name} = $obj;
|
||||
} catch (Create $exception) {
|
||||
$this->logger->warning($exception);
|
||||
continue;
|
||||
} catch (Error $error) {
|
||||
$this->logger->critical($error);
|
||||
}
|
||||
@ -76,14 +85,19 @@ class FormaPago extends Ideal\Service
|
||||
return $forma_pago;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Pie
|
||||
* @throws Create
|
||||
*/
|
||||
protected function addPie(array $data): Model\Venta\Pie
|
||||
{
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'fecha_venta',
|
||||
'pie',
|
||||
'cuotas',
|
||||
'uf'
|
||||
], 0);
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
$mapped_data = array_combine([
|
||||
'fecha',
|
||||
@ -94,14 +108,20 @@ class FormaPago extends Ideal\Service
|
||||
$mapped_data['valor'] = $this->valorService->clean($mapped_data['valor']);
|
||||
return $this->pieService->add($mapped_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Subsidio
|
||||
* @throws Create
|
||||
*/
|
||||
protected function addSubsidio(array $data): Model\Venta\Subsidio
|
||||
{
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'fecha_venta',
|
||||
'ahorro',
|
||||
'subsidio',
|
||||
'uf'
|
||||
], 0);
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
$mapped_data = array_combine([
|
||||
'fecha',
|
||||
@ -113,13 +133,19 @@ class FormaPago extends Ideal\Service
|
||||
$mapped_data['subsidio'] = $this->valorService->clean($mapped_data['subsidio']);
|
||||
return $this->subsidioService->add($mapped_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Credito
|
||||
* @throws Create
|
||||
*/
|
||||
protected function addCredito(array $data): Model\Venta\Credito
|
||||
{
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'fecha_venta',
|
||||
'credito',
|
||||
'uf'
|
||||
], 0);
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
$mapped_data = array_combine([
|
||||
'fecha',
|
||||
@ -129,12 +155,18 @@ class FormaPago extends Ideal\Service
|
||||
$mapped_data['valor'] = $this->valorService->clean($mapped_data['valor']);
|
||||
return $this->creditoService->add($mapped_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\BonoPie
|
||||
* @throws Create
|
||||
*/
|
||||
protected function addBonoPie(array $data): Model\Venta\BonoPie
|
||||
{
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'fecha_venta',
|
||||
'bono_pie'
|
||||
], 0);
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
$mapped_data = array_combine([
|
||||
'fecha',
|
||||
|
214
app/src/Service/Venta/MediosPago/AbstractEndPoint.php
Normal file
214
app/src/Service/Venta/MediosPago/AbstractEndPoint.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta\MediosPago;
|
||||
|
||||
use PDOException;
|
||||
use Psr\Http\Client\ClientExceptionInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Incoviba\Common\Define\Repository;
|
||||
use Incoviba\Common\Ideal\LoggerEnabled;
|
||||
use Incoviba\Common\Implement\Exception\{EmptyResponse, EmptyResult, HttpException};
|
||||
use Incoviba\Exception\InvalidResult;
|
||||
|
||||
abstract class AbstractEndPoint extends LoggerEnabled implements EndPoint
|
||||
{
|
||||
public function __construct(protected ClientInterface $client) {}
|
||||
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
* @param string $request_uri
|
||||
* @param array $validStatus
|
||||
* @param array $invalidStatus
|
||||
* @return void
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
protected function validateResponse(ResponseInterface $response, string $request_uri, array $validStatus, array $invalidStatus): void
|
||||
{
|
||||
$status = $response->getStatusCode();
|
||||
$reason = $response->getReasonPhrase();
|
||||
|
||||
if (in_array($status, $invalidStatus)) {
|
||||
$contents = $response->getBody()->getContents();
|
||||
$this->logger->warning('Invalid Status', [
|
||||
'uri' => $request_uri,
|
||||
'code' => $status,
|
||||
'reason' => $reason,
|
||||
'contents' => $contents
|
||||
]);
|
||||
$exception = new HttpException("{$reason}\n{$contents}", $status);
|
||||
throw new EmptyResponse($request_uri, $exception);
|
||||
}
|
||||
if (!in_array($status, $validStatus)) {
|
||||
$contents = $response->getBody()->getContents();
|
||||
$this->logger->warning('Not Valid Status', [
|
||||
'uri' => $request_uri,
|
||||
'code' => $status,
|
||||
'reason' => $reason,
|
||||
'contents' => $contents
|
||||
]);
|
||||
$exception = new HttpException("{$reason}\n{$contents}", $status);
|
||||
throw new EmptyResponse($request_uri, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $request_uri
|
||||
* @param array $validStatus
|
||||
* @param array $invalidStatus
|
||||
* @return array
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
protected function sendGet(string $request_uri, array $validStatus, array $invalidStatus): array
|
||||
{
|
||||
try {
|
||||
$response = $this->client->get($request_uri);
|
||||
} catch (ClientExceptionInterface $exception) {
|
||||
throw new EmptyResponse($request_uri, $exception);
|
||||
}
|
||||
|
||||
$this->validateResponse($response, $request_uri, $validStatus, $invalidStatus);
|
||||
|
||||
return json_decode($response->getBody()->getContents(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $request_uri
|
||||
* @param array $data
|
||||
* @param array $validStatus
|
||||
* @param array $invalidStatus
|
||||
* @param string|null $accountKey
|
||||
* @return bool
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
protected function sendAdd(string $request_uri, array $data, array $validStatus, array $invalidStatus, ?string $accountKey = null): bool
|
||||
{
|
||||
$params = $this->mapParams($data);
|
||||
$this->logger->info('Send Add', ['uri' => $request_uri, 'params' => $params]);
|
||||
try {
|
||||
$options = [
|
||||
'json' => $params
|
||||
];
|
||||
if ($accountKey !== null) {
|
||||
$options['headers'] = [
|
||||
'X-Account-Key' => $accountKey
|
||||
];
|
||||
}
|
||||
$response = $this->client->post($request_uri, $options);
|
||||
} catch (ClientExceptionInterface $exception) {
|
||||
throw new EmptyResponse($request_uri, $exception);
|
||||
}
|
||||
$this->validateResponse($response, $request_uri, $validStatus, $invalidStatus);
|
||||
|
||||
$contents = $response->getBody()->getContents();
|
||||
if (trim($contents) === '') {
|
||||
$this->logger->warning("Empty contents", [
|
||||
'uri' => $request_uri,
|
||||
'data' => $data,
|
||||
'code' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
'contents' => $contents
|
||||
]);
|
||||
throw new EmptyResponse($request_uri);
|
||||
}
|
||||
$json = json_decode($contents, true);
|
||||
$this->logger->info('Add Response', $json);
|
||||
return $this->save($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $request_uri
|
||||
* @param array $data
|
||||
* @param array $validStatus
|
||||
* @param array $invalidStatus
|
||||
* @param string|null $accountKey
|
||||
* @return bool
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
protected function sendEdit(string $request_uri, array $data, array $validStatus, array $invalidStatus, ?string $accountKey = null): bool
|
||||
{
|
||||
$params = $this->mapParams($data);
|
||||
try {
|
||||
$options = [
|
||||
'json' => $params
|
||||
];
|
||||
if ($accountKey !== null) {
|
||||
$options['headers'] = [
|
||||
'X-Account-Key' => $accountKey
|
||||
];
|
||||
}
|
||||
$response = $this->client->put($request_uri, $options);
|
||||
} catch (ClientExceptionInterface $exception) {
|
||||
throw new EmptyResponse($request_uri, $exception);
|
||||
}
|
||||
|
||||
$this->validateResponse($response, $request_uri, $validStatus, $invalidStatus);
|
||||
|
||||
$contents = $response->getBody()->getContents();
|
||||
$json = json_decode($contents, true);
|
||||
return $this->save($json);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $request_uri
|
||||
* @param array $validStatus
|
||||
* @param array $invalidStatus
|
||||
* @param array|null $data
|
||||
* @return void
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
protected function sendDelete(string $request_uri, array $validStatus, array $invalidStatus, ?array $data = null): void
|
||||
{
|
||||
$this->logger->info('Send Delete', ['uri' => $request_uri]);
|
||||
try {
|
||||
$options = [];
|
||||
if ($data !== null) {
|
||||
$options = ['json' => $data];
|
||||
}
|
||||
$response = $this->client->delete($request_uri, $options);
|
||||
} catch (ClientExceptionInterface $exception) {
|
||||
throw new EmptyResponse($request_uri, $exception);
|
||||
}
|
||||
|
||||
$this->validateResponse($response, $request_uri, $validStatus, $invalidStatus);
|
||||
$this->logger->info('Delete Response', ['request_uri' => $request_uri]);
|
||||
}
|
||||
protected function doSave(Repository $repository, array $data): bool
|
||||
{
|
||||
try {
|
||||
$repository->fetchByTokuId($data['id']);
|
||||
return true;
|
||||
} catch (EmptyResult) {
|
||||
$mappedData = $this->mapSave($data);
|
||||
$filteredData = $repository->filterData($mappedData);
|
||||
$model = $repository->create($filteredData);
|
||||
try {
|
||||
$repository->save($model);
|
||||
return true;
|
||||
} catch (PDOException $exception) {
|
||||
$this->logger->warning($exception);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
* @param string $id
|
||||
* @param string $message
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
protected function doGetById(callable $callable, string $id, string $message): array
|
||||
{
|
||||
try {
|
||||
$model = $callable($id);
|
||||
return json_decode(json_encode($model), true);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new InvalidResult($message, 404, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function save(array $data): bool;
|
||||
abstract protected function mapParams(array $data): array;
|
||||
abstract protected function mapSave(array $data): array;
|
||||
}
|
59
app/src/Service/Venta/MediosPago/EndPoint.php
Normal file
59
app/src/Service/Venta/MediosPago/EndPoint.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta\MediosPago;
|
||||
|
||||
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
||||
use Incoviba\Exception\InvalidResult;
|
||||
|
||||
interface EndPoint
|
||||
{
|
||||
/**
|
||||
* @param string $id
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function getById(string $id): array;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function getByExternalId(string $id): array;
|
||||
/**
|
||||
* @param string $id
|
||||
* @return array
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
public function get(string $id): array;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param string|null $accountKey
|
||||
* @return bool
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
public function add(array $data, ?string $accountKey = null): bool;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param array $data
|
||||
* @param string|null $accountKey
|
||||
* @return bool
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
public function edit(string $id, array $data, ?string $accountKey = null): bool;
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return void
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
public function delete(string $id): void;
|
||||
|
||||
/**
|
||||
* @param array $skip
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function reset(array $skip = []): array;
|
||||
}
|
526
app/src/Service/Venta/MediosPago/Toku.php
Normal file
526
app/src/Service/Venta/MediosPago/Toku.php
Normal file
@ -0,0 +1,526 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta\MediosPago;
|
||||
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use InvalidArgumentException;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Incoviba\Common\Define\Connection;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
||||
use Incoviba\Exception\InvalidResult;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Model\Persona;
|
||||
use Incoviba\Model\Venta\Propietario;
|
||||
use Incoviba\Service\HMAC;
|
||||
use Incoviba\Service\Venta\MediosPago\Toku\{Customer,Subscription,Invoice};
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
class Toku extends Ideal\Service
|
||||
{
|
||||
const string CUSTOMER = 'customer';
|
||||
const string SUBSCRIPTION = 'subscription';
|
||||
const string INVOICE = 'invoice';
|
||||
|
||||
protected Customer $customer;
|
||||
protected Subscription $subscription;
|
||||
protected Invoice $invoice;
|
||||
|
||||
public function __construct(LoggerInterface $logger, protected Connection $connection, protected HMAC $hmac)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function register(string $type, EndPoint $endPoint): self
|
||||
{
|
||||
if (!in_array(strtolower($type), ['customer', 'subscription', 'invoice'])) {
|
||||
throw new InvalidArgumentException("{$type} is not a valid type of EndPoint for " . __CLASS__);
|
||||
}
|
||||
$this->{strtolower($type)} = $endPoint;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Persona|Propietario $persona
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function sendPersona(Model\Persona|Model\Venta\Propietario $persona): array
|
||||
{
|
||||
$rut = implode('', [$persona->rut, strtoupper($persona->dv)]);
|
||||
try {
|
||||
return $this->customer->getById($rut);
|
||||
} catch (InvalidResult $exception) {
|
||||
$datos = $persona->datos;
|
||||
$customerData = [
|
||||
'rut' => $rut,
|
||||
'nombreCompleto' => $persona->nombreCompleto(),
|
||||
'email' => $datos?->email ?? '',
|
||||
'telefono' => $datos?->telefono ?? ''
|
||||
];
|
||||
try {
|
||||
if (!$this->customer->add($customerData)) {
|
||||
throw new InvalidResult("Could not save Customer for Persona {$rut}", 409, $exception);
|
||||
}
|
||||
} catch (EmptyResponse $exception) {
|
||||
throw new InvalidResult("Could not save Customer for Persona {$rut}", 409, $exception);
|
||||
}
|
||||
return $this->customer->getById($rut);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param Model\Venta $venta
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function sendVenta(Model\Venta $venta): array
|
||||
{
|
||||
$customer = $this->sendPersona($venta->propietario());
|
||||
try {
|
||||
return $this->subscription->getById($venta->id);
|
||||
} catch (InvalidResult $exception) {
|
||||
$inmobiliaria = $venta->proyecto()->inmobiliaria();
|
||||
$accountKey = null;
|
||||
try {
|
||||
$accountKey = $this->getAccountKey($inmobiliaria->rut);
|
||||
} catch (EmptyResult) {}
|
||||
$subscriptionData = [
|
||||
'customer' => $customer['toku_id'],
|
||||
'product_id' => $venta->id,
|
||||
'venta' => $venta
|
||||
];
|
||||
try {
|
||||
if (!$this->subscription->add($subscriptionData, $accountKey)) {
|
||||
throw new InvalidResult("Could not save Subscription for Venta {$venta->id}", 409, $exception);
|
||||
}
|
||||
} catch (EmptyResponse $exception) {
|
||||
throw new InvalidResult("Could not save Subscription for Venta {$venta->id}", 409, $exception);
|
||||
}
|
||||
return $this->subscription->getById($venta->id);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param Model\Venta $venta
|
||||
* @param array $cuotas_ids
|
||||
* @return array
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function sendCuotas(Model\Venta $venta, array $cuotas_ids = []): array
|
||||
{
|
||||
$customer = $this->sendPersona($venta->propietario());
|
||||
$subscription = $this->sendVenta($venta);
|
||||
|
||||
$customerInvoices = [];
|
||||
try {
|
||||
$customerInvoices = $this->invoice->getByCustomer($customer['toku_id']);
|
||||
$customerInvoices = array_filter($customerInvoices, function($invoiceRow) use ($subscription) {
|
||||
return $invoiceRow['subscription'] === $subscription['toku_id'];
|
||||
});
|
||||
} catch (EmptyResponse) {}
|
||||
|
||||
$inmobiliaria = $venta->proyecto()->inmobiliaria();
|
||||
$accountKey = null;
|
||||
try {
|
||||
$accountKey = $this->getAccountKey($inmobiliaria->rut);
|
||||
} catch (EmptyResult) {}
|
||||
|
||||
$invoices = [];
|
||||
$errors = [];
|
||||
foreach ($venta->formaPago()->pie->cuotas() as $cuota) {
|
||||
if (count($cuotas_ids) > 0 and !in_array($cuota->id, $cuotas_ids)) {
|
||||
continue;
|
||||
}
|
||||
if (count($customerInvoices) and in_array($cuota->id, array_column($customerInvoices, 'invoice_external_id'))) {
|
||||
$invoice = array_find($customerInvoices, function($invoiceRow) use ($cuota) {
|
||||
return $invoiceRow['invoice_external_id'] === $cuota->id;
|
||||
});
|
||||
if ($invoice !== null) {
|
||||
$invoices []= $invoice;
|
||||
$this->invoice->save($invoice);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$invoices []= $this->invoice->getById($cuota->id);
|
||||
} catch (InvalidResult $exception) {
|
||||
try {
|
||||
$invoiceData = [
|
||||
'customer' => $customer['toku_id'],
|
||||
'product_id' => $venta->id,
|
||||
'subscription' => $subscription['toku_id'],
|
||||
'cuota' => $cuota,
|
||||
'venta' => $venta
|
||||
];
|
||||
if (!$this->invoice->add($invoiceData, $accountKey)) {
|
||||
throw new EmptyResponse("Could not add Invoice for Cuota {$cuota->id}", $exception);
|
||||
}
|
||||
$invoices []= $this->invoice->getById($cuota->id);
|
||||
} catch (EmptyResponse $exception) {
|
||||
$this->logger->warning($exception);
|
||||
$errors []= $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($errors) > 0) {
|
||||
$this->logger->warning("Revisar el envío de cuotas de la Venta {$venta->id}");
|
||||
}
|
||||
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)) {
|
||||
$this->logger->warning("{$input['event_type']} is not a valid event");
|
||||
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);
|
||||
}
|
||||
}
|
||||
public function check(bool $update = false): array
|
||||
{
|
||||
try {
|
||||
list('existingSubscriptions' => $existingSubscriptions, 'missingVentas' => $missingVentas) = $this->subscription->check();
|
||||
} catch (Read) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$queues = [];
|
||||
if (count($missingVentas) > 0) {
|
||||
foreach ($missingVentas as $venta) {
|
||||
$cuotas = $venta->formaPago()->pie->cuotas();
|
||||
if (count($cuotas) === 0) {
|
||||
continue;
|
||||
}
|
||||
$queueData = [
|
||||
'type' => 'request',
|
||||
'url' => "/api/external/toku/cuotas/{$venta->id}",
|
||||
'method' => 'post',
|
||||
'body' => ['cuotas' => array_map(function(Model\Venta\Cuota $cuota) {return $cuota->id;}, $cuotas)]
|
||||
];
|
||||
$queues []= $queueData;
|
||||
}
|
||||
}
|
||||
if ($update and count($existingSubscriptions) > 0) {
|
||||
foreach ($existingSubscriptions as $subscription) {
|
||||
$cuotas = $subscription->venta->formaPago()->pie->cuotas();
|
||||
if (count($cuotas) === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$propietario = $subscription->venta->propietario();
|
||||
try {
|
||||
$customer = $this->customer->getById($propietario->rut());
|
||||
} catch (InvalidResult) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$editData = [
|
||||
'rut' => $customer['rut'],
|
||||
'nombreCompleto' => $propietario->nombreCompleto(),
|
||||
'email' => $propietario->datos?->email ?? '',
|
||||
'telefono' => $propietario->datos?->telefono ?? ''
|
||||
];
|
||||
$this->customer->edit($customer['toku_id'], $editData);
|
||||
} catch (EmptyResponse $exception) {
|
||||
$this->logger->warning($exception);
|
||||
}
|
||||
foreach ($cuotas as $cuota) {
|
||||
try {
|
||||
$invoice = $this->invoice->getById($cuota->id);
|
||||
$editData = [
|
||||
'customer' => $customer['toku_id'],
|
||||
'product_id' => $subscription->venta->id,
|
||||
'subscription' => $subscription->toku_id,
|
||||
'cuota' => $cuota,
|
||||
'venta' => $subscription->venta
|
||||
];
|
||||
try {
|
||||
$this->invoice->edit($invoice['toku_id'], $editData);
|
||||
} catch (EmptyResponse) {}
|
||||
} catch (InvalidResult) {
|
||||
$invoiceData = [
|
||||
'customer' => $customer['toku_id'],
|
||||
'product_id' => $subscription->venta->id,
|
||||
'subscription' => $subscription->toku_id,
|
||||
'cuota' => $cuota,
|
||||
'venta' => $subscription->venta
|
||||
];
|
||||
try {
|
||||
$this->invoice->add($invoiceData);
|
||||
} catch (EmptyResponse) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $queues;
|
||||
}
|
||||
public function reset(array $skips = []): array
|
||||
{
|
||||
$output = [];
|
||||
try {
|
||||
$output['customer'] = $this->customer->reset($skips['customer'] ?? []);
|
||||
$output['subscription'] = $this->subscription->reset($skips['subscription'] ?? []);
|
||||
$output['payments'] = $this->invoice->resetPayments();
|
||||
$output['invoice'] = $this->invoice->reset($skips['invoice'] ?? []);
|
||||
} catch (InvalidResult $exception) {
|
||||
$this->logger->warning($exception);
|
||||
return [];
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
public function queue(array $venta_ids): array
|
||||
{
|
||||
$queues = [];
|
||||
foreach ($venta_ids as $venta_id) {
|
||||
if ($this->subscription->queue($venta_id)) {
|
||||
$queues []= [
|
||||
'type' => 'request',
|
||||
'url' => "/api/external/toku/cuotas/{$venta_id}",
|
||||
'method' => 'post',
|
||||
'body' => []
|
||||
];
|
||||
}
|
||||
}
|
||||
return $queues;
|
||||
}
|
||||
|
||||
public function update(array $ids, ?string $type = null): array
|
||||
{
|
||||
if ($type === null) {
|
||||
$types = [
|
||||
'customers',
|
||||
'subscriptions',
|
||||
'invoices'
|
||||
];
|
||||
$results = [];
|
||||
foreach ($types as $type) {
|
||||
$results[$type] = $this->update($ids[$type], $type);
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
$results = [];
|
||||
switch ($type) {
|
||||
case 'subscriptions':
|
||||
try {
|
||||
$results['subscription'] = $this->subscription->update($ids);
|
||||
} catch (EmptyResult | EmptyResponse $exception) {
|
||||
$this->logger->error($exception);
|
||||
}
|
||||
break;
|
||||
case 'invoices':
|
||||
try {
|
||||
$results['invoice'] = $this->invoice->updateAll($ids);
|
||||
} catch (EmptyResult $exception) {
|
||||
$this->logger->error($exception);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param array $tokenConfig
|
||||
* @return bool
|
||||
*/
|
||||
public function validateToken(ServerRequestInterface $request, array $tokenConfig): bool
|
||||
{
|
||||
if (!$request->hasHeader('User-Agent') or !str_starts_with($request->getHeaderLine('User-Agent'), 'Toku-Webhooks')) {
|
||||
return false;
|
||||
}
|
||||
if (!$request->hasHeader('X-Datadog-Tags') or !$request->hasHeader('Tracestate')) {
|
||||
return false;
|
||||
}
|
||||
if (!$request->hasHeader('Toku-Signature')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tokuSignature = $request->getHeaderLine('Toku-Signature');
|
||||
try {
|
||||
list($timestamp, $signature) = array_map(function($elem) {
|
||||
return explode('=', $elem)[1];
|
||||
}, explode(',', $tokuSignature));
|
||||
$body = $request->getBody()->getContents();
|
||||
$json = json_decode($body, true);
|
||||
if (!is_array($json)) {
|
||||
return false;
|
||||
}
|
||||
if (!array_key_exists('id', $json)) {
|
||||
return false;
|
||||
}
|
||||
$eventId = $json['id'];
|
||||
$eventType = $json['event_type'];
|
||||
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('secret')
|
||||
->from('toku_webhooks')
|
||||
->where('enabled = ? AND JSON_SEARCH(events, "one", ?) IS NOT NULL');
|
||||
$params = [true, $eventType];
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute($params);
|
||||
$results = $statement->fetchAll(PDO::FETCH_COLUMN);
|
||||
if (count($results) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_any($results, fn($secret) => $this->hmac->validate($timestamp, $signature, $eventId, $secret))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (Throwable $throwable) {
|
||||
$this->logger->error($throwable);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $request
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
protected function updatePago(array $request): bool
|
||||
{
|
||||
# If $customer is not found, it will throw an exception and stop
|
||||
$customer = $this->customer->getByExternalId($request['customer']);
|
||||
$invoice = $this->invoice->getByExternalId($request['invoice']);
|
||||
|
||||
return $this->invoice->update($invoice['toku_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'];
|
||||
if (!array_key_exists('amount', $data) and array_key_exists('payment_amount', $data)) {
|
||||
$data['amount'] = $data['payment_amount'];
|
||||
}
|
||||
$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;
|
||||
}
|
||||
protected function getAccountKey(int $sociedad_rut): string
|
||||
{
|
||||
$query = $this->connection->getQueryBuilder()
|
||||
->select('account_key')
|
||||
->from('toku_accounts')
|
||||
->where('enabled = ? AND sociedad_rut = ?');
|
||||
$params = [true, $sociedad_rut];
|
||||
try {
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute($params);
|
||||
return $statement->fetchColumn();
|
||||
} catch (PDOException $exception) {
|
||||
$this->logger->error($exception);
|
||||
throw new EmptyResult($query, $exception);
|
||||
}
|
||||
}
|
||||
}
|
132
app/src/Service/Venta/MediosPago/Toku/Customer.php
Normal file
132
app/src/Service/Venta/MediosPago/Toku/Customer.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta\MediosPago\Toku;
|
||||
|
||||
use PDOException;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service\Venta\MediosPago\AbstractEndPoint;
|
||||
|
||||
class Customer extends AbstractEndPoint
|
||||
{
|
||||
public function __construct(ClientInterface $client,
|
||||
protected Repository\Venta\MediosPago\Toku\Customer $customerRepository)
|
||||
{
|
||||
parent::__construct($client);
|
||||
}
|
||||
|
||||
public function getById(string $id): array
|
||||
{
|
||||
return $this->doGetById([$this->customerRepository, 'fetchByRut'], $id, "No existe toku_id para Persona {$id}");
|
||||
}
|
||||
public function getByExternalId(string $id): array
|
||||
{
|
||||
return $this->doGetById([$this->customerRepository, 'fetchByTokuId'], $id, "No existe Customer para toku_id {$id}");
|
||||
}
|
||||
public function get(string $id): array
|
||||
{
|
||||
$request_uri = "/customers/{$id}";
|
||||
return $this->sendGet($request_uri, [200], [404, 422]);
|
||||
}
|
||||
public function add(array $data, ?string $accountKey = null): bool
|
||||
{
|
||||
$request_uri = "/customers";
|
||||
return $this->sendAdd($request_uri, $data, [200, 201], [400, 422], $accountKey);
|
||||
}
|
||||
public function edit(string $id, array $data, ?string $accountKey = null): bool
|
||||
{
|
||||
$request_uri = "customers/{$id}";
|
||||
return $this->sendEdit($request_uri, $data, [200], [400, 404, 422], $accountKey);
|
||||
}
|
||||
public function delete(string $id): void
|
||||
{
|
||||
$request_uri = "/customers/{$id}";
|
||||
$this->sendDelete($request_uri, [204], [404, 409]);
|
||||
}
|
||||
public function reset(array $skip = []): array
|
||||
{
|
||||
try {
|
||||
$tokuIds = $this->customerRepository->fetchAllTokuIds();
|
||||
$tokuIds = array_filter($tokuIds, function (string $tokuId) use ($skip) {
|
||||
return !in_array($tokuId, $skip);
|
||||
});
|
||||
} catch (EmptyResult $exception) {
|
||||
$this->logger->warning($exception);
|
||||
return [];
|
||||
}
|
||||
$this->logger->info('Resetando ' . count($tokuIds) . ' clientes');
|
||||
foreach ($tokuIds as $tokuId) {
|
||||
try {
|
||||
$this->delete($tokuId);
|
||||
$this->customerRepository->removeByTokuId($tokuId);
|
||||
} catch (EmptyResponse | PDOException $exception) {
|
||||
$this->logger->warning($exception, ['customer->toku_id' => $tokuId]);
|
||||
}
|
||||
}
|
||||
return $tokuIds;
|
||||
}
|
||||
|
||||
public function save(array $data): bool
|
||||
{
|
||||
return $this->doSave($this->customerRepository, $data);
|
||||
}
|
||||
protected function mapParams(array $data): array
|
||||
{
|
||||
$paramsMap = [
|
||||
'government_id' => 'rut',
|
||||
'external_id' => 'rut',
|
||||
'mail' => 'email',
|
||||
'name' => 'nombreCompleto',
|
||||
'phone_number' => 'telefono',
|
||||
'pac_mandate_id' => null,
|
||||
'default_agent' => 'contacto@incoviba.cl',
|
||||
'send_mail' => false,
|
||||
'agent_phone_number' => null,
|
||||
'rfc' => null,
|
||||
'tax_zip_code' => null,
|
||||
'fiscal_regime' => null,
|
||||
'default_receipt_type' => null,
|
||||
'secondary_emails' => null,
|
||||
'silenced_until' => null,
|
||||
'metadata' => null
|
||||
];
|
||||
|
||||
$params = [];
|
||||
foreach ($paramsMap as $key => $ref) {
|
||||
if ($ref === null) {
|
||||
continue;
|
||||
}
|
||||
if ($ref === 'telefono') {
|
||||
$value = $data[$ref];
|
||||
if ($value === '' or $value === null or $value === '0') {
|
||||
continue;
|
||||
}
|
||||
if (!str_starts_with($value, '+')) {
|
||||
$value = "+56{$value}";
|
||||
}
|
||||
$params[$key] = $value;
|
||||
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 = [
|
||||
'government_id' => 'rut',
|
||||
'id' => 'toku_id'
|
||||
];
|
||||
$mappedData = [];
|
||||
foreach ($responseMap as $responseKey => $dataKey) {
|
||||
if (isset($data[$responseKey])) {
|
||||
$mappedData[$dataKey] = $data[$responseKey];
|
||||
}
|
||||
}
|
||||
return $mappedData;
|
||||
}
|
||||
}
|
335
app/src/Service/Venta/MediosPago/Toku/Invoice.php
Normal file
335
app/src/Service/Venta/MediosPago/Toku/Invoice.php
Normal file
@ -0,0 +1,335 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta\MediosPago\Toku;
|
||||
|
||||
use DateMalformedStringException;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use PDO;
|
||||
use PDOException;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResponse;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\InvalidResult;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service\UF;
|
||||
use Incoviba\Service\Venta\MediosPago\AbstractEndPoint;
|
||||
use Incoviba\Service\Venta\Pago;
|
||||
|
||||
class Invoice extends AbstractEndPoint
|
||||
{
|
||||
public function __construct(ClientInterface $client,
|
||||
protected Repository\Venta\MediosPago\Toku\Invoice $invoiceRepository,
|
||||
protected Pago $pagoService,
|
||||
protected UF $ufService)
|
||||
{
|
||||
parent::__construct($client);
|
||||
}
|
||||
|
||||
public function getById(string $id): array
|
||||
{
|
||||
return $this->doGetById([$this->invoiceRepository, 'fetchByCuota'], $id, "No existe toku_id para Cuota {$id}");
|
||||
}
|
||||
public function getByExternalId(string $id): array
|
||||
{
|
||||
return $this->doGetById([$this->invoiceRepository, 'fetchByTokuId'], $id, "No existe Invoice para toku_id {$id}");
|
||||
}
|
||||
public function get(string $id): array
|
||||
{
|
||||
$request_uri = "/invoices/{$id}";
|
||||
return $this->sendGet($request_uri, [200], [404]);
|
||||
}
|
||||
public function add(array $data, ?string $accountKey = null): bool
|
||||
{
|
||||
$request_uri = "/invoices";
|
||||
return $this->sendAdd($request_uri, $data, [200, 201], [400, 409, 422], $accountKey);
|
||||
}
|
||||
public function edit(string $id, array $data, ?string $accountKey = null): bool
|
||||
{
|
||||
$request_uri = "/invoices/{$id}";
|
||||
return $this->sendEdit($request_uri, $data, [200], [400, 404, 409, 422], $accountKey);
|
||||
}
|
||||
public function delete(string $id): void
|
||||
{
|
||||
$request_uri = "/invoices/{$id}";
|
||||
$this->sendDelete($request_uri, [204], [404, 409]);
|
||||
}
|
||||
public function reset(array $skip = []): array
|
||||
{
|
||||
try {
|
||||
$tokuIds = $this->invoiceRepository->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->invoiceRepository->removeByTokuId($tokuId);
|
||||
} catch (EmptyResponse | PDOException $exception) {
|
||||
$this->logger->warning($exception, ['invoice->toku_id' => $tokuId]);
|
||||
}
|
||||
}
|
||||
return $tokuIds;
|
||||
}
|
||||
public function resetPayments(): array
|
||||
{
|
||||
$page = 1;
|
||||
$pageSize = 1000;
|
||||
$totalPayments = [];
|
||||
while (true) {
|
||||
if ($page > 100) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
$request_uri = "/organization/payments?page=1&page_size=1000";
|
||||
$payments = $this->sendGet($request_uri, [200], [404, 422]);
|
||||
} catch (EmptyResponse $exception) {
|
||||
$this->logger->warning($exception, ['request_uri' => $request_uri]);
|
||||
return [];
|
||||
}
|
||||
if (array_key_exists('message', $payments)) {
|
||||
break;
|
||||
}
|
||||
$this->altLogger->info('Reset Payments', ['count' => count($payments), 'payments' => $payments]);
|
||||
$query = [];
|
||||
/*
|
||||
"id": "pay_79zh1OU1pVV5g0V0I6kShf5AF-I24cUn",
|
||||
"created_at": "2025-06-07T07:08:51+0000",
|
||||
"deleted_at": null,
|
||||
"invoice": "in_IhbKbT21x0ADlnKRCbV57sn2DDI8neq0",
|
||||
"customer": "cus_bTXPBVopZxKOqTOWzRZkhvDEM9XXtvWh",
|
||||
"government_id": "175181431",
|
||||
"name": "Augusto Felipe Schilfferli Rojas",
|
||||
"product_id": "1304-d1749582981383358",
|
||||
"due_date": "2024-11-01",
|
||||
"transaction_date": "2025-06-07T07:08:51+0000",
|
||||
"payment_amount": 14.4822,
|
||||
"buy_order": null,
|
||||
"processed_by_toku": false,
|
||||
"payment_method": null,
|
||||
"card_type": null,
|
||||
"card_number": null,
|
||||
"payment_type": null,
|
||||
"authorization_code": null,
|
||||
"mc_order_id": null,
|
||||
"amount_paid": 14.4822
|
||||
*/
|
||||
foreach ($payments as $payment) {
|
||||
$query[] = [
|
||||
'payment_amount' => $payment['payment_amount'],
|
||||
'payment_date' => $payment['transaction_date'],
|
||||
'payment_method' => $payment['payment_method'],
|
||||
'product_id' => $payment['product_id'],
|
||||
'due_date' => $payment['due_date'],
|
||||
];
|
||||
}
|
||||
try {
|
||||
$request_uri = "/payments";
|
||||
$this->sendDelete($request_uri, [204], [404, 422], ['payments' => $query]);
|
||||
} catch (EmptyResponse $exception) {
|
||||
$this->logger->warning($exception, ['request_uri' => $request_uri]);
|
||||
return [];
|
||||
}
|
||||
$this->altLogger->info('Reset Payments Payload', ['count' => count($payments), 'payments' => $query]);
|
||||
$totalPayments = array_merge($totalPayments, $payments);
|
||||
if (count($payments) < $pageSize) {
|
||||
break;
|
||||
}
|
||||
$page++;
|
||||
}
|
||||
return $totalPayments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $customer_id
|
||||
* @return array
|
||||
* @throws EmptyResponse
|
||||
*/
|
||||
public function getByCustomer(string $customer_id): array
|
||||
{
|
||||
$request_uri = "/invoices/customer/{$customer_id}";
|
||||
return $this->sendGet($request_uri, [200], [404]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $invoice_toku_id
|
||||
* @param array $data
|
||||
* @return bool
|
||||
* @throws InvalidResult
|
||||
*/
|
||||
public function update(string $invoice_toku_id, array $data): bool
|
||||
{
|
||||
try {
|
||||
$invoice = $this->invoiceRepository->fetchByTokuId($invoice_toku_id);
|
||||
} catch (EmptyResult $exception) {
|
||||
$this->logger->warning($exception, ['invoice_toku_id' => $invoice_toku_id, 'data' => $data]);
|
||||
throw new InvalidResult("No existe Invoice para toku_id {$invoice_toku_id}", 404, $exception);
|
||||
}
|
||||
if ($data['status'] !== 'AUTHORIZED') {
|
||||
$this->logger->warning("Pago no autorizado", ['invoice_toku_id' => $invoice_toku_id, 'data' => $data]);
|
||||
throw new InvalidResult("Pago no autorizado", 422);
|
||||
}
|
||||
$dateString = $data['date'];
|
||||
try {
|
||||
$date = new DateTimeImmutable($dateString);
|
||||
} catch (DateMalformedStringException $exception) {
|
||||
$this->logger->warning($exception, ['invoice_toku_id' => $invoice_toku_id, 'data' => $data]);
|
||||
throw new InvalidResult("Fecha no válida: {$dateString}", 422, $exception);
|
||||
}
|
||||
$uf = $this->ufService->get($date);
|
||||
if ($uf === 0.0) {
|
||||
$this->logger->warning("No hay UF para la fecha: {$dateString}", ['invoice_toku_id' => $invoice_toku_id, 'data' => $data]);
|
||||
throw new InvalidResult("No hay UF para la fecha: {$dateString}", 422);
|
||||
}
|
||||
$valor = $data['amount'];
|
||||
if ($valor > 1000) {
|
||||
$valor = $data['amount'] / $uf;
|
||||
}
|
||||
if (abs($valor - $invoice->cuota->pago->valor()) >= 0.0001) {
|
||||
$this->logger->warning("Valor en UF no coincide: {$data['amount']}, {$valor} <=> {$invoice->cuota->pago->valor()}", ['invoice_toku_id' => $invoice_toku_id, 'data' => $data]);
|
||||
throw new InvalidResult("Valor en UF no coincide: {$data['amount']}, {$valor} <=> {$invoice->cuota->pago->valor()}", 422);
|
||||
}
|
||||
if ($invoice->cuota->pago->isPagado()) {
|
||||
return true;
|
||||
}
|
||||
return $this->pagoService->depositar($invoice->cuota->pago, $date);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $idsData
|
||||
* @return array
|
||||
* @throws EmptyResult
|
||||
*/
|
||||
public function updateAll(array $idsData): array
|
||||
{
|
||||
$tokuIds = array_column($idsData, 'toku_id');
|
||||
$oldIds = array_column($idsData, 'product_id');
|
||||
|
||||
$placeholders = array_map(fn($id) => "id{$id}", array_keys($oldIds));
|
||||
$placeholdersString = implode(', ', array_map(fn($id) => ":{$id}", $placeholders));
|
||||
$query = $this->pagoService->getRepository()->getConnection()->getQueryBuilder()
|
||||
->select('pago.id, CONCAT_WS("-", unidad.descripcion, CONCAT_WS("-", propietario.rut, propietario.dv)) AS old_pid')
|
||||
->from('pago')
|
||||
->joined('JOIN cuota ON cuota.pago = pago.id')
|
||||
->joined('JOIN venta ON venta.pie = cuota.pie')
|
||||
->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, $oldIds);
|
||||
try {
|
||||
$statement = $this->pagoService->getRepository()->getConnection()->execute($query, $values);
|
||||
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $exception) {
|
||||
$this->logger->error($exception);
|
||||
throw new EmptyResult($query, $exception);
|
||||
}
|
||||
|
||||
$ids = array_column($results, 'pago.id');
|
||||
$newIds = array_combine($ids, $tokuIds);
|
||||
return array_map(fn($id) => ['product_id' => $id, 'toku_id' => $newIds[$id]], $ids);
|
||||
}
|
||||
|
||||
public function save(array $data): bool
|
||||
{
|
||||
return $this->doSave($this->invoiceRepository, $data);
|
||||
}
|
||||
|
||||
protected LoggerInterface $altLogger;
|
||||
public function setAltLogger(LoggerInterface $altLogger): self
|
||||
{
|
||||
$this->altLogger = $altLogger;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function mapParams(array $data): array
|
||||
{
|
||||
$paramsMap = [
|
||||
'customer' => 'customer',
|
||||
'product_id' => 'cuota_id',
|
||||
'due_date' => 'fecha',
|
||||
'subscription' => 'subscription',
|
||||
'amount' => 'valor',
|
||||
'is_paid' => 'isPagada',
|
||||
'is_void' => 'isRechazada',
|
||||
'link_payment' => null,
|
||||
'metadata' => 'datosCuota',
|
||||
'receipt_type' => null,
|
||||
'id_receipt' => null,
|
||||
'disable_automatic_payment' => null,
|
||||
'currency_code' => 'CLF',
|
||||
'invoice_external_id' => 'cuota_id'
|
||||
];
|
||||
|
||||
$today = new DateTimeImmutable('now', new DateTimeZone('America/Santiago'));
|
||||
|
||||
$params = [];
|
||||
foreach ($paramsMap as $key => $ref) {
|
||||
if ($ref === null) {
|
||||
continue;
|
||||
}
|
||||
if ($ref === 'fecha') {
|
||||
$params[$key] = $data['cuota']->pago->fecha->format('Y-m-d');
|
||||
continue;
|
||||
}
|
||||
if ($ref === 'valor') {
|
||||
/*$valor = 0;
|
||||
if ($data['cuota']->pago->fecha <= $today) {
|
||||
$valor = $data['cuota']->pago->valor();
|
||||
}
|
||||
if ($valor === 0) {
|
||||
$valor = $data['cuota']->pago->valor / $data['venta']->uf;
|
||||
}
|
||||
$params[$key] = $valor;*/
|
||||
$params[$key] = $data['cuota']->pago->valor;
|
||||
continue;
|
||||
}
|
||||
if ($ref === 'datosCuota') {
|
||||
$params[$key] = $this->datosCuota($data['cuota']);
|
||||
continue;
|
||||
}
|
||||
if ($ref === 'isPagada') {
|
||||
$params[$key] = $data['cuota']->isPagada();
|
||||
}
|
||||
if ($ref === 'isRechazada') {
|
||||
$params[$key] = $data['cuota']->isRechazada();
|
||||
}
|
||||
if ($ref === 'cuota_id') {
|
||||
$params[$key] = $data['cuota']->id;
|
||||
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 = [
|
||||
'invoice_external_id' => 'cuota_id',
|
||||
'id' => 'toku_id'
|
||||
];
|
||||
$mappedData = [];
|
||||
foreach ($responseMap as $responseKey => $dataKey) {
|
||||
if (isset($data[$responseKey])) {
|
||||
$mappedData[$dataKey] = $data[$responseKey];
|
||||
}
|
||||
}
|
||||
return $mappedData;
|
||||
}
|
||||
|
||||
protected function datosCuota(Model\Venta\Cuota $cuota): array
|
||||
{
|
||||
return [
|
||||
'Numero' => $cuota->numero,
|
||||
'Monto_CLP' => $cuota->pago->valor
|
||||
];
|
||||
}
|
||||
}
|
302
app/src/Service/Venta/MediosPago/Toku/Subscription.php
Normal file
302
app/src/Service/Venta/MediosPago/Toku/Subscription.php
Normal file
@ -0,0 +1,302 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
@ -1,27 +1,40 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use Exception;
|
||||
use DateTimeInterface;
|
||||
use DateTimeImmutable;
|
||||
use DateMalformedStringException;
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Exception\ServiceAction\Update;
|
||||
use PDOException;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Service;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Pago
|
||||
class Pago extends Ideal\Service\Repository
|
||||
{
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
protected Repository\Venta\Pago $pagoRepository,
|
||||
protected Repository\Venta\EstadoPago $estadoPagoRepository,
|
||||
protected Repository\Venta\TipoEstadoPago $tipoEstadoPagoRepository,
|
||||
protected Service\UF $ufService,
|
||||
protected Service\Valor $valorService
|
||||
) {}
|
||||
protected Service\Valor $valorService,
|
||||
protected Service\Queue $queueService
|
||||
)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getRepository(): Define\Repository
|
||||
{
|
||||
return $this->pagoRepository;
|
||||
}
|
||||
|
||||
public function depositar(Model\Venta\Pago $pago, DateTimeInterface $fecha): bool
|
||||
{
|
||||
@ -37,7 +50,7 @@ class Pago
|
||||
$pago = $this->process($this->pagoRepository->fetchById($pago->id));
|
||||
$this->getUF($pago);
|
||||
return true;
|
||||
} catch (PDOException) {
|
||||
} catch (PDOException | EmptyResult) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -89,13 +102,23 @@ class Pago
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $pago_id
|
||||
* @return Model\Venta\Pago|null
|
||||
* @throws Read
|
||||
*/
|
||||
public function getById(?int $pago_id): ?Model\Venta\Pago
|
||||
{
|
||||
if ($pago_id === null) {
|
||||
return null;
|
||||
}
|
||||
$pago = $this->pagoRepository->fetchById($pago_id);
|
||||
return $this->process($pago);
|
||||
try {
|
||||
$pago = $this->pagoRepository->fetchById($pago_id);
|
||||
return $this->process($pago);
|
||||
} catch (EmptyResult) {
|
||||
throw new Read(__CLASS__);
|
||||
}
|
||||
}
|
||||
|
||||
public function getByVenta(int $venta_id): array
|
||||
@ -130,6 +153,11 @@ class Pago
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Pago
|
||||
* @throws Create
|
||||
*/
|
||||
public function add(array $data): Model\Venta\Pago
|
||||
{
|
||||
if (array_key_exists('fecha', $data)) {
|
||||
@ -139,24 +167,32 @@ class Pago
|
||||
$fecha = new DateTimeImmutable();
|
||||
}
|
||||
$data['fecha'] = $fecha->format('Y-m-d');
|
||||
if (!array_key_exists('uf', $data)) {
|
||||
$data['uf'] = $this->ufService->get($fecha);
|
||||
}
|
||||
}
|
||||
$data['valor'] = $this->valorService->toPesos($this->valorService->clean($data['valor']), $data['fecha']);
|
||||
|
||||
$filtered_data = $this->pagoRepository->filterData($data);
|
||||
|
||||
$pago = $this->pagoRepository->create($filtered_data);
|
||||
$pago = $this->pagoRepository->save($pago);
|
||||
try {
|
||||
$pago = $this->pagoRepository->create($filtered_data);
|
||||
$pago = $this->pagoRepository->save($pago);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
if (!array_key_exists('uf', $data)) {
|
||||
$this->getUFAsync($pago);
|
||||
}
|
||||
|
||||
$tipoEstado = $this->tipoEstadoPagoRepository->fetchByDescripcion('no pagado');
|
||||
$estado = $this->estadoPagoRepository->create([
|
||||
'pago' => $pago->id,
|
||||
'fecha' => $pago->fecha->format('Y-m-d'),
|
||||
'estado' => $tipoEstado->id
|
||||
]);
|
||||
$estado = $this->estadoPagoRepository->save($estado);
|
||||
try {
|
||||
$estado = $this->estadoPagoRepository->create([
|
||||
'pago' => $pago->id,
|
||||
'fecha' => $pago->fecha->format('Y-m-d'),
|
||||
'estado' => $tipoEstado->id
|
||||
]);
|
||||
$estado = $this->estadoPagoRepository->save($estado);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
$pago->currentEstado = $estado;
|
||||
return $pago;
|
||||
}
|
||||
@ -213,6 +249,21 @@ class Pago
|
||||
|
||||
return $this->process($this->pagoRepository->fetchById($pago->id));
|
||||
}
|
||||
public function updateUF(int $pago_id): bool
|
||||
{
|
||||
try {
|
||||
$pago = $this->getById($pago_id);
|
||||
} catch (Read) {
|
||||
return false;
|
||||
}
|
||||
$uf = $this->ufService->get($pago->currentEstado->fecha);
|
||||
try {
|
||||
$this->pagoRepository->edit($pago, ['uf' => $uf]);
|
||||
return true;
|
||||
} catch (EmptyResult | PDOException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function process($pago): Model\Venta\Pago
|
||||
{
|
||||
@ -232,13 +283,27 @@ class Pago
|
||||
return $uf;
|
||||
}
|
||||
if ($uf !== 0.0) {
|
||||
$this->pagoRepository->edit($pago, ['uf' => $uf]);
|
||||
try {
|
||||
$this->pagoRepository->edit($pago, ['uf' => $uf]);
|
||||
} catch (EmptyResult) {}
|
||||
return $uf;
|
||||
}
|
||||
} elseif ($pago->uf === 0.0) {
|
||||
$this->pagoRepository->edit($pago, ['uf' => null]);
|
||||
try {
|
||||
$this->pagoRepository->edit($pago, ['uf' => null]);
|
||||
} catch (EmptyResult) {}
|
||||
return null;
|
||||
}
|
||||
return $pago->uf;
|
||||
}
|
||||
protected function getUFAsync(Model\Venta\Pago $pago): void
|
||||
{
|
||||
$queueData = [
|
||||
'type' => 'service',
|
||||
'service' => __CLASS__,
|
||||
'method' => 'updateUF',
|
||||
'params' => ['pago_id' => $pago->id]
|
||||
];
|
||||
$this->queueService->push($queueData);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,22 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use PDOException;
|
||||
use DateTimeImmutable;
|
||||
use DateMalformedStringException;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Common\Implement\Repository\Factory;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Exception\ServiceAction\{Create, Read};
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service\UF;
|
||||
|
||||
class Pie
|
||||
{
|
||||
public function __construct(
|
||||
protected Repository\Venta\Pie $pieRepository,
|
||||
protected Cuota $cuotaService,
|
||||
protected Pago $pagoService
|
||||
protected Pago $pagoService,
|
||||
protected UF $ufService
|
||||
) {}
|
||||
|
||||
public function getById(int $pie_id): Model\Venta\Pie
|
||||
@ -28,12 +32,33 @@ class Pie
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Pie
|
||||
* @throws Create
|
||||
*/
|
||||
public function add(array $data): Model\Venta\Pie
|
||||
{
|
||||
$filteredData = $this->pieRepository->filterData($data);
|
||||
$pie = $this->pieRepository->create($filteredData);
|
||||
return $this->pieRepository->save($pie);
|
||||
try {
|
||||
$filteredData = $this->pieRepository->filterData($data);
|
||||
if (!isset($filteredData['uf'])) {
|
||||
try {
|
||||
$date = new DateTimeImmutable($filteredData['fecha']);
|
||||
$filteredData['uf'] = $this->ufService->get($date);
|
||||
} catch (DateMalformedStringException) {}
|
||||
}
|
||||
$pie = $this->pieRepository->create($filteredData);
|
||||
return $this->pieRepository->save($pie);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Cuota
|
||||
* @throws Create
|
||||
*/
|
||||
public function addCuota(array $data): Model\Venta\Cuota
|
||||
{
|
||||
return $this->cuotaService->add($data);
|
||||
@ -58,6 +83,12 @@ class Pie
|
||||
if (isset($pie->asociado)) {
|
||||
$pie->asociado = $this->getById($pie->asociado->id);
|
||||
}
|
||||
if (($pie->uf === null or $pie->uf === 0.0) and $pie->fecha <= new DateTimeImmutable()) {
|
||||
$pie->uf = $this->ufService->get($pie->fecha);
|
||||
try {
|
||||
$this->pieRepository->edit($pie, ['uf' => $pie->uf]);
|
||||
} catch (EmptyResult) {}
|
||||
}
|
||||
return $pie;
|
||||
}
|
||||
}
|
||||
|
464
app/src/Service/Venta/Promotion.php
Normal file
464
app/src/Service/Venta/Promotion.php
Normal file
@ -0,0 +1,464 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use Incoviba\Controller\API\Ventas\Promotions;
|
||||
use PDOException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Exception;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Promotion extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Venta\Promotion $promotionRepository,
|
||||
protected Repository\Proyecto $projectRepository,
|
||||
protected Repository\Proyecto\Broker\Contract $contractRepository,
|
||||
protected Repository\Proyecto\Broker $brokerRepository,
|
||||
protected Repository\Proyecto\TipoUnidad $tipoUnidadRepository,
|
||||
protected Repository\Proyecto\ProyectoTipoUnidad $proyectoTipoUnidadRepository,
|
||||
protected Repository\Venta\Unidad $unidadRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getAll(null|string|array $order = null): array
|
||||
{
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->promotionRepository->fetchAll($order));
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Read
|
||||
*/
|
||||
public function getById(int $promotion_id): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
return $this->process($this->promotionRepository->fetchById($promotion_id));
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contract_id
|
||||
* @return array
|
||||
*/
|
||||
public function getByContract(int $contract_id): array
|
||||
{
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->promotionRepository->fetchByContract($contract_id));
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $contract_id
|
||||
* @return array
|
||||
*/
|
||||
public function getActiveByContract(int $contract_id): array
|
||||
{
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->promotionRepository->fetchActiveByContract($contract_id));
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function add(array $data): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$filteredData = $this->promotionRepository->filterData($data);
|
||||
$promotion = $this->promotionRepository->create($filteredData);
|
||||
return $this->process($this->promotionRepository->save($promotion));
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model\Venta\Promotion $promotion
|
||||
* @param array $data
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Update
|
||||
*/
|
||||
public function edit(Model\Venta\Promotion $promotion, array $data): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$filteredData = $this->promotionRepository->filterData($data);
|
||||
$promotion = $this->promotionRepository->edit($promotion, $filteredData);
|
||||
return $this->process($promotion);
|
||||
} catch (PDOException | Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Update(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
*/
|
||||
public function remove(int $promotion_id): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
$this->promotionRepository->remove($promotion);
|
||||
return $promotion;
|
||||
} catch (PDOException | Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $project_id
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function addProject(int $promotion_id, int $project_id): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$project = $this->projectRepository->fetchById($project_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
if (in_array($project, $promotion->projects())) {
|
||||
return $this->process($promotion);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->insertProjectForPromotion($promotion, $project->id);
|
||||
return $this->process($promotion);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $broker_rut
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function addBroker(int $promotion_id, int $broker_rut): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$broker = $this->brokerRepository->fetchById($broker_rut);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
if (in_array($broker, $promotion->brokers())) {
|
||||
return $this->process($promotion);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->insertBrokerForPromotion($promotion, $broker->rut);
|
||||
return $this->process($promotion);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $project_id
|
||||
* @param int $unitType_id
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function addUnitType(int $promotion_id, int $project_id, int $unitType_id): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$project = $this->projectRepository->fetchById($project_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$unitType = $this->tipoUnidadRepository->fetchById($unitType_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
if (in_array(['project' => $project, 'unitType' => $unitType], $promotion->unitTypes())) {
|
||||
return $this->process($promotion);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->insertUnitTypeForPromotion($promotion, $project->id, $unitType->id);
|
||||
return $this->process($promotion);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $unit_line_id
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function addUnitLine(int $promotion_id, int $unit_line_id): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$unitLine = $this->proyectoTipoUnidadRepository->fetchById($unit_line_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
if (in_array($unitLine, $promotion->unitLines())) {
|
||||
return $this->process($promotion);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->insertUnitLineForPromotion($promotion, $unitLine->id);
|
||||
return $this->process($promotion);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $unit_id
|
||||
* @return Model\Venta\Promotion
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function addUnit(int $promotion_id, int $unit_id): Model\Venta\Promotion
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$unit = $this->unidadRepository->fetchById($unit_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
if (in_array($unit, $promotion->units())) {
|
||||
return $this->process($promotion);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->insertUnitForPromotion($promotion, $unit->id);
|
||||
return $this->process($promotion);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $project_id
|
||||
* @return void
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
*/
|
||||
public function removeProject(int $promotion_id, int $project_id): void
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$project = $this->projectRepository->fetchById($project_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->removeProjectForPromotion($promotion, $project->id);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $broker_rut
|
||||
* @return void
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
*/
|
||||
public function removeBroker(int $promotion_id, int $broker_rut): void
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$broker = $this->brokerRepository->fetchById($broker_rut);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->removeBrokerForPromotion($promotion, $broker->rut);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $project_id
|
||||
* @param int $unitType_id
|
||||
* @return void
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
*/
|
||||
public function removeUnitType(int $promotion_id, int $project_id, int $unitType_id): void
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$project = $this->projectRepository->fetchById($project_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$unitType = $this->tipoUnidadRepository->fetchById($unitType_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->removeUnitTypeForPromotion($promotion, $project->id, $unitType->id);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $unit_line_id
|
||||
* @return void
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
*/
|
||||
public function removeUnitLine(int $promotion_id, int $unit_line_id): void
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$unitLine = $this->proyectoTipoUnidadRepository->fetchById($unit_line_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->removeUnitLineForPromotion($promotion, $unitLine->id);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $promotion_id
|
||||
* @param int $unit_id
|
||||
* @return void
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
*/
|
||||
public function removeUnit(int $promotion_id, int $unit_id): void
|
||||
{
|
||||
try {
|
||||
$promotion = $this->promotionRepository->fetchById($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$unit = $this->unidadRepository->fetchById($unit_id);
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
try {
|
||||
$this->promotionRepository->removeUnitForPromotion($promotion, $unit->id);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
protected function process(Model\Venta\Promotion $model): Model\Venta\Promotion
|
||||
{
|
||||
$model->addFactory('projects', (new Implement\Repository\Factory())
|
||||
->setCallable(function($promotion_id) {
|
||||
try {
|
||||
return $this->projectRepository->fetchByPromotion($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
->setArgs(['promotion_id' => $model->id]));
|
||||
$model->addFactory('brokers', (new Implement\Repository\Factory())
|
||||
->setCallable(function($promotion_id) {
|
||||
try {
|
||||
return $this->brokerRepository->fetchByPromotion($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
->setArgs(['promotion_id' => $model->id]));
|
||||
$model->addFactory('unitTypes', (new Implement\Repository\Factory())
|
||||
->setCallable(function($promotion_id) {
|
||||
try {
|
||||
return array_map(function(array $ids) {
|
||||
return [
|
||||
'project' => $this->projectRepository->fetchById($ids['project_id']),
|
||||
'unitType' => $this->tipoUnidadRepository->fetchById($ids['id'])
|
||||
];
|
||||
}, $this->tipoUnidadRepository->fetchByPromotion($promotion_id));
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
->setArgs(['promotion_id' => $model->id])
|
||||
);
|
||||
$model->addFactory('unitLines', (new Implement\Repository\Factory())
|
||||
->setCallable(function($promotion_id) {
|
||||
try {
|
||||
return $this->proyectoTipoUnidadRepository->fetchByPromotion($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
->setArgs(['promotion_id' => $model->id])
|
||||
);
|
||||
$model->addFactory('units', (new Implement\Repository\Factory())
|
||||
->setCallable(function($promotion_id) {
|
||||
try {
|
||||
return $this->unidadRepository->fetchByPromotion($promotion_id);
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
})
|
||||
->setArgs(['promotion_id' => $model->id]));
|
||||
return $model;
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal\Service;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
|
||||
@ -21,11 +22,48 @@ class Propiedad extends Service
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $propiedad_id
|
||||
* @return Model\Venta\Propiedad
|
||||
* @throws Exception\ServiceAction\Read
|
||||
*/
|
||||
public function getById(int $propiedad_id): Model\Venta\Propiedad
|
||||
{
|
||||
try {
|
||||
return $this->process($this->propiedadRepository->fetchById($propiedad_id));
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $propiedad_id
|
||||
* @return array
|
||||
* @throws Exception\ServiceAction\Read
|
||||
*/
|
||||
public function getArrayById(int $propiedad_id): array
|
||||
{
|
||||
try {
|
||||
return $this->propiedadRepository->fetchArrayById($propiedad_id);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Exception\ServiceAction\Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $ids
|
||||
* @return Model\Venta\Propiedad
|
||||
* @throws Exception\ServiceAction\Create
|
||||
*/
|
||||
public function addPropiedad(array $ids): Model\Venta\Propiedad
|
||||
{
|
||||
$unidades = [];
|
||||
foreach ($ids as $unidad_id) {
|
||||
$unidades []= $this->unidadRepository->fetchById($unidad_id);
|
||||
try {
|
||||
$unidades []= $this->unidadRepository->fetchById($unidad_id);
|
||||
} catch (EmptyResult $exception) {
|
||||
$this->logger->warning($exception);
|
||||
}
|
||||
}
|
||||
usort($unidades, function(Model\Venta\Unidad $a, Model\Venta\Unidad $b) {
|
||||
$t = $a->proyectoTipoUnidad->tipoUnidad->orden - $b->proyectoTipoUnidad->tipoUnidad->orden;
|
||||
@ -42,13 +80,25 @@ class Propiedad extends Service
|
||||
'unidad_principal' => $unidades[0]->id,
|
||||
'estado' => 1
|
||||
]);
|
||||
$propiedad = $this->propiedadRepository->save($propiedad);
|
||||
try {
|
||||
$propiedad = $this->propiedadRepository->save($propiedad);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
$this->addUnidades($propiedad, $unidades);
|
||||
$this->cleanUpUnidades($propiedad, $unidades);
|
||||
try {
|
||||
$this->cleanUpUnidades($propiedad, $unidades);
|
||||
} catch (Exception\ServiceAction\Read|Exception\ServiceAction\Delete) {}
|
||||
|
||||
return $propiedad;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model\Venta\Propiedad $propiedad
|
||||
* @param array $unidades
|
||||
* @return void
|
||||
*/
|
||||
protected function addUnidades(Model\Venta\Propiedad $propiedad, array $unidades): void
|
||||
{
|
||||
$query = "SELECT 1 FROM `propiedad_unidad` WHERE `propiedad` = ? AND `unidad` = ?";
|
||||
@ -63,19 +113,33 @@ class Propiedad extends Service
|
||||
throw new EmptyResult($query);
|
||||
}
|
||||
} catch (PDOException|EmptyResult) {
|
||||
$insert->execute([$propiedad->id, $unidad->id, ($ix === 0) ? 1 : 0]);
|
||||
try {
|
||||
$insert->execute([$propiedad->id, $unidad->id, ($ix === 0) ? 1 : 0]);
|
||||
} catch (PDOException) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model\Venta\Propiedad $propiedad
|
||||
* @param array $unidades
|
||||
* @return void
|
||||
* @throws Exception\ServiceAction\Delete
|
||||
* @throws Exception\ServiceAction\Read
|
||||
*/
|
||||
protected function cleanUpUnidades(Model\Venta\Propiedad $propiedad, array $unidades): void
|
||||
{
|
||||
$query = "SELECT `unidad` FROM `propiedad_unidad` WHERE `propiedad` = ?";
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute([$propiedad->id]);
|
||||
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
try {
|
||||
$statement = $this->connection->prepare($query);
|
||||
$statement->execute([$propiedad->id]);
|
||||
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Read(__CLASS__, $exception);
|
||||
}
|
||||
|
||||
if (!$results) {
|
||||
return;
|
||||
throw new Exception\ServiceAction\Read(__CLASS__);
|
||||
}
|
||||
|
||||
$all_ids = array_map(function($row) {return $row['unidad'];}, $results);
|
||||
@ -85,9 +149,19 @@ class Propiedad extends Service
|
||||
return;
|
||||
}
|
||||
$query = "DELETE FROM `propiedad_unidad` WHERE `propiedad` = ? AND `unidad` = ?";
|
||||
$statement = $this->connection->prepare($query);
|
||||
try {
|
||||
$statement = $this->connection->prepare($query);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Exception\ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
foreach ($diff as $id) {
|
||||
$statement->execute([$propiedad->id, $id]);
|
||||
try {
|
||||
$statement->execute([$propiedad->id, $id]);
|
||||
} catch (PDOException) {}
|
||||
}
|
||||
}
|
||||
protected function process(Model\Venta\Propiedad $propiedad): Model\Venta\Propiedad
|
||||
{
|
||||
return $propiedad;
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +1,70 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use PDOException;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Exception\ServiceAction\{Create, Read, Update};
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Incoviba\Model;
|
||||
|
||||
class PropiedadUnidad
|
||||
{
|
||||
public function __construct(protected Repository\Venta\PropiedadUnidad $propiedadUnidadRepository,
|
||||
protected Repository\Venta\Unidad $unidadRepository,
|
||||
protected Precio $precioService) {}
|
||||
protected Precio $precioService, protected Service\Valor $valorService) {}
|
||||
|
||||
/**
|
||||
* @param int $unidad_id
|
||||
* @return Model\Venta\PropiedadUnidad
|
||||
* @throws Read
|
||||
*/
|
||||
public function getById(int $unidad_id): Model\Venta\PropiedadUnidad
|
||||
{
|
||||
return $this->process($this->propiedadUnidadRepository->fetchById($unidad_id));
|
||||
try {
|
||||
return $this->process($this->propiedadUnidadRepository->fetchById($unidad_id));
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
public function getByVenta(int $venta_id): array
|
||||
{
|
||||
return array_map([$this, 'process'], $this->propiedadUnidadRepository->fetchByVenta($venta_id));
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->propiedadUnidadRepository->fetchByVenta($venta_id));
|
||||
} catch (EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
public function getByPropiedad(int $propiedad_id): array
|
||||
{
|
||||
return array_map([$this, 'process'], $this->propiedadUnidadRepository->fetchByPropiedad($propiedad_id));
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->propiedadUnidadRepository->fetchByPropiedad($propiedad_id));
|
||||
} catch (EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
public function getArrayByPropiedad(int $propiedad_id): array
|
||||
{
|
||||
try {
|
||||
return $this->propiedadUnidadRepository->fetchArrayByPropiedad($propiedad_id);
|
||||
} catch (EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\PropiedadUnidad
|
||||
* @throws Create
|
||||
* @throws Read
|
||||
*/
|
||||
public function add(array $data): Model\Venta\PropiedadUnidad
|
||||
{
|
||||
$unidad = $this->unidadRepository->fetchById($data['unidad']);
|
||||
try {
|
||||
$unidad = $this->unidadRepository->fetchById($data['unidad']);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
$temp = json_decode(json_encode($unidad), JSON_OBJECT_AS_ARRAY);
|
||||
$columnMap = [
|
||||
'proyecto_tipo_unidad' => 'pt'
|
||||
@ -40,11 +77,31 @@ class PropiedadUnidad
|
||||
$temp['propiedad'] = $data['propiedad'];
|
||||
$temp['valor'] = $data['valor'];
|
||||
$pu = $this->propiedadUnidadRepository->create($temp);
|
||||
return $this->process($this->propiedadUnidadRepository->save($pu));
|
||||
try {
|
||||
return $this->process($this->propiedadUnidadRepository->save($pu));
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model\Venta\PropiedadUnidad $propiedadUnidad
|
||||
* @param array $data
|
||||
* @return Model\Venta\PropiedadUnidad
|
||||
* @throws EmptyResult
|
||||
* @throws Update
|
||||
*/
|
||||
public function edit(Model\Venta\PropiedadUnidad $propiedadUnidad, array $data): Model\Venta\PropiedadUnidad
|
||||
{
|
||||
return $this->process($this->propiedadUnidadRepository->edit($propiedadUnidad, $data));
|
||||
try {
|
||||
$filteredData = $this->propiedadUnidadRepository->filterData($data);
|
||||
if (array_key_exists('valor', $filteredData)) {
|
||||
$filteredData['valor'] = $this->valorService->clean($filteredData['valor']);
|
||||
}
|
||||
return $this->process($this->propiedadUnidadRepository->edit($propiedadUnidad, $filteredData));
|
||||
} catch (PDOException $exception) {
|
||||
throw new Update(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
protected function process(Model\Venta\PropiedadUnidad $unidad): Model\Venta\PropiedadUnidad
|
||||
@ -52,7 +109,7 @@ class PropiedadUnidad
|
||||
try {
|
||||
$unidad->precios = $this->precioService->getByUnidad($unidad->id);
|
||||
$unidad->currentPrecio = $this->precioService->getVigenteByUnidad($unidad->id);
|
||||
if ($unidad->valor === null or $unidad->valor === 0) {
|
||||
if ($unidad->valor === null) {
|
||||
$unidad->valor = $unidad->currentPrecio->valor;
|
||||
}
|
||||
} catch (Read) {}
|
||||
|
@ -3,8 +3,12 @@ namespace Incoviba\Service\Venta;
|
||||
|
||||
use Incoviba\Common\Ideal\Service;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Exception\ServiceAction\Update;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
use PDOException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Propietario extends Service
|
||||
@ -17,10 +21,27 @@ class Propietario extends Service
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $rut
|
||||
* @return Model\Venta\Propietario
|
||||
* @throws Read
|
||||
*/
|
||||
public function getByRut(int $rut): Model\Venta\Propietario
|
||||
{
|
||||
return $this->propietarioRepository->fetchById($rut);
|
||||
try {
|
||||
return $this->propietarioRepository->fetchById($rut);
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model\Venta\Propietario $propietario
|
||||
* @param array $data
|
||||
* @return Model\Venta\Propietario
|
||||
* @throws Create
|
||||
* @throws Update
|
||||
*/
|
||||
public function edit(Model\Venta\Propietario $propietario, array $data): Model\Venta\Propietario
|
||||
{
|
||||
if (isset($data['calle']) or isset($data['numero']) or isset($data['extra']) or isset($data['comuna'])) {
|
||||
@ -28,8 +49,18 @@ class Propietario extends Service
|
||||
$data['direccion'] = $direccion->id;
|
||||
}
|
||||
$filteredData = $this->propietarioRepository->filterData($data);
|
||||
return $this->propietarioRepository->edit($propietario, $filteredData);
|
||||
try {
|
||||
return $this->propietarioRepository->edit($propietario, $filteredData);
|
||||
} catch (PDOException | EmptyResult $exception) {
|
||||
throw new Update(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Propietario
|
||||
* @throws Create
|
||||
*/
|
||||
public function addPropietario(array $data): Model\Venta\Propietario
|
||||
{
|
||||
$direccion = $this->addDireccion($data);
|
||||
@ -42,14 +73,16 @@ class Propietario extends Service
|
||||
$data['dv'] = $dv;
|
||||
}
|
||||
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'rut',
|
||||
'dv',
|
||||
'nombres',
|
||||
'apellido_paterno',
|
||||
'apellido_materno',
|
||||
'direccion'
|
||||
], 0);
|
||||
'direccion',
|
||||
'email',
|
||||
'telefono'
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
|
||||
try {
|
||||
@ -60,11 +93,22 @@ class Propietario extends Service
|
||||
}
|
||||
$propietario = $this->propietarioRepository->edit($propietario, $edits);
|
||||
} catch (EmptyResult) {
|
||||
$propietario = $this->propietarioRepository->create($filtered_data);
|
||||
$propietario = $this->propietarioRepository->save($propietario);
|
||||
try {
|
||||
$propietario = $this->propietarioRepository->create($filtered_data);
|
||||
$propietario = $this->propietarioRepository->save($propietario);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
return $propietario;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Venta\Propietario
|
||||
* @throws Create
|
||||
* @throws Update
|
||||
*/
|
||||
public function addSociedad(array $data): Model\Venta\Propietario
|
||||
{
|
||||
$direccion = $this->addDireccion($data);
|
||||
@ -74,12 +118,12 @@ class Propietario extends Service
|
||||
$data['rut'] = explode('-', $data['rut'])[0];
|
||||
}
|
||||
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'rut',
|
||||
'razon_social',
|
||||
'direccion',
|
||||
'representante'
|
||||
], 0);
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
$mapped_data = array_combine([
|
||||
'rut',
|
||||
@ -97,27 +141,45 @@ class Propietario extends Service
|
||||
if ($sociedad->contacto->rut !== $mapped_data['representante']) {
|
||||
$edits['representante'] = $mapped_data['representante'];
|
||||
}
|
||||
$sociedad = $this->propietarioRepository->edit($sociedad, $edits);
|
||||
try {
|
||||
$sociedad = $this->propietarioRepository->edit($sociedad, $edits);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Update(__CLASS__, $exception);
|
||||
}
|
||||
} catch (EmptyResult) {
|
||||
$sociedad = $this->propietarioRepository->create($mapped_data);
|
||||
$sociedad = $this->propietarioRepository->save($sociedad);
|
||||
try {
|
||||
$sociedad = $this->propietarioRepository->create($mapped_data);
|
||||
$sociedad = $this->propietarioRepository->save($sociedad);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
return $sociedad;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return Model\Direccion
|
||||
* @throws Create
|
||||
*/
|
||||
protected function addDireccion(array $data): Model\Direccion
|
||||
{
|
||||
$fields = array_fill_keys([
|
||||
$fields = array_flip([
|
||||
'calle',
|
||||
'numero',
|
||||
'extra',
|
||||
'comuna'
|
||||
], 0);
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
try {
|
||||
$direccion = $this->direccionRepository->fetchByCalleAndNumeroAndExtraAndComuna($filtered_data['calle'], $filtered_data['numero'], $filtered_data['extra'], $filtered_data['comuna']);
|
||||
} catch (EmptyResult) {
|
||||
$direccion = $this->direccionRepository->create($filtered_data);
|
||||
$direccion = $this->direccionRepository->save($direccion);
|
||||
try {
|
||||
$direccion = $this->direccionRepository->create($filtered_data);
|
||||
$direccion = $this->direccionRepository->save($direccion);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
return $direccion;
|
||||
}
|
||||
|
81
app/src/Service/Venta/Reservation.php
Normal file
81
app/src/Service/Venta/Reservation.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateMalformedStringException;
|
||||
use PDOException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Exception\ServiceAction;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Reservation extends Ideal\Service\API
|
||||
{
|
||||
public function __construct(LoggerInterface $logger, protected Repository\Venta\Reservation $reservationRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getAll(null|string|array $order = null): array
|
||||
{
|
||||
try {
|
||||
return $this->reservationRepository->fetchAll($order);
|
||||
} catch (Implement\Exception\EmptyResult) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public function get(int $id): Model\Venta\Reservation
|
||||
{
|
||||
try {
|
||||
return $this->process($this->reservationRepository->fetchById($id));
|
||||
} catch (Implement\Exception\EmptyResult $exception) {
|
||||
throw new ServiceAction\Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function add(array $data): Model\Venta\Reservation
|
||||
{
|
||||
try {
|
||||
$date = new DateTimeImmutable();
|
||||
try {
|
||||
$date = new DateTimeImmutable($data['date']);
|
||||
} catch (DateMalformedStringException) {}
|
||||
return $this->process($this->reservationRepository->fetchByBuyerAndDate($data['buyer_rut'], $date));
|
||||
} catch (Implement\Exception\EmptyResult) {}
|
||||
|
||||
try {
|
||||
$reservationData = $this->reservationRepository->filterData($data);
|
||||
$reservation = $this->reservationRepository->create($reservationData);
|
||||
$this->reservationRepository->save($reservation);
|
||||
return $this->process($reservation);
|
||||
} catch (PDOException $exception) {
|
||||
throw new ServiceAction\Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
public function edit(Define\Model $model, array $new_data): Model\Venta\Reservation
|
||||
{
|
||||
try {
|
||||
return $this->process($this->reservationRepository->edit($model, $new_data));
|
||||
} catch (PDOException | Implement\Exception\EmptyResult $exception) {
|
||||
throw new ServiceAction\Update(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
public function delete(int $id): Model\Venta\Reservation
|
||||
{
|
||||
try {
|
||||
$reservation = $this->reservationRepository->fetchById($id);
|
||||
$this->reservationRepository->remove($reservation);
|
||||
return $reservation;
|
||||
} catch (PDOException | Implement\Exception\EmptyResult $exception) {
|
||||
throw new ServiceAction\Delete(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
protected function process(Define\Model $model): Model\Venta\Reservation
|
||||
{
|
||||
return $model;
|
||||
}
|
||||
}
|
@ -2,7 +2,10 @@
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateMalformedStringException;
|
||||
use PDOException;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
@ -35,16 +38,29 @@ class Subsidio
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @param array $data
|
||||
* @return Model\Venta\Subsidio
|
||||
* @throws Create
|
||||
*/
|
||||
public function add(array $data): Model\Venta\Subsidio
|
||||
{
|
||||
$fecha = new DateTimeImmutable($data['fecha']);
|
||||
$fecha = new DateTimeImmutable();
|
||||
try {
|
||||
$fecha = new DateTimeImmutable($data['fecha']);
|
||||
} catch (DateMalformedStringException) {}
|
||||
$uf = $data['uf'] ?? $this->moneyService->getUF($fecha);
|
||||
$tipoPago = $this->tipoPagoRepository->fetchByDescripcion('vale vista');
|
||||
try {
|
||||
$tipoPago = $this->tipoPagoRepository->fetchByDescripcion('vale vista');
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
$ahorro = $this->pagoService->add(['fecha' => $fecha->format('Y-m-d'), 'valor' => $this->valorService->clean($data['ahorro']) * $uf, 'uf' => $uf, 'tipo' => $tipoPago->id]);
|
||||
$subsidioPago = $this->pagoService->add(['fecha' => $fecha->format('Y-m-d'), 'valor' => $this->valorService->clean($data['subsidio']) * $uf, 'uf' => $uf, 'tipo' => $tipoPago->id]);
|
||||
$subsidio = $this->subsidioRepository->create(['pago' => $ahorro->id, 'subsidio' => $subsidioPago->id]);
|
||||
return $this->subsidioRepository->save($subsidio);
|
||||
try {
|
||||
return $this->subsidioRepository->save($subsidio);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use PDOException;
|
||||
use Incoviba\Common\Implement\Repository\Factory;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Unidad
|
||||
@ -16,9 +16,18 @@ class Unidad
|
||||
protected Precio $precioService
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param int $unidad_id
|
||||
* @return Model\Venta\Unidad
|
||||
* @throws Read
|
||||
*/
|
||||
public function getById(int $unidad_id): Model\Venta\Unidad
|
||||
{
|
||||
return $this->process($this->unidadRepository->fetchById($unidad_id));
|
||||
try {
|
||||
return $this->process($this->unidadRepository->fetchById($unidad_id));
|
||||
} catch (EmptyResult $exception) {
|
||||
throw new Read(__CLASS__, $exception);
|
||||
}
|
||||
}
|
||||
public function getByVenta(int $venta_id): array
|
||||
{
|
||||
@ -32,6 +41,10 @@ class Unidad
|
||||
{
|
||||
return array_map([$this, 'process'], $this->unidadRepository->fetchByCierre($cierre_id));
|
||||
}
|
||||
public function getByProyecto(int $proyecto_id): array
|
||||
{
|
||||
return array_map([$this, 'process'], $this->unidadRepository->fetchByProyecto($proyecto_id));
|
||||
}
|
||||
public function getDisponiblesByProyecto(int $proyecto_id): array
|
||||
{
|
||||
return $this->unidadRepository->fetchDisponiblesByProyecto($proyecto_id);
|
||||
@ -63,6 +76,10 @@ class Unidad
|
||||
$unidad->precios = $this->precioService->getByUnidad($unidad->id);
|
||||
$unidad->currentPrecio = $this->precioService->getVigenteByUnidad($unidad->id);
|
||||
} catch (Read) {}
|
||||
$unidad->addFactory('sold', (new Factory())
|
||||
->setCallable([$this->unidadRepository, 'fetchSoldByUnidad'])
|
||||
->setArgs(['unidad_id' => $unidad->id])
|
||||
);
|
||||
return $unidad;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user