<?php
namespace App\Entity;
use App\Repository\EvaluationRepository;
use App\State\CompliancePostProcessor;
use App\State\CompliancePutProcessor;
use App\State\ComplianceDeleteProcessor;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Traits\AutoTimestampTrait;
use ApiPlatform\Metadata\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
#[ORM\Table(name: 'compliance')]
#[ORM\Index(name: 'section_id', columns: ['section_id'])]
#[ORM\Entity]
#[ORM\HasLifecycleCallbacks]
#[ApiResource(
order: ['ranked' => 'ASC'],
normalizationContext: ['groups' => ['compliance.get', 'compliance.write']],
operations: [
new GetCollection(),
new Post(
security: 'user.isMasterAdmin()',
processor: CompliancePostProcessor::class
),
new Get(),
new Put(
security: 'user.isMasterAdmin()',
processor: CompliancePutProcessor::class
),
new Delete(
security: 'user.isMasterAdmin()',
processor: ComplianceDeleteProcessor::class
)
]
)]
#[ApiFilter(
SearchFilter::class, properties: [
'evaluations.site' => 'exact',
'title' => 'partial',
'document' => 'exact',
'section' => 'exact',
'evaluations.document' => 'exact',
]
)]
class Compliance
{
use AutoTimestampTrait;
#[ORM\Column(name: 'id', type: 'integer', nullable: false)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
#[Groups(['compliance.get', 'plan.get'])]
private int $id;
#[ORM\Column(name: 'old_id', type: 'string', length: 255, nullable: true)]
private ?string $oldId = null;
#[ORM\Column(name: 'deadline_at', type: 'datetime', nullable: true)]
#[Groups('compliance.get')]
private $deadlineAt;
#[ORM\Column(name: 'title', type: 'text', length: 65535)]
#[Groups(['compliance.get','plan.get'])]
private ?string $title;
#[ORM\Column(name: 'ranked', type: 'integer')]
#[Groups('compliance.get')]
private int $ranked = 1;
#[ORM\Column(name: 'is_applicable', type: 'boolean')]
#[Groups('compliance.get')]
private bool $isApplicable = true;
#[ORM\JoinColumn(name: 'section_id', referencedColumnName: 'id')]
#[ORM\ManyToOne(targetEntity: 'Section', inversedBy: 'compliances')]
#[Groups(['plan.get'])]
private Section $section;
#[ORM\JoinColumn(name: 'text_id', referencedColumnName: 'id')]
#[ORM\ManyToOne(targetEntity: 'Document', inversedBy: 'compliances')]
#[Groups('compliance.get')]
private Document $document;
#[ORM\OneToMany(mappedBy: 'compliance', targetEntity: Evaluation::class)]
#[Groups('compliance:evaluation:get')]
private Collection $evaluations;
#[Groups('compliance.get')]
private ?int $conformity;
#[Groups('compliance.get')]
private ?int $progress;
#[ORM\ManyToOne(inversedBy: 'evaluations', targetEntity: 'EvaluationStatus')]
#[ORM\JoinColumn(nullable: true)]
#[Groups(['compliance.get'])]
private $status = null;
#[ORM\Column(name: 'annotation_compliance', type: 'text', nullable: true)]
#[Groups(['compliance.get'])]
private ?string $annotationCompliance = null;
#[ORM\Column(name: 'last_update_compliance', type: 'datetime', nullable: true)]
#[Groups('compliance.get')]
private ?\DateTimeInterface $lastUpdateCompliance = null;
#[ORM\Column(nullable: true)]
private ?int $version = null;
#[ORM\Column(type: 'text', nullable: true)]
private ?string $defaultPaTitle = null;
#[ORM\ManyToOne]
#[Groups('compliance.get')]
private ?User $updatedBy = null;
#[ORM\Column(type: 'text', nullable: true)]
#[Groups(['compliance.get','plan.get'])]
private ?string $titleRte = null;
public function __construct()
{
$this->evaluations = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getOldId(): ?string
{
return $this->oldId;
}
public function setOldId(?string $oldId): self
{
$this->oldId = $oldId;
return $this;
}
public function getDeadlineAt(): ?\DateTimeInterface
{
return $this->deadlineAt;
}
public function setDeadlineAt(?\DateTimeInterface $deadlineAt): self
{
$this->deadlineAt = $deadlineAt;
return $this;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(?string $title): self
{
$this->title = $title;
return $this;
}
public function getRanked(): int
{
return $this->ranked;
}
public function setRanked(int $ranked): self
{
$this->ranked = $ranked;
return $this;
}
public function isIsApplicable(): bool
{
return $this->isApplicable;
}
public function setIsApplicable(bool $isApplicable): self
{
$this->isApplicable = $isApplicable;
return $this;
}
public function getSection(): Section
{
return $this->section;
}
public function setSection(Section $section): self
{
$this->section = $section;
return $this;
}
public function getDocument(): Document
{
return $this->document;
}
public function setDocument(Document $document): self
{
$this->document = $document;
return $this;
}
/**
* @return Collection<int, self>
*/
public function getEvaluations(): Collection
{
return $this->evaluations;
}
public function addEvaluation(self $evaluation): self
{
if (!$this->evaluations->contains($evaluation)) {
$this->evaluations->add($evaluation);
$evaluation->setCompliance($this);
}
return $this;
}
public function removeEvaluation(self $evaluation): self
{
if ($this->evaluations->removeElement($evaluation)) {
// set the owning side to null (unless already changed)
if ($evaluation->getCompliance() === $this) {
$evaluation->setCompliance(null);
}
}
return $this;
}
public function getConformity(): int
{
return $this->conformity;
}
public function setConformity(int $conformity): self
{
$this->conformity = $conformity;
return $this;
}
public function getProgress(): int
{
return $this->progress;
}
public function setProgress(int $progress): self
{
$this->progress = $progress;
return $this;
}
/**
* @return null
*/
public function getStatus()
{
return $this->status;
}
/**
* @param null $status
*/
public function setStatus($status): void
{
$this->status = $status;
}
/**
* @return string|null
*/
public function getAnnotationCompliance(): ?string
{
return $this->annotationCompliance;
}
/**
* @param string|null $annotationCompliance
*/
public function setAnnotationCompliance(?string $annotationCompliance): void
{
$this->annotationCompliance = $annotationCompliance;
}
/**
* @return \DateTimeInterface|null
*/
public function getLastUpdateCompliance(): ?\DateTimeInterface
{
return $this->lastUpdateCompliance;
}
/**
* @param \DateTimeInterface|null $lastUpdateCompliance
*/
public function setLastUpdateCompliance(?\DateTimeInterface $lastUpdateCompliance): self
{
$this->lastUpdateCompliance = $lastUpdateCompliance;
return $this;
}
#[Groups(['compliance.get'])]
public function getLiveStatus()
{
$lastUpdateComplianceAgo= false;
if (!empty($this->lastUpdateCompliance))
$lastUpdateComplianceAgo = (new \DateTimeImmutable('now'))->diff($this->lastUpdateCompliance)->format('%a');
$documentStatusDaysAgo = EvaluationRepository::DOCUMENT_STATUS_DAYS_AGO;
if ($this->status?->getId() === DocumentStatus::REPEALED_COMPLIANCE_STATUS){
$status = $this->status?->getId();
}
else if (!empty($this->lastUpdateCompliance) && $lastUpdateComplianceAgo < $documentStatusDaysAgo) {
$status = DocumentStatus::EDITED_STATUS;
}
else{
if ($this->status) {
$status = $this->status;
return '';
} else {
$status = 39;
}
}
return DocumentStatus::STATUSES[$status];
}
public function getVersion(): ?int
{
return $this->version;
}
public function setVersion(?int $version): self
{
$this->version = $version;
return $this;
}
public function getDefaultPaTitle(): ?string
{
return $this->defaultPaTitle;
}
public function setDefaultPaTitle(?string $defaultPaTitle): self
{
$this->defaultPaTitle = $defaultPaTitle;
return $this;
}
public function getUpdatedBy(): ?User
{
return $this->updatedBy;
}
public function setUpdatedBy(?User $updatedBy): self
{
$this->updatedBy = $updatedBy;
return $this;
}
public function getTitleRte(): ?string
{
return $this->titleRte;
}
public function setTitleRte(string $titleRte): self
{
$this->titleRte = $titleRte;
return $this;
}
}