Reservas agregar y aprobar Co-authored-by: Juan Pablo Vial <jpvialb@incoviba.cl> Reviewed-on: #30
171 lines
5.4 KiB
PHP
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() ?? []
|
|
];
|
|
}
|
|
}
|