From bae0f1f555c3b81993ccbf15c12204dd30bf4fce Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Mon, 17 Mar 2025 22:49:48 -0300 Subject: [PATCH] Separacion de Promocion de Contrato y Precio "Simplificacion" de datos en listado de precios --- ...250317192659_create_promotion_contract.php | 30 ++ ...7193111_alter_promotions_remove_price.php} | 6 +- .../20250317193246_create_promotion_unit.php | 30 ++ .../views/layout/body/scripts/stats.blade.php | 6 + .../brokers/contracts/show.blade.php | 283 ++++-------------- .../brokers/contracts/show/linea.blade.php | 80 +++++ .../brokers/contracts/show/tipo.blade.php | 61 ++++ .../brokers/contracts/show/unidades.blade.php | 124 ++++++++ app/src/Model/Venta/Promotion.php | 26 +- .../Repository/Proyecto/Broker/Contract.php | 15 + app/src/Repository/Venta/Promotion.php | 72 ++--- app/src/Repository/Venta/Unidad.php | 15 + app/src/Service/Venta/Promotion.php | 9 +- 13 files changed, 479 insertions(+), 278 deletions(-) create mode 100644 app/resources/database/migrations/20250317192659_create_promotion_contract.php rename app/resources/database/migrations/{20250312221404_alter_promotions_add_contract_id.php => 20250317193111_alter_promotions_remove_price.php} (64%) create mode 100644 app/resources/database/migrations/20250317193246_create_promotion_unit.php create mode 100644 app/resources/views/layout/body/scripts/stats.blade.php create mode 100644 app/resources/views/proyectos/brokers/contracts/show/linea.blade.php create mode 100644 app/resources/views/proyectos/brokers/contracts/show/tipo.blade.php create mode 100644 app/resources/views/proyectos/brokers/contracts/show/unidades.blade.php diff --git a/app/resources/database/migrations/20250317192659_create_promotion_contract.php b/app/resources/database/migrations/20250317192659_create_promotion_contract.php new file mode 100644 index 0000000..b427f43 --- /dev/null +++ b/app/resources/database/migrations/20250317192659_create_promotion_contract.php @@ -0,0 +1,30 @@ +table('promotion_contracts') + ->addColumn('promotion_id', 'integer', ['signed' => false, 'null' => false]) + ->addColumn('contract_id', 'integer', ['signed' => false, 'null' => false]) + ->addColumn('created_at', 'datetime', ['null' => false, 'default' => 'CURRENT_TIMESTAMP']) + ->addForeignKey('promotion_id', 'promotions', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) + ->addForeignKey('contract_id', 'broker_contracts', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) + ->create(); + } +} diff --git a/app/resources/database/migrations/20250312221404_alter_promotions_add_contract_id.php b/app/resources/database/migrations/20250317193111_alter_promotions_remove_price.php similarity index 64% rename from app/resources/database/migrations/20250312221404_alter_promotions_add_contract_id.php rename to app/resources/database/migrations/20250317193111_alter_promotions_remove_price.php index d0a5cdb..9da0da8 100644 --- a/app/resources/database/migrations/20250312221404_alter_promotions_add_contract_id.php +++ b/app/resources/database/migrations/20250317193111_alter_promotions_remove_price.php @@ -4,7 +4,7 @@ declare(strict_types=1); use Phinx\Migration\AbstractMigration; -final class AlterPromotionsAddContractId extends AbstractMigration +final class AlterPromotionsRemovePrice extends AbstractMigration { /** * Change Method. @@ -20,8 +20,8 @@ final class AlterPromotionsAddContractId extends AbstractMigration public function change(): void { $this->table('promotions') - ->addColumn('contract_id', 'integer', ['signed' => false, 'null' => false, 'default' => 0, 'after' => 'id']) - ->addForeignKey('contract_id', 'broker_contracts', 'id', ['delete' => 'cascade', 'update' => 'cascade']) + ->dropForeignKey('price_id') + ->removeColumn('price_id') ->update(); } } diff --git a/app/resources/database/migrations/20250317193246_create_promotion_unit.php b/app/resources/database/migrations/20250317193246_create_promotion_unit.php new file mode 100644 index 0000000..dfc83bc --- /dev/null +++ b/app/resources/database/migrations/20250317193246_create_promotion_unit.php @@ -0,0 +1,30 @@ +table('promotion_units') + ->addColumn('promotion_id', 'integer', ['signed' => false, 'null' => false]) + ->addColumn('unit_id', 'integer', ['signed' => false, 'null' => false]) + ->addColumn('created_at', 'datetime', ['null' => false, 'default' => 'CURRENT_TIMESTAMP']) + ->addForeignKey('promotion_id', 'promotions', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) + ->addForeignKey('unit_id', 'unidad', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']) + ->create(); + } +} diff --git a/app/resources/views/layout/body/scripts/stats.blade.php b/app/resources/views/layout/body/scripts/stats.blade.php new file mode 100644 index 0000000..6b777bf --- /dev/null +++ b/app/resources/views/layout/body/scripts/stats.blade.php @@ -0,0 +1,6 @@ +@prepend('page_scripts') + + +@endprepend diff --git a/app/resources/views/proyectos/brokers/contracts/show.blade.php b/app/resources/views/proyectos/brokers/contracts/show.blade.php index 2c77b4d..a26942f 100644 --- a/app/resources/views/proyectos/brokers/contracts/show.blade.php +++ b/app/resources/views/proyectos/brokers/contracts/show.blade.php @@ -8,11 +8,46 @@ {{ $contract->broker->name }} - {{ $contract->project->descripcion }} @endsection +@include('layout.body.scripts.stats') +@prepend('page_scripts') + +@endprepend + @section('brokers_content') -
- Comisión: {{ $format->percent($contract->commission, 2, true) }}
- Fecha Inicio: {{ $contract->current()->date->format('d/m/Y') }}
+
+
{{ $format->percent($contract->commission, 2, true) }}
+
+ Comisión desde {{ $contract->current()->date->format('d/m/Y') }} +
+
- - - - - - - - - - - - - - - - - - - -
TipoCantidadPrecioPromociónAcciones
MínimoPromedioMáximoMínimaPromedioMáxima
+ @include('proyectos.brokers.contracts.show.tipo')
- - - - - - - - - - - - - - - - - - - - - -
TipoLíneaOrientaciónCantidadPrecioPromociónAcciones
MínimoPromedioMáximoMínimaPromedioMáxima
+ @include('proyectos.brokers.contracts.show.linea')
- - - - - - - - - - - - - - - - -
TipoTipo OrderUnidadUnidad OrdenEstadoPrecioPromociónFecha InicioFecha TérminoAcciones
+ @include('proyectos.brokers.contracts.show.unidades')
@endsection @include('layout.body.scripts.datatables') @include('layout.body.scripts.datatables.searchbuilder') +@include('layout.body.scripts.datatables.buttons') @push('page_scripts') @endpush diff --git a/app/resources/views/proyectos/brokers/contracts/show/linea.blade.php b/app/resources/views/proyectos/brokers/contracts/show/linea.blade.php new file mode 100644 index 0000000..8a20b39 --- /dev/null +++ b/app/resources/views/proyectos/brokers/contracts/show/linea.blade.php @@ -0,0 +1,80 @@ + + + + + + + + + + + + + +
TipoLíneaOrientaciónCantidadPrecio ListaPorcentajePrecio Final
+ +@push('page_scripts') + +@endpush diff --git a/app/resources/views/proyectos/brokers/contracts/show/tipo.blade.php b/app/resources/views/proyectos/brokers/contracts/show/tipo.blade.php new file mode 100644 index 0000000..227dae5 --- /dev/null +++ b/app/resources/views/proyectos/brokers/contracts/show/tipo.blade.php @@ -0,0 +1,61 @@ + + + + + + + + + + + +
TipoCantidadPrecio BasePorcentajePrecio Final
+ +@push('page_scripts') + +@endpush diff --git a/app/resources/views/proyectos/brokers/contracts/show/unidades.blade.php b/app/resources/views/proyectos/brokers/contracts/show/unidades.blade.php new file mode 100644 index 0000000..cdd81e3 --- /dev/null +++ b/app/resources/views/proyectos/brokers/contracts/show/unidades.blade.php @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + +
TipoTipo OrderUnidadUnidad OrdenEstadoPrecio ListaPorcentajePrecio FinalFecha InicioFecha Término
+ +@push('page_scripts') + +@endpush diff --git a/app/src/Model/Venta/Promotion.php b/app/src/Model/Venta/Promotion.php index 7aafa3f..9089e99 100644 --- a/app/src/Model/Venta/Promotion.php +++ b/app/src/Model/Venta/Promotion.php @@ -7,33 +7,43 @@ use Incoviba\Model\Proyecto\Broker; class Promotion extends Common\Ideal\Model { - public Broker\Contract $contract; - public Precio $price; public float $amount; public DateTimeInterface $startDate; public DateTimeInterface $endDate; public DateTimeInterface $validUntil; public int $state; - public function price(): float + protected array $contracts; + public function contracts(): array { - return $this->price->valor * $this->amount; + if (empty($this->contracts)) { + $this->contracts = $this->runFactory('contracts'); + } + return $this->contracts; + } + + protected array $units; + public function units(): array + { + if (empty($this->units)) { + $this->units = $this->runFactory('units'); + } + return $this->units; } protected function jsonComplement(): array { return [ - 'contract_rut' => $this->contract->id, - 'price_id' => $this->price->id, 'amount' => $this->amount, - 'price' => $this->price(), 'start_date' => $this->startDate->format('Y-m-d'), 'end_date' => $this->endDate->format('Y-m-d'), 'valid_until' => $this->validUntil->format('Y-m-d'), 'state' => [ 'id' => $this->state, 'description' => Promotion\State::name($this->state) - ] + ], + 'contracts' => $this->contracts() ?? [], + 'units' => $this->units() ?? [] ]; } } diff --git a/app/src/Repository/Proyecto/Broker/Contract.php b/app/src/Repository/Proyecto/Broker/Contract.php index 66d1bd5..416376b 100644 --- a/app/src/Repository/Proyecto/Broker/Contract.php +++ b/app/src/Repository/Proyecto/Broker/Contract.php @@ -128,6 +128,21 @@ class Contract extends Common\Ideal\Repository return $this->fetchOne($query, ['project_id' => $projectId, 'broker_rut' => $brokerRut, 'state' => Model\Proyecto\Broker\Contract\State\Type::ACTIVE->value]); } + /** + * @param int $promotion_id + * @return array + * @throws Common\Implement\Exception\EmptyResult + */ + public function fetchByPromotion(int $promotion_id): array + { + $query = $this->connection->getQueryBuilder() + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('INNER JOIN promotion_contracts pc ON pc.contract_id = a.id') + ->where('pc.promotion_id = :promotion_id'); + return $this->fetchMany($query, ['promotion_id' => $promotion_id]); + } + 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_id = a.id'; diff --git a/app/src/Repository/Venta/Promotion.php b/app/src/Repository/Venta/Promotion.php index 76ce919..1eece43 100644 --- a/app/src/Repository/Venta/Promotion.php +++ b/app/src/Repository/Venta/Promotion.php @@ -20,16 +20,6 @@ class Promotion extends Common\Ideal\Repository public function create(?array $data = null): Model\Venta\Promotion { $map = (new Common\Implement\Repository\MapperParser(['amount', 'type'])) - ->register('contract_id', (new Common\Implement\Repository\Mapper()) - ->setProperty('contract') - ->setFunction(function($data) { - return $this->contractRepository->fetchById($data['contract_id']); - })) - ->register('price_id', (new Common\Implement\Repository\Mapper()) - ->setProperty('price') - ->setFunction(function($data) { - return $this->precioRepository->create($data); - })) ->register('start_date', new Common\Implement\Repository\Mapper\DateTime('start_date', 'startDate')) ->register('end_date', new Common\Implement\Repository\Mapper\DateTime('end_date', 'endDate')) ->register('valid_until', new Common\Implement\Repository\Mapper\DateTime('valid_until', 'validUntil')); @@ -39,15 +29,15 @@ class Promotion extends Common\Ideal\Repository public function save(Common\Define\Model $model): Model\Venta\Promotion { $model->id = $this->saveNew( - ['contract_id', 'amount', 'type', 'start_date', 'end_date', 'valid_until', 'price_id'], - [$model->contract->id, $model->amount, $model->type, $model->startDate->format('Y-m-d'), - $model->endDate->format('Y-m-d'), $model->validUntil->format('Y-m-d'), $model->price->id] + ['amount', 'type', 'start_date', 'end_date', 'valid_until'], + [$model->amount, $model->type, $model->startDate->format('Y-m-d'), + $model->endDate->format('Y-m-d'), $model->validUntil->format('Y-m-d')] ); return $model; } public function edit(Common\Define\Model $model, array $new_data): Model\Venta\Promotion { - return $this->update($model, ['contract_id', 'amount', 'type', 'start_date', 'end_date', 'valid_until', 'price_id'], $new_data); + return $this->update($model, ['amount', 'type', 'start_date', 'end_date', 'valid_until'], $new_data); } /** @@ -58,9 +48,10 @@ class Promotion extends Common\Ideal\Repository public function fetchByContract(int $contract_id): array { $query = $this->connection->getQueryBuilder() - ->select() - ->from($this->getTable()) - ->where('contract_id = :contract_id'); + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('INNER JOIN promotion_contracts pc ON pc.promotion_id = a.id') + ->where('pc.contract_id = :contract_id'); return $this->fetchMany($query, ['contract_id' => $contract_id]); } @@ -72,38 +63,41 @@ class Promotion extends Common\Ideal\Repository public function fetchActiveByContract(int $contract_id): array { $query = $this->connection->getQueryBuilder() - ->select() - ->from($this->getTable()) - ->where('contract_id = :contract_id AND state = :state'); + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('INNER JOIN promotion_contracts pc ON pc.promotion_id = a.id') + ->where('pc.contract_id = :contract_id AND a.state = :state'); return $this->fetchMany($query, ['contract_id' => $contract_id, 'state' => Model\Venta\Promotion\State::ACTIVE]); } /** - * @param int $price_id + * @param int $unit_id * @return array * @throws Common\Implement\Exception\EmptyResult */ - public function fetchByPrice(int $price_id): array + public function fetchByUnit(int $unit_id): array { $query = $this->connection->getQueryBuilder() - ->select() - ->from($this->getTable()) - ->where('price_id = :price_id'); - return $this->fetchMany($query, ['price_id' => $price_id]); + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('INNER JOIN promotion_units pu ON pu.promotion_id = a.id') + ->where('pu.unit_id = :unit_id'); + return $this->fetchMany($query, ['unit_id' => $unit_id]); } /** - * @param int $price_id + * @param int $unit_id * @return array * @throws Common\Implement\Exception\EmptyResult */ - public function fetchActiveByPrice(int $price_id): array + public function fetchActiveByUnit(int $unit_id): array { $query = $this->connection->getQueryBuilder() - ->select() - ->from($this->getTable()) - ->where('price_id = :price_id AND state = :state'); - return $this->fetchMany($query, ['price_id' => $price_id, 'state' => Model\Venta\Promotion\State::ACTIVE]); + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('INNER JOIN promotion_units pu ON pu.promotion_id = a.id') + ->where('pu.unit_id = :unit_id AND a.state = :state'); + return $this->fetchMany($query, ['unit_id' => $unit_id, 'state' => Model\Venta\Promotion\State::ACTIVE]); } /** @@ -116,8 +110,8 @@ class Promotion extends Common\Ideal\Repository $query = $this->connection->getQueryBuilder() ->select('a.*') ->from("{$this->getTable()} a") - ->joined('INNER JOIN precio ON precio.id = a.price_id') - ->joined('INNER JOIN unidad ON unidad.id = precio.unidad') + ->joined('INNER JOIN promotion_units pu ON pu.promotion_id = a.id') + ->joined('INNER JOIN unidad ON unidad.id = pu.unit_id') ->joined('INNER JOIN proyecto_tipo_unidad ON proyecto_tipo_unidad.id = unidad.pt') ->joined('INNER JOIN proyecto ON proyecto.id = proyecto_tipo_unidad.proyecto') ->where('proyecto.id = :project_id'); @@ -134,8 +128,8 @@ class Promotion extends Common\Ideal\Repository $query = $this->connection->getQueryBuilder() ->select('a.*') ->from("{$this->getTable()} a") - ->joined('INNER JOIN precio ON precio.id = a.price_id') - ->joined('INNER JOIN unidad ON unidad.id = precio.unidad') + ->joined('INNER JOIN promotion_units pu ON pu.promotion_id = a.id') + ->joined('INNER JOIN unidad ON unidad.id = pu.unit_id') ->joined('INNER JOIN proyecto_tipo_unidad ON proyecto_tipo_unidad.id = unidad.pt') ->joined('INNER JOIN proyecto ON proyecto.id = proyecto_tipo_unidad.proyecto') ->where('proyecto.id = :project_id AND a.state = :state'); @@ -153,9 +147,9 @@ class Promotion extends Common\Ideal\Repository $query = $this->connection->getQueryBuilder() ->select('a.*') ->from("{$this->getTable()} a") - ->joined('INNER JOIN precio ON precio.id = a.price_id') - ->joined('INNER JOIN unidad ON unidad.id = precio.unidad') - ->where('a.contract_id = :contract_id AND unidad.id = :unit_id'); + ->joined('INNER JOIN promotion_contracts pc ON pc.promotion_id = a.id') + ->joined('INNER JOIN promotion_units pu ON pu.promotion_id = a.id') + ->where('pc.contract_id = :contract_id AND pu.unit_id = :unit_id'); return $this->fetchOne($query, ['contract_id' => $contract_id, 'unit_id' => $unit_id]); } } diff --git a/app/src/Repository/Venta/Unidad.php b/app/src/Repository/Venta/Unidad.php index 6f8477c..1cf698e 100644 --- a/app/src/Repository/Venta/Unidad.php +++ b/app/src/Repository/Venta/Unidad.php @@ -185,6 +185,21 @@ class Unidad extends Ideal\Repository return $this->fetchOne($query, ['unidad_id' => $unidad_id]); } + /** + * @param int $promotion_id + * @return array + * @throws Implement\Exception\EmptyResult + */ + public function fetchByPromotion(int $promotion_id): array + { + $query = $this->connection->getQueryBuilder() + ->select('a.*') + ->from("{$this->getTable()} a") + ->joined('INNER JOIN `promotion_units` pu ON pu.`unit_id` = a.`id`') + ->where('pu.`promotion_id` = :promotion_id'); + return $this->fetchMany($query, ['promotion_id' => $promotion_id]); + } + protected function joinProrrateo(): string { return "LEFT OUTER JOIN unidad_prorrateo up ON up.unidad_id = a.id"; diff --git a/app/src/Service/Venta/Promotion.php b/app/src/Service/Venta/Promotion.php index 5b1b781..2eb3685 100644 --- a/app/src/Service/Venta/Promotion.php +++ b/app/src/Service/Venta/Promotion.php @@ -13,7 +13,8 @@ class Promotion extends Ideal\Service { public function __construct(LoggerInterface $logger, protected Repository\Venta\Promotion $promotionRepository, - protected Repository\Proyecto\Broker\Contract $contractRepository) + protected Repository\Proyecto\Broker\Contract $contractRepository, + protected Repository\Venta\Unidad $unidadRepository) { parent::__construct($logger); } @@ -80,6 +81,12 @@ class Promotion extends Ideal\Service protected function process(Model\Venta\Promotion $model): Model\Venta\Promotion { + $model->addFactory('contracts', (new Implement\Repository\Factory()) + ->setCallable([$this->contractRepository, 'fetchByPromotion']) + ->setArgs(['promotion_id' => $model->id])); + $model->addFactory('units', (new Implement\Repository\Factory()) + ->setCallable([$this->unidadRepository, 'fetchByPromotion']) + ->setArgs(['promotion_id' => $model->id])); return $model; } }