*/ #[ORM\OneToMany(mappedBy: 'invoice', targetEntity: InvoiceMeta::class, cascade: ['persist'])] #[Serializer\Expose] #[Serializer\Groups(['Invoice'])] #[Serializer\Type(name: 'array')] #[Serializer\SerializedName('metaFields')] #[Serializer\Accessor(getter: 'getVisibleMetaFields')] private Collection $meta; public function __construct() { $this->meta = new ArrayCollection(); } public function getId(): ?int { return $this->id; } public function getCustomer(): ?Customer { return $this->customer; } public function getUser(): ?User { return $this->user; } public function getInvoiceNumber(): ?string { return $this->invoiceNumber; } public function getTotal(): float { return $this->total; } public function getCreatedAt(): ?\DateTime { if (!$this->localized) { if (null !== $this->createdAt && null !== $this->timezone) { $this->createdAt->setTimezone(new \DateTimeZone($this->timezone)); } $this->localized = true; } return $this->createdAt; } public function getDueDate(): ?\DateTime { if (null === $this->getCreatedAt()) { return null; } $dueDate = clone $this->getCreatedAt(); $dueDate->modify('+ ' . $this->dueDays . 'days'); return $dueDate; } public function isOverdue(): bool { if (null === $this->getDueDate()) { return false; } return $this->getDueDate()->getTimestamp() < (new \DateTime('now', new \DateTimeZone($this->timezone)))->getTimestamp(); } public function setFilename(string $filename): Invoice { $this->invoiceFilename = $filename; return $this; } public function setModel(InvoiceModel $model): Invoice { $template = $model->getTemplate(); if ($template === null) { throw new \InvalidArgumentException('Missing invoice template'); } if ($template->getDueDays() === null || $template->getVat() === null) { throw new \InvalidArgumentException('Missing due-days or vat setting'); } $customer = $model->getCustomer(); if ($customer === null) { throw new \InvalidArgumentException('Missing invoice customer'); } $user = $model->getUser(); if ($user === null) { throw new \InvalidArgumentException('Missing invoice user'); } $this->setCustomer($customer); $this->setUser($user); $this->setTotal($model->getCalculator()->getTotal()); $this->setTax($model->getCalculator()->getTax()); $this->setInvoiceNumber($model->getInvoiceNumber()); $this->setCurrency($model->getCurrency()); $this->setCreatedAt($model->getInvoiceDate()); $this->setDueDays($template->getDueDays()); $this->setVat($template->getVat()); return $this; } public function isNew(): bool { return $this->status === self::STATUS_NEW; } public function setIsNew(): Invoice { $this->setPaymentDate(null); $this->status = self::STATUS_NEW; return $this; } public function isPending(): bool { return $this->status === self::STATUS_PENDING; } public function setIsPending(): Invoice { $this->setPaymentDate(null); $this->status = self::STATUS_PENDING; return $this; } public function isPaid(): bool { return $this->status === self::STATUS_PAID; } public function setIsPaid(): Invoice { $this->status = self::STATUS_PAID; return $this; } public function isCanceled(): bool { return $this->status === self::STATUS_CANCELED; } public function getStatus(): string { return $this->status; } public function setStatus(string $status): void { if (!\in_array($status, [self::STATUS_NEW, self::STATUS_PENDING, self::STATUS_PAID, self::STATUS_CANCELED])) { throw new \InvalidArgumentException('Unknown invoice status'); } $this->status = $status; } public function setIsCanceled(): void { $this->status = self::STATUS_CANCELED; } public function getDueDays(): int { return $this->dueDays; } public function getVat(): float { return $this->vat; } public function getTax(): float { return $this->tax; } public function getCurrency(): ?string { return $this->currency; } public function getInvoiceFilename(): ?string { return $this->invoiceFilename; } #[Exporter\Expose(label: 'invoice.subtotal', type: 'float', name: 'subtotal')] public function getSubtotal(): float { return $this->total - $this->tax; } public function getPaymentDate(): ?\DateTime { return $this->paymentDate; } public function setPaymentDate(?\DateTime $paymentDate): Invoice { $this->paymentDate = $paymentDate; return $this; } public function setComment(?string $comment): void { $this->comment = $comment; } public function getComment(): ?string { return $this->comment; } /** * @return Collection|MetaTableTypeInterface[] */ public function getMetaFields(): Collection { return $this->meta; } /** * @return MetaTableTypeInterface[] */ public function getVisibleMetaFields(): array { $all = []; foreach ($this->meta as $meta) { if ($meta->isVisible()) { $all[] = $meta; } } return $all; } public function getMetaField(string $name): ?MetaTableTypeInterface { foreach ($this->meta as $field) { if (strtolower($field->getName()) === strtolower($name)) { return $field; } } return null; } public function setMetaField(MetaTableTypeInterface $meta): EntityWithMetaFields { if (null === ($current = $this->getMetaField($meta->getName()))) { $meta->setEntity($this); $this->meta->add($meta); return $this; } $current->merge($meta); return $this; } public function setVat(float $vat): void { $this->vat = $vat; } public function setInvoiceNumber(string $invoiceNumber): void { $this->invoiceNumber = $invoiceNumber; } public function setCustomer(Customer $customer): void { $this->customer = $customer; } public function setUser(User $user): void { $this->user = $user; } public function setCreatedAt(\DateTimeInterface $createdAt): void { $this->createdAt = \DateTime::createFromInterface($createdAt); $this->timezone = $createdAt->getTimezone()->getName(); } public function setTotal(float $total): void { $this->total = $total; } public function setTax(float $tax): void { $this->tax = $tax; } public function setCurrency(string $currency): void { $this->currency = $currency; } public function setDueDays(int $dueDays): void { $this->dueDays = $dueDays; } public function __clone() { if ($this->id) { $this->id = null; } $currentMeta = $this->meta; $this->meta = new ArrayCollection(); /** @var InvoiceMeta $meta */ foreach ($currentMeta as $meta) { $newMeta = clone $meta; $newMeta->setEntity($this); $this->setMetaField($newMeta); } } }