<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use App\Controller\Manager\Transaction\RefuseTransactionController;
use App\Controller\Manager\Transaction\ValidateTransactionController;
use App\Entity\Reference\ReferenceTransactionRentalType;
use App\Repository\TransactionRepository;
use DateTimeInterface;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter;
/**
* @ApiResource(
* normalizationContext={"groups"={"transaction:collection:read","transaction-item:read"}},
* denormalizationContext={"groups"={"transaction:write"},"skip_null_values" = true},
* attributes={
* "pagination_items_per_page"=10,
* "formats"={"jsonld", "json"},
* "order"={"id":"DESC"}
* },
* itemOperations={
* "get" = {
* "normalization_context"={"groups"={"transaction-item:read"}},
* "access_control"="is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')"
* },
* "put" = {
* "access_control" = "is_granted('PUT', object)",
* "denormalization_context"={"groups"={"transaction:put"}},
* },
* "validate_transaction"={
* "denormalization_context"={"groups"={"transaction:validate"}},
* "security"="is_granted('ROLE_MANAGER')",
* "method"="PATCH",
* "path"="/transactions/{id}/validate",
* "controller"=ValidateTransactionController::class,
* "read"=true,
* "write"=false,
* },
* "refuse_transaction"={
* "denormalization_context"={"groups"={"transaction:refuse"}},
* "security"="is_granted('ROLE_MANAGER')",
* "method"="PATCH",
* "path"="/transactions/{id}/refuse",
* "controller"=RefuseTransactionController::class,
* "read"=true,
* "write"=true,
* },
* },
*
* collectionOperations={
* "get" = {
* "normalization_context"={"groups"={"transaction:collection:read"}},
* "access_control"="is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')"
* },
* "post"={
* "security" = "is_granted('ROLE_AGENT') or is_granted('ROLE_MANAGER')",
* }
*
* },
* )
* @ApiFilter(OrderFilter::class, properties={"id"} , arguments= {"orderParameterName" : "order"})
* @ApiFilter(SearchFilter::class, properties={
* "id": "exact",
* "inputAgent.id": "exact",
* "outputAgent.id": "exact",
* "mandate.id" : "exact",
* "mandate.property.propertyAddress.zipCode": "ipartial",
* "referenceTransactionStatus.id": "exact",
* "mandate.key": "ipartial"
* })
* @ORM\Entity(repositoryClass=TransactionRepository::class)
* @ORM\HasLifecycleCallbacks()
* @ORM\EntityListeners({"App\EventListener\TransactionStatusListener"})
*/
class Transaction extends AbstractTransaction implements Loggable
{
/**
* @ORM\Column(type="float", nullable=true)
*
* @Groups({
* "transaction-item:read","transaction:write",
* "siege:put","siege:write",
* "transaction:collection:read"
* })
*/
private ?float $sellerCommission = 0;
/**
* @ORM\ManyToOne(targetEntity=Prescriber::class)
* @Groups({"transaction-item:read"})
*/
private ?Prescriber $inputPrescriber;
/**
* @ORM\ManyToOne(targetEntity=Prescriber::class)
* @Groups({"transaction-item:read","transaction:write","transaction:put"})
*/
private ?Prescriber $outputPrescriber;
/**
* @ORM\ManyToOne(targetEntity=Agent::class)
* @Groups({"transaction-item:read","transaction:write","transaction:put"})
*/
private ?Agent $outputRecommendation;
/**
* @ORM\ManyToOne(targetEntity=Agent::class)
* @Groups({"transaction-item:read","siege:put"})
*/
private ?Agent $inputRecommendation = null;
/**
* @ORM\ManyToOne(targetEntity=ReferenceTransactionRentalType::class)
* @ORM\JoinColumn(nullable=true)
*
* @Groups({"transaction-item:read","transaction:write","transaction:put"})
*/
private ?ReferenceTransactionRentalType $referenceRentalType = null;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "transaction:write", "transaction:put"})
*/
private ?DateTimeInterface $rentalStartDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put", "transaction:collection:read"})
*/
private ?DateTimeInterface $signatureActDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put"})
*/
private ?DateTimeInterface $paymentDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put"})
*/
private ?DateTimeInterface $disbursementDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put"})
*/
private ?DateTimeInterface $cancellationDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put"})
*/
private ?DateTimeInterface $editRentalContractDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put"})
*/
private ?DateTimeInterface $signatureRentalContractDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "siege:write", "siege:put"})
*/
private ?DateTimeInterface $refusalDate;
/**
* @ORM\Column(type="date", nullable=true)
* @Groups({"transaction-item:read", "transaction:write", "transaction:put"})
*/
private ?DateTimeInterface $rentalEndDate;
/**
* @ORM\Column(type="float",nullable=true)
*
* @Groups({"transaction:collection:read","transaction-item:read", "transaction:write", "transaction:put"})
*/
private ?float $rentalPrice;
public function getSellerCommission(): ?float
{
return $this->sellerCommission;
}
public function setSellerCommission(?float $sellerCommission): self
{
$this->sellerCommission = $sellerCommission;
return $this;
}
public function setInputPrescriber(?Prescriber $inputPrescriber): self
{
$this->inputPrescriber = $inputPrescriber;
return $this;
}
public function getInputPrescriber(): ?Prescriber
{
return $this->inputPrescriber;
}
public function getOutputPrescriber(): ?Prescriber
{
return $this->outputPrescriber;
}
public function setOutputRecommendation(?Agent $outputRecommendation): self
{
$this->outputRecommendation = $outputRecommendation;
return $this;
}
public function setOutputPrescriber(?Prescriber $outputPrescriber): self
{
$this->outputPrescriber = $outputPrescriber;
return $this;
}
public function getInputRecommendation(): ?Agent
{
return $this->inputRecommendation;
}
public function setInputRecommendation(?Agent $inputRecommendation): self
{
$this->inputRecommendation = $inputRecommendation;
return $this;
}
public function getOutputRecommendation(): ?Agent
{
return $this->outputRecommendation;
}
public function getRentalStartDate(): ?DateTimeInterface
{
return $this->rentalStartDate;
}
public function setRentalStartDate(?DateTimeInterface $rentalStartDate): void
{
$this->rentalStartDate = $rentalStartDate;
}
public function getRentalEndDate(): ?DateTimeInterface
{
return $this->rentalEndDate;
}
public function setRentalEndDate(?DateTimeInterface $rentalEndDate): void
{
$this->rentalEndDate = $rentalEndDate;
}
public function getSignatureActDate(): ?DateTimeInterface
{
return $this->signatureActDate;
}
public function setSignatureActDate(?DateTimeInterface $signatureActDate): self
{
$this->signatureActDate = $signatureActDate;
return $this;
}
public function getPaymentDate(): ?DateTimeInterface
{
return $this->paymentDate;
}
public function setPaymentDate(?DateTimeInterface $paymentDate): self
{
$this->paymentDate = $paymentDate;
return $this;
}
public function getDisbursementDate(): ?DateTimeInterface
{
return $this->disbursementDate;
}
public function setDisbursementDate(?DateTimeInterface $disbursementDate): self
{
$this->disbursementDate = $disbursementDate;
return $this;
}
public function getCancellationDate(): ?DateTimeInterface
{
return $this->cancellationDate;
}
public function setCancellationDate(?DateTimeInterface $cancellationDate): self
{
$this->cancellationDate = $cancellationDate;
return $this;
}
public function getRefusalDate(): ?DateTimeInterface
{
return $this->refusalDate;
}
public function setRefusalDate(?DateTimeInterface $refusalDate): self
{
$this->refusalDate = $refusalDate;
return $this;
}
public function getEditRentalContractDate(): ?DateTimeInterface
{
return $this->editRentalContractDate;
}
public function setEditRentalContractDate(?DateTimeInterface $editRentalContractDate): self
{
$this->editRentalContractDate = $editRentalContractDate;
return $this;
}
public function getSignatureRentalContractDate(): ?DateTimeInterface
{
return $this->signatureRentalContractDate;
}
public function setSignatureRentalContractDate(?DateTimeInterface $signatureRentalContractDate): self
{
$this->signatureRentalContractDate = $signatureRentalContractDate;
return $this;
}
public function getReferenceRentalType(): ?ReferenceTransactionRentalType
{
return $this->referenceRentalType;
}
public function setReferenceRentalType(?ReferenceTransactionRentalType $referenceRentalType): self
{
$this->referenceRentalType = $referenceRentalType;
return $this;
}
public function getRentalPrice(): ?float
{
return $this->rentalPrice;
}
public function setRentalPrice(?float $rentalPrice): void
{
$this->rentalPrice = $rentalPrice;
}
public function calculateFees(Transaction $transaction): void
{
$this->calculateSellerCommission($transaction);
$this->calculateFeesWithTax();
$this->calculateFeesWithoutTax();
}
private function calculateSellerCommission(Transaction $transaction): void
{
$mandate = $this->getMandate();
$transaction->getSellerCommission() !== $mandate->getCommission()
? $this->setSellerCommission((float) $transaction->sellerCommission)
: $this->setSellerCommission((float) $mandate->getCommission());
}
private function calculateFeesWithoutTax(): void
{
$feesWithoutTax = (100 * $this->getFeesWithTax()) / (100 + ($this->getVat()->getTax() * 100));
$this->setFeesWithoutTax($feesWithoutTax);
}
private function calculateFeesWithTax(): void
{
$sellerCommission = $this->getSellerCommission();
$buyerCommission = $this->getBuyerCommission();
$feesWithTax = (float) $sellerCommission + (float) $buyerCommission;
$this->setFeesWithTax($feesWithTax);
}
/**
* @return array
*/
public function getFields(): array
{
return [
'referenceTransactionStatus' => 'referenceTransactionStatus',
'contact' => 'contact',
'sellerCommission' => 'sellerCommission',
'rentalPrice' => 'rentalPrice',
'invoiceDate' => 'invoiceDate',
'advance' => 'advance'
];
}
}