units, 'value')); } public function withCommission(): float { $base = 0; foreach ($this->units as $unit) { foreach ($this->promotions as $promotion) { $base += $promotion->activate()->reverse($unit['unit'], $unit['value'], $this->broker); } } return $base; } public function base(): float { $base = $this->withCommission(); if ($this->broker !== null) { $base = $this->broker->reverseCommission($this->project, $base, $this->date); } return $base; } public function price(): float { $price = 0; foreach ($this->units as $unit) { $price += $unit->unit->precio($this->date)?->valor ?? 0; } return $price; } protected array $states = []; public function states(): array { if (count($this->states) === 0) { $this->states = $this->runFactory('states'); } return $this->states; } protected Model\Venta\Reservation\State $currentState; public function currentState(): Model\Venta\Reservation\State { if (!isset($this->currentState)) { $states = $this->states(); if (count($states) === 0) { throw new InvalidArgumentException('States must not be empty'); } $this->currentState = last($states); } return $this->currentState; } public function addUnit(Model\Venta\Unidad $unit, float $value): self { if (($i = $this->findUnit($unit->id)) !== null) { $this->units[$i]->value = $value; return $this; } $this->units[] = (object) [ 'unit' => $unit, 'value' => $value, ]; return $this; } public function removeUnit(int $unit_id): self { if (($i = $this->findUnit($unit_id)) === null) { return $this; } unset($this->units[$i]); $this->units = array_values($this->units); return $this; } public function findUnit(int $unit_id): ?int { return array_find_key($this->units, fn($unit) => $unit->unit->id == $unit_id); } public function hasUnit(int $unit_id): bool { return $this->findUnit($unit_id) !== null; } public function summary(): string { $unitSummary = array_map(function($unit) { $type = $unit->unit->proyectoTipoUnidad->tipoUnidad->descripcion; $cap = strtoupper(strstr($type, 0, 1)); return "{$cap}{$unit->unit->descripcion}"; }, $this->units); return implode('', $unitSummary); } public function valid(): bool { $base = $this->base(); $price = $this->price(); return $base >= $price; } protected function jsonComplement(): array { return [ 'project_id' => $this->project->id, 'buyer' => $this->buyer, 'date' => $this->date->format('Y-m-d'), 'units' => $this->units, 'promotions' => $this->promotions, 'broker' => $this->broker, 'offer' => $this->offer(), 'with_commission' => $this->withCommission(), 'base' => $this->base(), 'price' => $this->price(), 'valid' => $this->valid(), 'summary' => $this->summary() ]; } }