Compare commits
5 Commits
9310d65d77
...
develop
Author | SHA1 | Date | |
---|---|---|---|
4e4c0b7648 | |||
47679cd4e4 | |||
0f8db5a3f8 | |||
c38e89d3f1 | |||
307f2ac7d7 |
0
app/bin/console
Normal file → Executable file
0
app/bin/console
Normal file → Executable file
0
app/bin/integration_tests
Normal file → Executable file
0
app/bin/integration_tests
Normal file → Executable file
0
app/bin/performance_tests
Normal file → Executable file
0
app/bin/performance_tests
Normal file → Executable file
0
app/bin/unit_tests
Normal file → Executable file
0
app/bin/unit_tests
Normal file → Executable file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class ChangeTelefonoSizeInPropietario extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change(): void
|
||||
{
|
||||
$this->table('propietario')
|
||||
->changeColumn('telefono', 'biginteger', ['null' => true, 'signed' => false, 'default' => null])
|
||||
->update();
|
||||
}
|
||||
}
|
@ -156,7 +156,7 @@
|
||||
<script>
|
||||
const regiones = [
|
||||
@foreach ($regiones as $region)
|
||||
'<div class="item" data-value="{{$region->id}}">{{$region->descripcion}}</div>',
|
||||
'<div class="item" data-value="{{$region->id}}">{{$region->numeral}} - {{$region->descripcion}}</div>',
|
||||
@endforeach
|
||||
]
|
||||
|
||||
|
@ -54,22 +54,23 @@
|
||||
}
|
||||
$(document).ready(() => {
|
||||
const url = '{{$urls->api}}/ventas/pago/{{$venta->resciliacion()->id}}'
|
||||
let old = new Date({{$venta->resciliacion()?->fecha->format('Y') ?? date('Y')}},
|
||||
{{$venta->resciliacion()?->fecha->format('n') ?? date('n')}}-1, {{$venta->resciliacion()?->fecha->format('j') ?? date('j')}})
|
||||
let old = new Date(Date.parse('{{$venta->resciliacion()?->fecha->format('Y-m-d') ?? $venta->currentEstado()->fecha->format('Y-m-d') ?? $venta->fecha->format('Y-m-d')}}') + 24 * 60 * 60 * 1000)
|
||||
calendar_date_options['initialDate'] = old
|
||||
calendar_date_options['onChange'] = function(date, text, mode) {
|
||||
if (date.getTime() === old.getTime()) {
|
||||
return
|
||||
}
|
||||
const body = new FormData()
|
||||
body.set('fecha', date.toISOString())
|
||||
const fecha = new Date(date.getTime())
|
||||
fecha.setDate(fecha.getDate() - 1)
|
||||
body.set('fecha', fecha.toISOString())
|
||||
$('#loading-spinner-fecha').show()
|
||||
APIClient.fetch(url, {method: 'post', body}).then(response => {
|
||||
$('#loading-spinner-fecha').hide()
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
old = date
|
||||
old = new Date(date.getTime())
|
||||
alertResponse('Fecha cambiada correctamente.')
|
||||
})
|
||||
}
|
||||
|
@ -6,15 +6,26 @@
|
||||
|
||||
@section('venta_content')
|
||||
<div class="ui list">
|
||||
<div class="item">
|
||||
<div class="header">Valor Pagado</div>
|
||||
<div class="content">
|
||||
{{$format->pesos($venta->formaPago()->pie->pagado('pesos'))}}
|
||||
<div class="ui left pointing small label">
|
||||
{{$format->number($venta->formaPago()->pie->pagado() / $venta->valor * 100)}}% de la venta
|
||||
@if (isset($venta->formaPago()->pie))
|
||||
<div class="item">
|
||||
<div class="header">Valor Pagado</div>
|
||||
<div class="content">
|
||||
{{$format->pesos($venta->formaPago()->pie->pagado('pesos'))}}
|
||||
<div class="ui left pointing small label">
|
||||
{{$format->number($venta->formaPago()->pie->pagado() / $venta->valor * 100)}}% de la venta
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="item">
|
||||
<div class="ui compact warning message">
|
||||
<div class="content">
|
||||
<i class="exclamation triangle icon"></i>
|
||||
No tiene valor pagado
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="item">
|
||||
<div class="header">
|
||||
Multa Estandar
|
||||
|
@ -116,7 +116,18 @@ return [
|
||||
->registerSub($container->get(Incoviba\Service\Contabilidad\Cartola\BCI\Mes::class));
|
||||
},
|
||||
'TokuClient' => function(ContainerInterface $container) {
|
||||
$logger = $container->get('externalLogger');
|
||||
$stack = GuzzleHttp\HandlerStack::create();
|
||||
$stack->push(GuzzleHttp\Middleware::mapRequest(function(Psr\Http\Message\RequestInterface $request) use ($logger) {
|
||||
$logger->info('Toku Request', [
|
||||
'method' => $request->getMethod(),
|
||||
'uri' => (string) $request->getUri(),
|
||||
'headers' => $request->getHeaders(),
|
||||
'body' => $request->getBody()->getContents(),
|
||||
]);
|
||||
}));
|
||||
return new GuzzleHttp\Client([
|
||||
'handler' => $stack,
|
||||
'base_uri' => $container->get('TOKU_URL'),
|
||||
'headers' => [
|
||||
'x-api-key' => $container->get('TOKU_TOKEN'),
|
||||
|
@ -4,6 +4,9 @@ namespace Incoviba\Controller;
|
||||
use Incoviba\Common\Alias\View;
|
||||
use Incoviba\Common\Implement\Exception\EmptyRedis;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Exception\ServiceAction\Create;
|
||||
use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Exception\ServiceAction\Update;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
@ -142,9 +145,24 @@ class Ventas
|
||||
return $view->render($response, 'ventas.desistir', compact('venta'));
|
||||
}
|
||||
public function desistida(ServerRequestInterface $request, ResponseInterface $response, Service\Venta $ventaService,
|
||||
Service\Venta\Pago $pagoService,
|
||||
View $view, int $venta_id): ResponseInterface
|
||||
{
|
||||
$venta = $ventaService->getById($venta_id);
|
||||
try {
|
||||
$venta = $ventaService->getById($venta_id);
|
||||
} catch (Read) {
|
||||
return $view->render($response->withStatus(404), 'not_found');
|
||||
}
|
||||
if ($venta->resciliacion() === null) {
|
||||
$pagoData = [
|
||||
'fecha' => $venta->currentEstado()->fecha->format('Y-m-d'),
|
||||
'valor' => 0
|
||||
];
|
||||
try {
|
||||
$pago = $pagoService->add($pagoData);
|
||||
$venta = $ventaService->edit($venta, ['resciliacion' => $pago->id]);
|
||||
} catch (Create | Update) {}
|
||||
}
|
||||
return $view->render($response, 'ventas.desistida', compact('venta'));
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ class Queue extends Ideal\Service
|
||||
try {
|
||||
if (!$worker->execute($job)) {
|
||||
$this->logger->debug("Could not execute job {$job->id}");
|
||||
$job->retries++;
|
||||
$this->jobService->update($job);
|
||||
return false;
|
||||
}
|
||||
if (!$this->jobService->execute($job)) {
|
||||
@ -67,6 +69,12 @@ class Queue extends Ideal\Service
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
$this->logger->warning("Could not run job {$job->id}", ['exception' => $exception]);
|
||||
$job->retries++;
|
||||
try {
|
||||
$this->jobService->update($job);
|
||||
} catch (Update $exception) {
|
||||
$this->logger->error($exception->getMessage(), ['job' => $job, 'exception' => $exception]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -4,7 +4,7 @@ namespace Incoviba\Service;
|
||||
use DateTimeInterface;
|
||||
use DateTimeImmutable;
|
||||
use DateMalformedStringException;
|
||||
use function PHPUnit\Framework\countOf;
|
||||
use Incoviba\Service\Valor\Phone;
|
||||
|
||||
class Valor
|
||||
{
|
||||
@ -40,6 +40,14 @@ class Valor
|
||||
}
|
||||
return $value / $this->ufService->get($date);
|
||||
}
|
||||
public function phone(): Phone
|
||||
{
|
||||
return new Phone();
|
||||
}
|
||||
public function telefono(): Phone
|
||||
{
|
||||
return $this->phone();
|
||||
}
|
||||
|
||||
protected function getDateTime(null|string|DateTimeInterface $date): DateTimeInterface
|
||||
{
|
||||
|
28
app/src/Service/Valor/Phone.php
Normal file
28
app/src/Service/Valor/Phone.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Valor;
|
||||
|
||||
class Phone
|
||||
{
|
||||
public function toDatabase(?string $phone): ?int
|
||||
{
|
||||
if ($phone === null) {
|
||||
return null;
|
||||
}
|
||||
return (int) str_replace([' ', '+'], '', $phone) ?? null;
|
||||
}
|
||||
public function toDisplay(?int $phone): ?string
|
||||
{
|
||||
if ($phone === null) {
|
||||
return null;
|
||||
}
|
||||
$parts = preg_split('/(?=<country>\d{2})?(?=<area>\d)(?=<first>\d{4})(?=<last>\d{4})/', $phone);
|
||||
$output = [];
|
||||
if (array_key_exists('country', $parts)) {
|
||||
$output [] = "+{$parts[0]}";
|
||||
}
|
||||
$output [] = $parts[1] ?? '';
|
||||
$output [] = $parts[2] ?? '';
|
||||
$output [] = $parts[3] ?? '';
|
||||
return implode(' ', $output);
|
||||
}
|
||||
}
|
@ -1,22 +1,24 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use PDOException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
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;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service\Valor;
|
||||
|
||||
class Propietario extends Service
|
||||
{
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
protected Repository\Venta\Propietario $propietarioRepository,
|
||||
protected Repository\Direccion $direccionRepository
|
||||
protected Repository\Direccion $direccionRepository,
|
||||
protected Valor $valorService
|
||||
) {
|
||||
parent::__construct($logger);
|
||||
}
|
||||
@ -49,6 +51,9 @@ class Propietario extends Service
|
||||
$data['direccion'] = $direccion->id;
|
||||
}
|
||||
$filteredData = $this->propietarioRepository->filterData($data);
|
||||
if (array_key_exists('telefono', $filteredData)) {
|
||||
$filteredData['telefono'] = $this->valorService->telefono()->toDatabase($filteredData['telefono']);
|
||||
}
|
||||
try {
|
||||
return $this->propietarioRepository->edit($propietario, $filteredData);
|
||||
} catch (PDOException | EmptyResult $exception) {
|
||||
@ -85,6 +90,10 @@ class Propietario extends Service
|
||||
]);
|
||||
$filtered_data = array_intersect_key($data, $fields);
|
||||
|
||||
if (array_key_exists('telefono', $filtered_data)) {
|
||||
$filtered_data['telefono'] = $this->valorService->telefono()->toDatabase($filtered_data['telefono']);
|
||||
}
|
||||
|
||||
try {
|
||||
$propietario = $this->propietarioRepository->fetchById($data['rut']);
|
||||
$edits = [];
|
||||
@ -95,6 +104,7 @@ class Propietario extends Service
|
||||
} catch (EmptyResult) {
|
||||
try {
|
||||
$propietario = $this->propietarioRepository->create($filtered_data);
|
||||
$this->logger->info('Propietario', ['propietario' => $propietario]);
|
||||
$propietario = $this->propietarioRepository->save($propietario);
|
||||
} catch (PDOException $exception) {
|
||||
throw new Create(__CLASS__, $exception);
|
||||
|
@ -42,7 +42,14 @@ class Queue extends Command
|
||||
}
|
||||
|
||||
$io->title("[{$now->format('Y-m-d H:i:s e')}] Running Queue...");
|
||||
return $this->runJob();
|
||||
$results = [];
|
||||
for ($i = 0; $i < $this->batchSize; $i++) {
|
||||
if ($this->jobService->getPending() === 0) {
|
||||
break;
|
||||
}
|
||||
$results []= $this->runJob();
|
||||
}
|
||||
return count(array_filter($results, fn ($result) => $result === self::FAILURE)) === 0 ? self::SUCCESS : self::FAILURE;
|
||||
}
|
||||
|
||||
protected array $sections;
|
||||
|
@ -2,13 +2,14 @@
|
||||
namespace Incoviba\Command\Queue;
|
||||
|
||||
use Throwable;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console;
|
||||
use Incoviba\Service;
|
||||
|
||||
#[Console\Attribute\AsCommand(name: 'queue:push', description: 'Push a job to the queue')]
|
||||
class Push extends Console\Command\Command
|
||||
{
|
||||
public function __construct(protected Service\Job $jobService, ?string $name = null)
|
||||
public function __construct(protected LoggerInterface $logger, protected Service\Job $jobService, ?string $name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
}
|
||||
@ -16,7 +17,7 @@ class Push extends Console\Command\Command
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->addOption('configurations', 'c', Console\Input\InputOption::VALUE_REQUIRED | Console\Input\InputOption::VALUE_IS_ARRAY, 'Job configuration options array, each job configuration must be in valid JSON format');
|
||||
$this->addOption('file', 'f', Console\Input\InputOption::VALUE_REQUIRED, 'Path to jobs configuration file with JSON array');
|
||||
$this->addOption('files', 'f', Console\Input\InputOption::VALUE_REQUIRED | Console\Input\InputOption::VALUE_IS_ARRAY, 'Paths to jobs configurations files with JSON array content');
|
||||
}
|
||||
|
||||
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output): int
|
||||
@ -49,19 +50,72 @@ class Push extends Console\Command\Command
|
||||
}
|
||||
|
||||
protected function getConfigurations(Console\Input\InputInterface $input): array
|
||||
{
|
||||
return [
|
||||
...$this->getFilesConfigurations($input),
|
||||
...$this->getOptionConfigurations($input),
|
||||
];
|
||||
}
|
||||
protected function getFilesConfigurations(Console\Input\InputInterface $input): array
|
||||
{
|
||||
$configurations = [];
|
||||
$filePath = $input->getOption('file');
|
||||
if ($filePath !== null and file_exists($filePath)) {
|
||||
$json = file_get_contents($filePath);
|
||||
if (json_validate($json)) {
|
||||
$configurations = array_map(fn($configArray) => json_encode($configArray), json_decode($json, true));
|
||||
}
|
||||
$files = $input->getOption('files');
|
||||
if ($files === null) {
|
||||
return $configurations;
|
||||
}
|
||||
$configOptions = $input->getOption('configurations');
|
||||
if ($configOptions !== null) {
|
||||
$configurations = array_merge($configurations, array_filter($configOptions, fn($config) => json_validate($config)));
|
||||
foreach ($files as $filePath) {
|
||||
if (!file_exists($filePath)) {
|
||||
continue;
|
||||
}
|
||||
$configurations = array_merge($configurations, $this->getFileConfigurations($filePath));
|
||||
}
|
||||
return $configurations;
|
||||
}
|
||||
protected function getFileConfigurations(string $filePath): array
|
||||
{
|
||||
$configurations = [];
|
||||
if (!file_exists($filePath)) {
|
||||
return $configurations;
|
||||
}
|
||||
$json = file_get_contents($filePath);
|
||||
if (!json_validate($json)) {
|
||||
return $configurations;
|
||||
}
|
||||
$tmp = json_decode($json, true);
|
||||
foreach ($tmp as $config) {
|
||||
try {
|
||||
$configurations []= $this->processConfiguration(json_encode($config));
|
||||
} catch (Throwable $exception) {
|
||||
$this->logger->warning($exception->getMessage(), ['exception' => $exception, 'config' => $config]);
|
||||
}
|
||||
}
|
||||
return $configurations;
|
||||
}
|
||||
protected function getOptionConfigurations(Console\Input\InputInterface $input): array
|
||||
{
|
||||
$configurations = [];
|
||||
$configOptions = $input->getOption('configurations');
|
||||
if ($configOptions === null) {
|
||||
return $configurations;
|
||||
}
|
||||
foreach ($configOptions as $config) {
|
||||
try {
|
||||
$configurations []= $this->processConfiguration($config);
|
||||
} catch (Throwable $exception) {
|
||||
$this->logger->warning($exception->getMessage(), ['exception' => $exception, 'config' => $config]);
|
||||
}
|
||||
}
|
||||
return $configurations;
|
||||
}
|
||||
protected function processConfiguration(string $configuration): string
|
||||
{
|
||||
$json = json_decode($configuration, true);
|
||||
if (!array_key_exists('type', $json) and !array_key_exists('configuration', $json)) {
|
||||
throw new Console\Exception\InvalidArgumentException('Missing type or configuration key in JSON');
|
||||
}
|
||||
if (array_key_exists('type', $json)) {
|
||||
return json_encode($json);
|
||||
}
|
||||
return json_encode($json['configuration']);
|
||||
}
|
||||
}
|
||||
|
0
cli/start_command
Normal file → Executable file
0
cli/start_command
Normal file → Executable file
Reference in New Issue
Block a user