Correcciones

This commit is contained in:
Juan Pablo Vial
2025-03-03 21:41:43 -03:00
parent 5f69069aa0
commit aeeca65d94
9 changed files with 122 additions and 43 deletions

View File

@ -204,9 +204,11 @@ abstract class Repository implements Define\Repository
{
try {
$result = $this->connection->execute($query, $data)->fetch(PDO::FETCH_ASSOC);
if ($result === false) {
throw new EmptyResult($query);
}
} catch (PDOException $exception) {
throw new EmptyResult($query, $exception);
}
return $this->load($result);
}

View File

@ -2,6 +2,7 @@
namespace Incoviba\Common\Implement\Repository\Mapper;
use DateTimeImmutable;
use DateMalformedStringException;
use Incoviba\Common\Implement\Repository\Mapper;
class DateTime extends Mapper
@ -9,7 +10,17 @@ class DateTime extends Mapper
public function __construct(string $column, ?string $property = null)
{
$this->setFunction(function($data) use ($column) {
if (!isset($data[$column])) {
return null;
}
if (is_a($data[$column], DateTimeImmutable::class)) {
return $data[$column];
}
try {
return new DateTimeImmutable($data[$column] ?? '');
} catch (DateMalformedStringException) {
return new DateTimeImmutable();
}
});
if ($property !== null) {
$this->setProperty($property);

View File

@ -2,23 +2,27 @@
use Psr\Container\ContainerInterface;
return [
Monolog\Formatter\LineFormatter::class => function(ContainerInterface $container) {
return (new Monolog\Formatter\LineFormatter(null, null, false, false, true))
->setBasePath('/code/');
},
Psr\Log\LoggerInterface::class => function(ContainerInterface $container) {
return new Monolog\Logger('incoviba', [
new Monolog\Handler\FilterHandler(
(new Monolog\Handler\RotatingFileHandler('/logs/error.log', 10))
->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
->setFormatter($container->get(Monolog\Formatter\LineFormatter::class)),
Monolog\Level::Error,
Monolog\Level::Error
),
new Monolog\Handler\FilterHandler(
(new Monolog\Handler\RotatingFileHandler('/logs/critical.log', 10))
->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true)),
->setFormatter($container->get(Monolog\Formatter\LineFormatter::class)),
Monolog\Level::Critical
),
new Monolog\Handler\FilterHandler(
($container->has('ENVIRONMENT') and $container->get('ENVIRONMENT') === 'development')
? (new Monolog\Handler\RotatingFileHandler('/logs/debug.log', 10))
->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true))
->setFormatter($container->get(Monolog\Formatter\LineFormatter::class))
: new Monolog\Handler\RedisHandler($container->get(Predis\ClientInterface::class), 'logs:notices'),
Monolog\Level::Debug,
Monolog\Level::Info
@ -26,7 +30,7 @@ return [
new Monolog\Handler\FilterHandler(
($container->has('ENVIRONMENT') and $container->get('ENVIRONMENT') === 'development')
? (new Monolog\Handler\RotatingFileHandler('/logs/notices.log', 10))
->setFormatter(new Monolog\Formatter\LineFormatter(null, null, false, false, true))
->setFormatter($container->get(Monolog\Formatter\LineFormatter::class))
: (new Incoviba\Common\Implement\Log\MySQLHandler($container->get(Incoviba\Common\Define\Connection::class)))
->setFormatter(new Incoviba\Common\Implement\Log\PDOFormatter()),
Monolog\Level::Notice,

View File

@ -16,9 +16,10 @@ trait withJson
return [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'file' => $this->parseFilename($exception->getFile()),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString()
'trace' => $this->parseStack($exception->getTraceAsString()),
'previous' => ($exception->getPrevious() instanceof Throwable) ? $this->parseError($exception->getPrevious()) : ''
];
}
public function withError(ResponseInterface $response, Throwable $exception): ResponseInterface
@ -37,4 +38,46 @@ trait withJson
return $response;
}
protected function parseFilename(string $filename): string
{
return str_replace('/code/', '', $filename);
}
protected function parseStack(string|array $stack): array
{
if (is_string($stack)) {
$stack = explode(PHP_EOL, $stack);
}
$output = [];
foreach ($stack as $line) {
$index = substr($line, 1, strpos($line, ' ') - 1);
$content = substr($line, strpos($line, ' ') + 1);
if (str_contains($line, '{main}')) {
$output [] = [
'stack' => $index,
'message' => $content
];
continue;
}
if (str_starts_with($content, '[internal function]')) {
$content = substr($content, strlen('[internal function]: '));
$output [] = [
'stack' => $index,
'type' => 'internal function',
'message' => $content
];
continue;
}
$fileData = substr($content, 0, strpos($content, ' '));
$file = substr($fileData, 0, strrpos($fileData, '('));
$fileLine = (int) substr($fileData, strrpos($fileData, '(') + 1, -2);
$error = substr($content, strlen($fileData) + 1);
$output []= [
'stack' => $index,
'file' => $this->parseFilename($file),
'line' => $fileLine,
'error' => $error
];
}
return $output;
}
}

View File

@ -13,17 +13,21 @@ class Contract extends Common\Ideal\Model
public function states(): array
{
if (!isset($this->states)) {
if (!isset($this->states) or count($this->states) === 0) {
$this->states = $this->runFactory('states');
}
return $this->states;
}
protected Contract\State $current;
public function currentState(): Contract\State
protected ?Contract\State $current;
public function currentState(): ?Contract\State
{
if (!isset($this->current)) {
try {
$this->current = last($this->states());
} catch (\TypeError $error) {
$this->current = null;
}
}
return $this->current;
}

View File

@ -9,7 +9,7 @@ class State extends Common\Ideal\Model
{
public Model\Proyecto\Broker\Contract $contract;
public DateTimeInterface $date;
public int $type;
public State\Type $type;
protected function jsonComplement(): array
{
@ -17,8 +17,8 @@ class State extends Common\Ideal\Model
'contract_id' => $this->contract->id,
'date' => $this->date->format('Y-m-d'),
'type' => [
'id' => $this->type,
'description' => State\Type::name($this->type)
'id' => $this->type->value,
'description' => $this->type->name
]
];
}

View File

@ -27,10 +27,10 @@ class Contract extends Common\Ideal\Repository
return $this->brokerRepository->fetchById($data['broker_rut']);
})
)
->register('proyecto_id', (new Common\Implement\Repository\Mapper())
->setProperty('proyecto')
->register('project_id', (new Common\Implement\Repository\Mapper())
->setProperty('project')
->setFunction(function($data) {
return $this->proyectoRepository->fetchById($data['proyecto_id']);
return $this->proyectoRepository->fetchById($data['project_id']);
})
);
return $this->parseData(new Model\Proyecto\Broker\Contract(), $data, $map);
@ -38,8 +38,8 @@ class Contract extends Common\Ideal\Repository
public function save(Common\Define\Model $model): Model\Proyecto\Broker\Contract
{
$model->id = $this->saveNew(
['broker_rut', 'proyecto_id', 'commission'],
[$model->broker->rut, $model->proyecto->id, $model->commission]);
['broker_rut', 'project_id', 'commission'],
[$model->broker->rut, $model->project->id, $model->commission]);
return $model;
}
@ -51,7 +51,7 @@ class Contract extends Common\Ideal\Repository
*/
public function edit(Common\Define\Model $model, array $new_data): Model\Proyecto\Broker\Contract
{
return $this->update($model, ['broker_rut', 'proyecto_id', 'commission'], $new_data);
return $this->update($model, ['broker_rut', 'project_id', 'commission'], $new_data);
}
/**
@ -69,17 +69,17 @@ class Contract extends Common\Ideal\Repository
}
/**
* @param int $proyecto_id
* @param int $projectId
* @return array
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchByProject(int $proyecto_id): array
public function fetchByProject(int $projectId): array
{
$query = $this->connection->getQueryBuilder()
->select()
->from($this->getTable())
->where('proyecto_id = :proyecto_id');
return $this->fetchMany($query, ['proyecto_id' => $proyecto_id]);
->where('project_id = :project_id');
return $this->fetchMany($query, ['project_id' => $projectId]);
}
/**
@ -98,38 +98,38 @@ class Contract extends Common\Ideal\Repository
}
/**
* @param int $proyecto_id
* @param int $projectId
* @return array
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchActiveByProject(int $proyecto_id): array
public function fetchActiveByProject(int $projectId): array
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined($this->statusJoin())
->where('a.proyecto_id = :proyecto_id AND bcs.state = :state');
return $this->fetchMany($query, ['proyecto_id' => $proyecto_id, 'state' => Model\Proyecto\Broker\Contract\Type::ACTIVE]);
return $this->fetchMany($query, ['proyecto_id' => $projectId, 'state' => Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value]);
}
/**
* @param int $proyecto_id
* @param int $projectId
* @param int $brokerRut
* @return Model\Proyecto\Broker\Contract
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchActiveByProjectAndBroker(int $proyecto_id, int $brokerRut): Model\Proyecto\Broker\Contract
public function fetchActiveByProjectAndBroker(int $projectId, int $brokerRut): Model\Proyecto\Broker\Contract
{
$query = $this->connection->getQueryBuilder()
->select('a.*')
->from("{$this->getTable()} a")
->joined($this->statusJoin())
->where('a.proyecto_id = :proyecto_id AND a.broker_rut = :broker_rut AND bcs.state = :state');
return $this->fetchOne($query, ['proyecto_id' => $proyecto_id, 'broker_rut' => $brokerRut, 'state' => Model\Proyecto\Broker\Contract\Type::ACTIVE]);
->where('a.project_id = :project_id AND a.broker_rut = :broker_rut AND bcs.type = :state');
return $this->fetchOne($query, ['project_id' => $projectId, 'broker_rut' => $brokerRut, 'state' => Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value]);
}
protected function statusJoin(): string
{
return 'INNER JOIN (SELECT bcs1.* FROM broker_contract_states bcs1 INNER JOIN (SELECT MAX(id) AS id, contract_id FROM broker_contract_states GROUP BY contract_id) bcs0 ON bcs0.id = bcs1.id) bcs ON bcs.contract = a.id';
return 'INNER JOIN (SELECT bcs1.* FROM broker_contract_states bcs1 INNER JOIN (SELECT MAX(id) AS id, contract_id FROM broker_contract_states GROUP BY contract_id) bcs0 ON bcs0.id = bcs1.id) bcs ON bcs.contract_id = a.id';
}
}

View File

@ -14,23 +14,27 @@ class State extends Common\Ideal\Repository
public function getTable(): string
{
return 'brokers_contract_states';
return 'broker_contract_states';
}
public function create(?array $data = null): Model\Proyecto\Broker\Contract\State
{
$map = (new Common\Implement\Repository\MapperParser(['type']))
$map = (new Common\Implement\Repository\MapperParser())
->register('contract_id', (new Common\Implement\Repository\Mapper())
->setProperty('contract')
->setFunction(function($data) {
return $this->contractRepository->fetchById($data['contract_id']);
}))
->register('type', (new Common\Implement\Repository\Mapper())
->setFunction(function($data) {
return Model\Proyecto\Broker\Contract\State\Type::from($data['type']);
}))
->register('date', new Common\Implement\Repository\Mapper\DateTime('date'));
return $this->parseData(new Model\Proyecto\Broker\Contract\State(), $data, $map);
}
public function save(Common\Define\Model $model): Model\Proyecto\Broker\Contract\State
{
$model->id = $this->saveNew(['contract_id', 'date', 'type'], [$model->contract->id, $model->date->format('Y-m-d'), $model->type]);
$model->id = $this->saveNew(['contract_id', 'date', 'type'], [$model->contract->id, $model->date->format('Y-m-d'), $model->type->value]);
return $model;
}
public function edit(Common\Define\Model $model, array $new_data): Model\Proyecto\Broker\Contract\State
@ -38,6 +42,11 @@ class State extends Common\Ideal\Repository
return $this->update($model, ['contract_id', 'date', 'type'], $new_data);
}
/**
* @param int $contract_id
* @return array
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchByContract(int $contract_id): array
{
$query = $this->connection->getQueryBuilder()
@ -46,6 +55,12 @@ class State extends Common\Ideal\Repository
->where('contract_id = :contract_id');
return $this->fetchMany($query, ['contract_id' => $contract_id]);
}
/**
* @param int $contract_id
* @return Model\Proyecto\Broker\Contract\State
* @throws Common\Implement\Exception\EmptyResult
*/
public function fetchActiveByContract(int $contract_id): Model\Proyecto\Broker\Contract\State
{
$query = $this->connection->getQueryBuilder()

View File

@ -32,7 +32,7 @@ class Contract extends Ideal\Service
public function getByBroker(int $broker_rut): array
{
try {
return array_map([$this, 'broker'], $this->contractRepository->fetchByBroker($broker_rut));
return array_map([$this, 'process'], $this->contractRepository->fetchByBroker($broker_rut));
} catch (Implement\Exception\EmptyResult $exception) {
throw new ServiceAction\Read(__CLASS__, $exception);
}
@ -56,14 +56,14 @@ class Contract extends Ideal\Service
public function add(array $data): Model\Proyecto\Broker\Contract
{
try {
return $this->process($this->contractRepository->fetchActiveByProjectAndBroker($data['proyecto_id'], $data['broker_rut']));
return $this->process($this->contractRepository->fetchActiveByProjectAndBroker($data['project_id'], $data['broker_rut']));
} catch (Implement\Exception\EmptyResult) {}
try {
$filteredData = $this->contractRepository->filterData($data);
$contract = $this->contractRepository->create($filteredData);
$contract = $this->contractRepository->save($contract);
$type = Model\Proyecto\Broker\Contract\State\Type::ACTIVE;
$type = Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value;
$date = new DateTimeImmutable();
if (isset($data['date'])) {
try {
@ -125,9 +125,9 @@ class Contract extends Ideal\Service
$contract->addFactory('states', (new Implement\Repository\Factory())
->setCallable([$this->stateRepository, 'fetchByContract'])
->setArgs(['contract_id' => $contract->id]));
$contract->addFactory('currentState', (new Implement\Repository\Factory())
/*$contract->addFactory('currentState', (new Implement\Repository\Factory())
->setCallable([$this->stateRepository, 'fetchActiveByContract'])
->setArgs(['contract_id' => $contract->id]));
->setArgs(['contract_id' => $contract->id]));*/
return $contract;
}
}