Files
oficial/app/src/Model/Venta/Promotion.php
aldarien 61c813fc08 feature/cierres (#30)
Reservas agregar y aprobar

Co-authored-by: Juan Pablo Vial <jpvialb@incoviba.cl>
Reviewed-on: #30
2025-09-11 15:16:12 -03:00

171 lines
5.4 KiB
PHP

<?php
namespace Incoviba\Model\Venta;
use DateTimeInterface;
use Incoviba\Common;
use Incoviba\Model\Proyecto;
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 Type $type;
public State $state = State::ACTIVE;
protected array $projects;
public function projects(): array
{
if (empty($this->projects)) {
$this->projects = $this->runFactory('projects') ?? [];
}
return $this->projects;
}
protected array $brokers;
public function brokers(): array
{
if (empty($this->brokers)) {
$this->brokers = $this->runFactory('brokers') ?? [];
}
return $this->brokers;
}
protected array $unitTypes;
public function unitTypes(): array
{
if (empty($this->unitTypes)) {
$this->unitTypes = $this->runFactory('unitTypes') ?? [];
}
return $this->unitTypes;
}
protected array $unitLines;
public function unitLines(): array
{
if (empty($this->unitLines)) {
$this->unitLines = $this->runFactory('unitLines') ?? [];
}
return $this->unitLines;
}
protected array $units;
public function units(): array
{
if (empty($this->units)) {
$this->units = $this->runFactory('units') ?? [];
}
return $this->units;
}
public function isActive(): bool
{
return $this->state === State::ACTIVE;
}
public function activate(): self
{
$this->state = State::ACTIVE;
return $this;
}
public function value(float $price): float
{
if (!$this->isActive()) {
return $price;
}
if ($this->type === Type::FIXED) {
return $price + $this->amount;
}
return $price / (1 - $this->amount);
}
public function inverse(float $price): float
{
if (!$this->isActive()) {
return $price;
}
if ($this->type === Type::FIXED) {
return $price - $this->amount;
}
return $price * (1 - $this->amount);
}
public function apply(Unidad $unit, float $price, ?Broker $broker = null): float
{
if (!$this->isActive()) {
return $price;
}
$projectIds = array_map(fn(Proyecto $proyecto) => $proyecto->id, $this->projects());
if (in_array($unit->proyectoTipoUnidad->proyecto->id, $projectIds)) {
return $this->value($price);
}
if ($broker !== null) {
$brokerIds = array_map(fn(Broker $broker) => $broker->id, $this->brokers());
if (in_array($broker->id, $brokerIds)) {
return $this->value($price);
}
}
$typeIds = array_map(fn(Proyecto\TipoUnidad $type) => $type->id, $this->unitTypes());
if (in_array($unit->proyectoTipoUnidad->tipoUnidad->id, $typeIds)) {
return $this->value($price);
}
$lineIds = array_map(fn(Proyecto\ProyectoTipoUnidad $line) => $line->id, $this->unitLines());
if (in_array($unit->proyectoTipoUnidad->id, $lineIds)) {
return $this->value($price);
}
$unitIds = array_map(fn(Unidad $unit) => $unit->id, $this->units());
if (in_array($unit->id, $unitIds)) {
return $this->value($price);
}
return $price;
}
public function reverse(Unidad $unit, float $price, ?Broker $broker = null): float
{
if (!$this->isActive()) {
return $price;
}
$projectIds = array_map(fn(Proyecto $proyecto) => $proyecto->id, $this->projects());
if (in_array($unit->proyectoTipoUnidad->proyecto->id, $projectIds)) {
return $this->inverse($price);
}
if ($broker !== null) {
$brokerIds = array_map(fn(Broker $broker) => $broker->id, $this->brokers());
if (in_array($broker->id, $brokerIds)) {
return $this->inverse($price);
}
}
$typeIds = array_map(fn(Proyecto\TipoUnidad $type) => $type->id, $this->unitTypes());
if (in_array($unit->proyectoTipoUnidad->tipoUnidad->id, $typeIds)) {
return $this->inverse($price);
}
$lineIds = array_map(fn(Proyecto\ProyectoTipoUnidad $line) => $line->id, $this->unitLines());
if (in_array($unit->proyectoTipoUnidad->id, $lineIds)) {
return $this->inverse($price);
}
$unitIds = array_map(fn(Unidad $unit) => $unit->id, $this->units());
if (in_array($unit->id, $unitIds)) {
return $this->inverse($price);
}
return $price;
}
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'),
'type' => $this->type,
'state' => $this->state,
'projects' => $this->projects() ?? [],
'contracts' => $this->brokers() ?? [],
'units' => $this->units() ?? []
];
}
}