From 27f7d1d57935e88ca2fe1c33a9148e6a70aae17a Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Tue, 12 Aug 2025 19:17:32 -0400 Subject: [PATCH] Mostrar reservas --- app/common/Implement/Repository/Factory.php | 12 +- app/resources/routes/api/personas.php | 7 + app/resources/routes/api/proyectos.php | 1 + .../views/ventas/reservations.blade.php | 236 +++--- .../ventas/reservations/add_modal.blade.php | 733 ++++++++++++++++++ app/src/Controller/API/Personas.php | 34 + app/src/Controller/API/Proyectos.php | 15 +- app/src/Controller/Ventas/Reservations.php | 10 +- app/src/Model/Persona.php | 7 +- app/src/Repository/Persona/Datos.php | 3 + app/src/Service/Persona.php | 8 +- app/src/Service/Venta/Promotion.php | 14 + 12 files changed, 967 insertions(+), 113 deletions(-) create mode 100644 app/resources/routes/api/personas.php create mode 100644 app/resources/views/ventas/reservations/add_modal.blade.php create mode 100644 app/src/Controller/API/Personas.php diff --git a/app/common/Implement/Repository/Factory.php b/app/common/Implement/Repository/Factory.php index 00fd799..10ec520 100644 --- a/app/common/Implement/Repository/Factory.php +++ b/app/common/Implement/Repository/Factory.php @@ -2,7 +2,9 @@ namespace Incoviba\Common\Implement\Repository; use Closure; +use Exception; use Incoviba\Common\Define; +use Incoviba\Common\Implement\Exception\EmptyResult; class Factory implements Define\Repository\Factory { @@ -20,8 +22,16 @@ class Factory implements Define\Repository\Factory return $this; } + /** + * @return mixed + * @throws EmptyResult + */ public function run(): mixed { - return call_user_func_array($this->callable, $this->args); + try { + return call_user_func_array($this->callable, $this->args); + } catch (Exception $exception) { + throw new EmptyResult($exception->getMessage(), $exception); + } } } diff --git a/app/resources/routes/api/personas.php b/app/resources/routes/api/personas.php new file mode 100644 index 0000000..b01069c --- /dev/null +++ b/app/resources/routes/api/personas.php @@ -0,0 +1,7 @@ +group('/personas', function($app) {}); +$app->group('/persona/{rut}', function($app) { + $app->get('[/]', [Personas::class, 'get']); +}); diff --git a/app/resources/routes/api/proyectos.php b/app/resources/routes/api/proyectos.php index 15d0445..5ff5f90 100644 --- a/app/resources/routes/api/proyectos.php +++ b/app/resources/routes/api/proyectos.php @@ -30,4 +30,5 @@ $app->group('/proyecto/{proyecto_id}', function($app) { $app->post('/edit[/]', [Proyectos::class, 'terreno']); }); $app->get('/brokers', [Proyectos::class, 'brokers']); + $app->get('/promotions', [Proyectos::class, 'promotions']); }); diff --git a/app/resources/views/ventas/reservations.blade.php b/app/resources/views/ventas/reservations.blade.php index 3a5eddb..2a0a4a4 100644 --- a/app/resources/views/ventas/reservations.blade.php +++ b/app/resources/views/ventas/reservations.blade.php @@ -24,8 +24,14 @@ @endif -

-
+
+
+

+
+
+
+
+
@@ -94,6 +100,8 @@
+ + @include('ventas.reservations.add_modal') @endsection @push('page_styles') @@ -134,19 +142,20 @@ event.preventDefault() const project_id = event.currentTarget.dataset.id - reservations.show().results() + reservations.show.results() if (project_id === this.current_project) { this.hide() this.title_component.innerHTML = event.currentTarget.innerHTML - reservations.action().reservations() + reservations.action.reservations() return } this.current_project = project_id - reservations.get().reservations(project_id) + reservations.get.reservations(project_id) + reservations.components.modals.add.load(project_id) this.hide() this.title_component.innerHTML = event.currentTarget.innerHTML @@ -196,7 +205,7 @@ watch() { Object.entries(this.buttons).forEach(([key, value]) => { const name = key.replace('_button', '') - value.addEventListener('click', reservations.action()[name].bind(reservations)) + value.addEventListener('click', this.action[name].bind(this)) }) } hide() { @@ -207,6 +216,24 @@ this.buttons.up.style.display = 'none' this.buttons.reset.style.display = 'none' } + + action = { + reset: event => { + event.preventDefault() + reservations.action.reset(event) + return false + }, + up: event => { + event.preventDefault() + reservations.action.up(event) + return false + }, + add: event => { + event.preventDefault() + reservations.action.add(event) + return false + } + } } class Reservations { display = { @@ -375,119 +402,114 @@ active: null, pending: null, rejected: null + }, + modals: { + add: null } }, display: { loader: '', results: '', }, - get() { - return { - send: (project_id, url_segment, component) => { - const url = `/api/ventas/reservations/project/${project_id}/${url_segment}` - return APIClient.fetch(url).then(response => response.json()).then(json => { - if (json.reservations.length === 0) { - component.empty() - return - } - component.set().reservations(json.reservations).draw() - }) - }, - active: project_id => { - return this.get().send(project_id, 'active', this.components.reservations.active) - /*const url = `/ventas/reservations/project/${project_id}/active` - return APIClient.fetch(url).then(json => { - if (json.reservations.length === 0) { - return - } - this.components.reservations.active.set().reservations(json.reservations).draw() - })*/ - }, - pending: project_id => { - return this.get().send(project_id, 'pending', this.components.reservations.pending) - /*const url = `/ventas/reservations/project/${project_id}/pending` - return APIClient.fetch(url).then(json => { - if (json.reservations.length === 0) { - return - } - this.components.reservations.pending.set().reservations(json.reservations).draw() - })*/ - }, - rejected: project_id => { - return this.get().send(project_id, 'rejected', this.components.reservations.rejected) - /*const url = `/ventas/reservations/project/${project_id}/rejected` - return APIClient.fetch(url).then(json => { - if (json.reservations.length === 0) { - return - } - this.components.reservations.rejected.set().reservations(json.reservations).draw() - })*/ - }, - reservations: project_id => { - this.loading().show() + get: { + send: (project_id, url_segment, component) => { + const url = `/api/ventas/reservations/project/${project_id}/${url_segment}` + return APIClient.fetch(url).then(response => response.json()).then(json => { + if (json.reservations.length === 0) { + component.empty() + return + } + component.set().reservations(json.reservations).draw() + }) + }, + active: project_id => { + return reservations.get.send(project_id, 'active', reservations.components.reservations.active) + /*const url = `/ventas/reservations/project/${project_id}/active` + return APIClient.fetch(url).then(json => { + if (json.reservations.length === 0) { + return + } + this.components.reservations.active.set().reservations(json.reservations).draw() + })*/ + }, + pending: project_id => { + return reservations.get.send(project_id, 'pending', reservations.components.reservations.pending) + /*const url = `/ventas/reservations/project/${project_id}/pending` + return APIClient.fetch(url).then(json => { + if (json.reservations.length === 0) { + return + } + this.components.reservations.pending.set().reservations(json.reservations).draw() + })*/ + }, + rejected: project_id => { + return reservations.get.send(project_id, 'rejected', reservations.components.reservations.rejected) + /*const url = `/ventas/reservations/project/${project_id}/rejected` + return APIClient.fetch(url).then(json => { + if (json.reservations.length === 0) { + return + } + this.components.reservations.rejected.set().reservations(json.reservations).draw() + })*/ + }, + reservations: project_id => { + reservations.loading.show() - const promises = [] + const promises = [] - promises.push(this.get().active(project_id)) - promises.push(this.get().pending(project_id)) - promises.push(this.get().rejected(project_id)) + promises.push(reservations.get.active(project_id)) + promises.push(reservations.get.pending(project_id)) + promises.push(reservations.get.rejected(project_id)) - return Promise.any(promises).then(() => { - this.loading().hide() - }) - } + return Promise.any(promises).then(() => { + reservations.loading.hide() + }) } }, - loading() { - return { - show: () => { - this.components.loader.style.display = this.display.loader - }, - hide: () => { - this.components.loader.style.display = 'none' - } + loading: { + show: () => { + reservations.components.loader.style.display = reservations.display.loader + }, + hide: () => { + reservations.components.loader.style.display = 'none' } }, - action() { - return { - reset: event => { - event.preventDefault() - this.components.projects.current_project = null - Object.entries(this.components.reservations).forEach(([key, value]) => { - this.components.reservations[key].reservations = [] - this.components.reservations[key].hide() - }) - this.show().projects() - return false - }, - up: event => { - event.preventDefault() - Object.values(this.components.reservations).forEach(reservations => reservations.hide()) - this.show().projects() - return false - }, - add: event => { - event.preventDefault() - console.debug('Add') - return false - }, - reservations: () => { - Object.values(this.components.reservations).forEach(reservations => { - reservations.draw() - }) - } + action: { + reset: event => { + event.preventDefault() + reservations.components.projects.current_project = null + Object.entries(reservations.components.reservations).forEach(([key, value]) => { + reservations.components.reservations[key].reservations = [] + reservations.components.reservations[key].hide() + }) + reservations.show.projects() + return false + }, + up: event => { + event.preventDefault() + Object.values(reservations.components.reservations).forEach(reservations => reservations.hide()) + reservations.show.projects() + return false + }, + add: event => { + event.preventDefault() + reservations.components.modals.add.show() + return false + }, + reservations: () => { + Object.values(reservations.components.reservations).forEach(reservations => { + reservations.draw() + }) } }, - show() { - return { - projects: () => { - this.components.projects.show() - this.components.results.style.display = 'none' - }, - results: () => { - this.components.projects.hide() - this.components.results.style.display = this.display.results - } + show: { + projects: () => { + reservations.components.projects.show() + reservations.components.results.style.display = 'none' + }, + results: () => { + reservations.components.projects.hide() + reservations.components.results.style.display = reservations.display.results } }, setup(configuration) { @@ -503,12 +525,14 @@ this.components.reservations.rejected = new RejectedReservations({component_id: configuration.ids.rejected, formatters}) this.display.loader = this.components.loader.style.display - this.loading().hide() + this.loading.hide() $(`#${configuration.ids.tabs} .item`).tab() this.components.results = document.getElementById(configuration.ids.results) this.display.results = this.components.results.style.display - this.show().projects() + this.show.projects() + + this.components.modals.add = new AddReservationModal() } } $(document).ready(() => { diff --git a/app/resources/views/ventas/reservations/add_modal.blade.php b/app/resources/views/ventas/reservations/add_modal.blade.php new file mode 100644 index 0000000..3f137b1 --- /dev/null +++ b/app/resources/views/ventas/reservations/add_modal.blade.php @@ -0,0 +1,733 @@ + + +@include('layout.body.scripts.rut') + +@push('page_scripts') + +@endpush diff --git a/app/src/Controller/API/Personas.php b/app/src/Controller/API/Personas.php new file mode 100644 index 0000000..ab424a9 --- /dev/null +++ b/app/src/Controller/API/Personas.php @@ -0,0 +1,34 @@ + $rut, + 'persona' => null, + 'success' => false + ]; + try { + $persona = $personaService->getById($rut); + $output['persona'] = $persona; + $output['success'] = true; + } catch (ServiceAction\Read $exception) { + $this->logger->error($exception->getMessage(), ['exception' => $exception]); + } + + return $this->withJson($response, $output); + } +} diff --git a/app/src/Controller/API/Proyectos.php b/app/src/Controller/API/Proyectos.php index e6994ec..d30adb8 100644 --- a/app/src/Controller/API/Proyectos.php +++ b/app/src/Controller/API/Proyectos.php @@ -187,5 +187,18 @@ class Proyectos } return $this->withJson($response, $output); } - + public function promotions(ServerRequestInterface $request, ResponseInterface $response, + Service\Venta\Promotion $promotionService, int $proyecto_id): ResponseInterface + { + $output = [ + 'project_id' => $proyecto_id, + 'promotions' => [] + ]; + try { + $output['promotions'] = $promotionService->getByProject($proyecto_id); + } catch (Read $exception) { + return $this->withError($response, $exception); + } + return $this->withJson($response, $output); + } } diff --git a/app/src/Controller/Ventas/Reservations.php b/app/src/Controller/Ventas/Reservations.php index d8bd8df..9ee1edc 100644 --- a/app/src/Controller/Ventas/Reservations.php +++ b/app/src/Controller/Ventas/Reservations.php @@ -5,18 +5,24 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Incoviba\Common\Alias\View; use Incoviba\Common\Implement\Exception\EmptyResult; +use Incoviba\Exception\ServiceAction\Read; use Incoviba\Repository; use Incoviba\Service; class Reservations { public function __invoke(ServerRequestInterface $request, ResponseInterface $response, - Service\Proyecto $proyectoService, View $view): ResponseInterface + Service\Proyecto $proyectoService, Repository\Region $regionRepository, + View $view): ResponseInterface { $projects = []; try { $projects = $proyectoService->getVendibles('descripcion'); + } catch (Read) {} + $regions = []; + try { + $regions = $regionRepository->fetchAll(); } catch (EmptyResult) {} - return $view->render($response, 'ventas.reservations', compact('projects')); + return $view->render($response, 'ventas.reservations', compact('projects', 'regions')); } } diff --git a/app/src/Model/Persona.php b/app/src/Model/Persona.php index 35be13d..3d3a465 100644 --- a/app/src/Model/Persona.php +++ b/app/src/Model/Persona.php @@ -1,6 +1,7 @@ datos)) { - $this->datos = $this->runFactory('datos'); + try { + $this->datos = $this->runFactory('datos'); + } catch (EmptyResult) { + $this->datos = null; + } } return $this->datos; } diff --git a/app/src/Repository/Persona/Datos.php b/app/src/Repository/Persona/Datos.php index bfec12b..3d71052 100644 --- a/app/src/Repository/Persona/Datos.php +++ b/app/src/Repository/Persona/Datos.php @@ -29,6 +29,9 @@ class Datos extends Ideal\Repository ->register('direccion_id', (new Implement\Repository\Mapper()) ->setProperty('direccion') ->setFunction(function($data) { + if ($data['direccion_id'] === null) { + return null; + } return $this->direccionRepository->fetchById($data['direccion_id']); })->setDefault(null)) ->register('telefono', (new Implement\Repository\Mapper())->setFunction(function($data) { diff --git a/app/src/Service/Persona.php b/app/src/Service/Persona.php index bfabeca..625e6d1 100644 --- a/app/src/Service/Persona.php +++ b/app/src/Service/Persona.php @@ -35,7 +35,7 @@ class Persona extends Ideal\Service /** * @param int $rut * @return Model\Persona - * @throws Read|Create + * @throws Read */ public function getById(int $rut): Model\Persona { @@ -44,7 +44,11 @@ class Persona extends Ideal\Service } catch (Implement\Exception\EmptyResult) { try { $this->propietarioRepository->fetchById($rut); - return $this->add(compact('rut')); + try { + return $this->add(compact('rut')); + } catch (Create $exception) { + throw new Read(__CLASS__, $exception); + } } catch (Implement\Exception\EmptyResult $exception) { throw new Read(__CLASS__, $exception); } diff --git a/app/src/Service/Venta/Promotion.php b/app/src/Service/Venta/Promotion.php index 6dc0194..052be9b 100644 --- a/app/src/Service/Venta/Promotion.php +++ b/app/src/Service/Venta/Promotion.php @@ -48,6 +48,20 @@ class Promotion extends Ideal\Service } } + /** + * @param int $project_id + * @return array + * @throws Exception\ServiceAction\Read + */ + public function getByProject(int $project_id): array + { + try { + return array_map([$this, 'process'], $this->promotionRepository->fetchByProject($project_id)); + } catch (Implement\Exception\EmptyResult $exception) { + throw new Exception\ServiceAction\Read(__CLASS__, $exception); + } + } + /** * @param int $contract_id * @return array