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() ?? [] ]; } }