From d3b0026ca416d9889aaee35580859b631d43cc48 Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Tue, 18 Mar 2025 19:13:47 -0300 Subject: [PATCH] Agregar, editar y eliminar promociones --- .../20250215133429_create_promotion.php | 2 +- app/src/Model/Venta/Promotion.php | 29 ++++++---- app/src/Repository/Venta/Promotion.php | 39 +++++++++++--- app/src/Service/Venta/Promotion.php | 54 +++++++++++++++++++ 4 files changed, 107 insertions(+), 17 deletions(-) diff --git a/app/resources/database/migrations/20250215133429_create_promotion.php b/app/resources/database/migrations/20250215133429_create_promotion.php index 888ce66..2e0eb47 100644 --- a/app/resources/database/migrations/20250215133429_create_promotion.php +++ b/app/resources/database/migrations/20250215133429_create_promotion.php @@ -29,7 +29,7 @@ final class CreatePromotion extends AbstractMigration ->addColumn('start_date', 'date', ['null' => false]) ->addColumn('end_date', 'date', ['null' => false]) ->addColumn('valid_until', 'date', ['null' => false]) - ->addColumn('state', 'integer', ['length' => 1, 'null' => false, 'default' => 0]) + ->addColumn('state', 'integer', ['length' => 1, 'null' => false, 'default' => 1]) ->addForeignKey('price_id', 'prices', 'id', ['delete' => 'cascade', 'update' => 'cascade']) ->create(); diff --git a/app/src/Model/Venta/Promotion.php b/app/src/Model/Venta/Promotion.php index 9089e99..dc1660e 100644 --- a/app/src/Model/Venta/Promotion.php +++ b/app/src/Model/Venta/Promotion.php @@ -4,14 +4,18 @@ namespace Incoviba\Model\Venta; use DateTimeInterface; use Incoviba\Common; use Incoviba\Model\Proyecto\Broker; +use Incoviba\Model\Venta\Promotion\State; +use Incoviba\Model\Venta\Promotion\Type; class Promotion extends Common\Ideal\Model { + public string $description; public float $amount; public DateTimeInterface $startDate; - public DateTimeInterface $endDate; - public DateTimeInterface $validUntil; - public int $state; + public ?DateTimeInterface $endDate; + public ?DateTimeInterface $validUntil; + public Type $type; + public State $state = State::ACTIVE; protected array $contracts; public function contracts(): array @@ -31,17 +35,24 @@ class Promotion extends Common\Ideal\Model return $this->units; } + public function value(float $price): float + { + if ($this->type === Type::FIXED) { + return $price + $this->amount; + } + return $price / (1 - $this->amount); + } + protected function jsonComplement(): array { return [ + 'description' => $this->description, 'amount' => $this->amount, '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) - ], + 'end_date' => $this->endDate?->format('Y-m-d'), + 'valid_until' => $this->validUntil?->format('Y-m-d'), + 'type' => $this->type, + 'state' => $this->state, 'contracts' => $this->contracts() ?? [], 'units' => $this->units() ?? [] ]; diff --git a/app/src/Repository/Venta/Promotion.php b/app/src/Repository/Venta/Promotion.php index 1eece43..8517d08 100644 --- a/app/src/Repository/Venta/Promotion.php +++ b/app/src/Repository/Venta/Promotion.php @@ -19,25 +19,50 @@ class Promotion extends Common\Ideal\Repository public function create(?array $data = null): Model\Venta\Promotion { - $map = (new Common\Implement\Repository\MapperParser(['amount', 'type'])) + $map = (new Common\Implement\Repository\MapperParser(['description', 'amount'])) + ->register('type', (new Common\Implement\Repository\Mapper()) + ->setFunction(function($data) { + return Model\Venta\Promotion\Type::from($data['type']); + })) + ->register('state', (new Common\Implement\Repository\Mapper()) + ->setFunction(function($data) { + return Model\Venta\Promotion\State::from($data['state']); + }) + ->setDefault(Model\Venta\Promotion\State::ACTIVE)) ->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')); + ->register('end_date', (new Common\Implement\Repository\Mapper\DateTime('end_date', 'endDate')) + ->setDefault(null)) + ->register('valid_until', (new Common\Implement\Repository\Mapper\DateTime('valid_until', 'validUntil')) + ->setDefault(null)); return $this->parseData(new Model\Venta\Promotion(), $data, $map); } + public function save(Common\Define\Model $model): Model\Venta\Promotion { $model->id = $this->saveNew( - ['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')] + ['description', 'amount', 'type', 'start_date', 'end_date', 'valid_until'], + [$model->description, $model->amount, $model->type->value, $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, ['amount', 'type', 'start_date', 'end_date', 'valid_until'], $new_data); + return $this->update($model, ['description', 'amount', 'type', 'start_date', 'end_date', 'valid_until'], $new_data); + } + + public function filterData(array $data): array + { + $filteredData = array_intersect_key($data, array_flip(['description', 'amount', 'type', 'start_date', 'end_date', 'valid_until'])); + if (!isset($filteredData['amount']) and isset($data['value'])) { + $filteredData['amount'] = $data['value']; + } + $filteredData['type'] = (int) $filteredData['type']; + if ($filteredData['amount'] > 1 and $filteredData['type'] === Model\Venta\Promotion\Type::VARIABLE->value) { + $filteredData['amount'] = $filteredData['amount'] / 100; + } + return $filteredData; } /** diff --git a/app/src/Service/Venta/Promotion.php b/app/src/Service/Venta/Promotion.php index 2eb3685..6e18bfa 100644 --- a/app/src/Service/Venta/Promotion.php +++ b/app/src/Service/Venta/Promotion.php @@ -1,6 +1,8 @@ promotionRepository->filterData($data); + #throw new \Exception(var_export($filteredData, true)); + $promotion = $this->promotionRepository->create($filteredData); + #throw new \Exception(var_export($promotion, true)); + $promotion = $this->promotionRepository->save($promotion); + return $this->process($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); + } + } + protected function process(Model\Venta\Promotion $model): Model\Venta\Promotion {