<?php 
 
namespace App\Entity; 
 
use ApiPlatform\Doctrine\Orm\Filter\DateFilter; 
use App\Controller\Action\AttachFileController; 
use App\Controller\Action\DocumentDeleteFileController; 
use App\Controller\Action\DocumentRecapEvalStatController; 
use App\Controller\Action\DocumentSiteDeleteActionController; 
use App\Controller\Action\UploadFileController; 
use App\Filter\DocumentFilter; 
use App\Repository\EvaluationRepository; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\EntityManagerInterface; 
use Doctrine\ORM\Mapping as ORM; 
use ApiPlatform\Metadata\ApiResource; 
use App\Traits\AutoTimestampTrait; 
use Doctrine\ORM\Mapping\PreUpdate; 
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; 
use App\Controller\Action\DocumentWithEvaluationStatAction; 
use App\Controller\Action\DocumentWithSiteStatActionController; 
use Doctrine\DBAL\Types\Types; 
use Doctrine\ORM\Mapping\PrePersist; 
 
#[ORM\Table(name: 'document')] 
#[ORM\Entity] 
#[ApiResource( 
    normalizationContext: ['skip_null_values' => false, 'datetime_format' => 'Y-m-d', 'groups' => ['document.get']], 
    denormalizationContext: ['skip_null_values' => false, 'groups' => ['document.write']], 
 
    operations: [ 
        new GetCollection(), 
        new GetCollection( 
            name: '_api_/documents/with_stat', 
            uriTemplate: '/documents/with_stat', 
            controller: DocumentWithEvaluationStatAction::class, 
            write: false, 
            read: false 
        ), 
        new GetCollection( 
            name: '_api_/documents/recap_eval_stat', 
            uriTemplate: '/documents/recap_eval_stat', 
            controller: DocumentRecapEvalStatController::class, 
            write: false, 
            read: false 
        ), 
        new Post( 
            name: '_api_/documents/with_site_stat', 
            uriTemplate: '/documents/with_site_stat', 
            controller: DocumentWithSiteStatActionController::class, 
            write: false, 
            read: false 
        ), 
        new GetCollection( 
            name: '_api_/documents/attach_files', 
            uriTemplate: '/documents/attach_files', 
            controller: AttachFileController::class, 
            write: false, 
            read: false 
        ), 
        new Post( 
            security: 'user.isMasterAdmin()', 
        ), 
        new Post( 
            name: '_api_/delete_document_site', 
            uriTemplate: '/delete_document_site', 
            controller: DocumentSiteDeleteActionController::class, 
            write: false, 
            read: false 
        ), 
        new Get(), 
        new Put( 
            security: 'user.isMasterAdmin()', 
        ), 
        new Delete( 
            name: '_api_/documents/delete_file', 
            uriTemplate: '/documents/delete_file', 
            controller: DocumentDeleteFileController::class, 
            write: false, 
            read: false 
        ), 
        new Delete( 
            security: 'user.isMasterAdmin()', 
        ), 
    ] 
)] 
#[ApiFilter( 
    SearchFilter::class, 
    properties: [ 
        'id' => 'exact', 
        'evaluations.site' => 'exact', 
       // 'term' => 'partial', 
        'affectations.site' => 'exact', 
        'theme' => 'exact', 
        'domain' => 'exact', 
        'subDomain' => 'exact', 
        'isConfidential' => 'exact' 
    ] 
)] 
 
#[ApiFilter(DocumentFilter::class)] 
#[ORM\HasLifecycleCallbacks] 
class Document 
{ 
    use AutoTimestampTrait; 
 
    #[ORM\Column(name: 'id', type: 'integer', nullable: false)] 
    #[ORM\Id] 
    #[ORM\GeneratedValue(strategy: 'IDENTITY')] 
    #[Groups(['document.get', 'plan.get'])] 
    private int $id; 
 
    #[ORM\Column(name: 'old_id', type: 'string', length: 255, nullable: true)] 
    private ?string $oldId = null; 
 
    #[ORM\Column(name: 'title', type: Types::TEXT, length: 16777215, nullable: true)] 
    #[Groups(['document.get', 'document.write', 'plan.get'])] 
    private ?string $title = null; 
 
    #[ORM\Column(name: 'description', type: 'text', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $description = null; 
 
    #[ORM\Column(name: 'document_type', type: 'string', length: 255, nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $documentType = null; 
 
    #[ORM\Column(name: 'is_confidential', type: 'boolean', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?bool $isConfidential = false; 
 
    #[ORM\Column(name: 'comment', type: 'text', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $comment = null; 
 
    #[ORM\Column(name: 'application_fields', type: 'text', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $applicationFields = null; 
 
    #[ORM\Column(name: 'last_updated_at', type: 'datetime', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    #[ApiFilter(DateFilter::class)] 
    private $lastUpdatedAt; 
 
    #[ORM\Column(name: 'dated_at', type: 'datetime', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    #[ApiFilter(DateFilter::class)] 
    private $datedAt; 
 
    #[ORM\Column(name: 'update_reason', type: 'text', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $updateReason = null; 
 
    #[ORM\Column(name: 'summary_file_name', type: 'string', length: 255, nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $summaryFileName = null; 
 
    #[ORM\Column(name: 'illustrations_file_name', type: 'string', length: 255, nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $illustrationsFileName = null; 
 
    #[ORM\Column(name: 'url', type: 'text', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $url = null; 
 
    #[ORM\Column(name: 'is_applicable', type: 'boolean', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?bool $isApplicable = null; 
 
    #[ORM\ManyToOne] 
    #[ORM\JoinColumn(nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?Category $theme = null; 
 
    #[ORM\ManyToOne] 
    #[ORM\JoinColumn(nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?Category $domain = null; 
 
    #[ORM\ManyToOne] 
    #[ORM\JoinColumn(nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?Category $subDomain = null; 
 
    #[ORM\ManyToOne] 
    #[Groups(['document.get', 'document.write'])] 
    private ?Country $country = null; 
 
    #[ORM\OneToMany(mappedBy: 'document', targetEntity: Affectation::class, cascade: ['persist'], orphanRemoval: true)] 
    #[Groups(['document.write', 'document.affectation.get'])] 
    private Collection $affectations; 
 
    #[ORM\OneToMany(mappedBy: 'document', targetEntity: Compliance::class)] 
    private Collection $compliances; 
 
    #[Groups(['document.get'])] 
    #[ORM\Column(type: 'datetime')] 
    protected $updatedAt; 
 
    #[Groups(['document.get'])] 
    #[ORM\Column(type: 'datetime')] 
    protected $createdAt; 
 
    #[ORM\Column(type: 'datetime', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    #[ApiFilter(DateFilter::class)] 
    private $creationAt = null; 
 
    #[ORM\Column(name: 'status', type: 'integer', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?int $status = null; 
 
    #[ORM\OneToMany(mappedBy: 'document', targetEntity: Evaluation::class)] 
    private Collection $evaluations; 
 
    #[ApiProperty()] 
    #[Groups(['document.get'])] 
    private int $conformity; 
 
    #[ApiProperty()] 
    #[Groups(['document.get'])] 
    private int $progression; 
 
 
    #[ORM\OneToMany(mappedBy: 'document', targetEntity: Section::class)] 
    private Collection $sections; 
 
    #[ORM\Column(type: Types::TEXT, nullable: true)] 
    private ?string $term = null; 
 
    #[ORM\Column(type: Types::TEXT, nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?string $annotationNovallia = null; 
    #[ORM\ManyToOne(inversedBy: 'illustrationsFile')] 
    #[Groups(['document.get', 'document.write'])] 
    private ?Media $illustrationsFile = null; 
 
    #[ORM\ManyToOne(inversedBy: 'summaryFile')] 
    #[Groups(['document.get', 'document.write'])] 
    private ?Media $summaryFile = null; 
 
    #[ORM\Column(name: 'last_update_compliance', type: 'datetime', nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?\DateTimeInterface $lastUpdateCompliance = null; 
 
    #[ORM\OneToMany(mappedBy: 'document', targetEntity: Discussion::class)] 
    private Collection $discussions; 
 
    #[ORM\Column(nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?bool $localTextRte = null; 
 
    #[ORM\ManyToOne] 
    #[Groups(['document.get', 'document.write'])] 
    private ?User $updatedBy = null; 
 
    #[ORM\Column(nullable: true)] 
    #[Groups(['document.get', 'document.write'])] 
    private ?bool $dashboardRatp = null; 
 
    public function __construct() 
    { 
        $this->affectations = new ArrayCollection(); 
        $this->evaluations = new ArrayCollection(); 
        $this->sections = new ArrayCollection(); 
        $this->discussions = 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 getTitle(): ?string 
    { 
        return $this->title; 
    } 
 
    public function setTitle(?string $title): self 
    { 
        $this->title = $title; 
 
        return $this; 
    } 
 
    public function getDescription(): ?string 
    { 
        return $this->description; 
    } 
 
    public function setDescription(?string $description): self 
    { 
        $this->description = $description; 
 
        return $this; 
    } 
 
    public function getDocumentType(): ?string 
    { 
        return $this->documentType; 
    } 
 
    public function setDocumentType(?string $documentType): self 
    { 
        $this->documentType = $documentType; 
 
        return $this; 
    } 
 
    public function isIsConfidential(): ?bool 
    { 
        return $this->isConfidential; 
    } 
 
    public function setIsConfidential(?bool $isConfidential): self 
    { 
        $this->isConfidential = $isConfidential; 
 
        return $this; 
    } 
 
    public function getComment(): ?string 
    { 
        return $this->comment; 
    } 
 
    public function setComment(?string $comment): self 
    { 
        $this->comment = $comment; 
 
        return $this; 
    } 
 
    public function getApplicationFields(): ?string 
    { 
        return $this->applicationFields; 
    } 
 
    public function setApplicationFields(?string $applicationFields): self 
    { 
        $this->applicationFields = $applicationFields; 
 
        return $this; 
    } 
 
    public function getLastUpdatedAt(): ?\DateTimeInterface 
    { 
        return $this->lastUpdatedAt; 
    } 
 
    public function setLastUpdatedAt(?\DateTimeInterface $lastUpdatedAt): self 
    { 
        $this->lastUpdatedAt = $lastUpdatedAt; 
 
        return $this; 
    } 
 
    public function getDatedAt(): ?\DateTimeInterface 
    { 
        return $this->datedAt; 
    } 
 
    public function setDatedAt(?\DateTimeInterface $datedAt): self 
    { 
        $this->datedAt = $datedAt; 
 
        return $this; 
    } 
 
    public function getUpdateReason(): ?string 
    { 
        return $this->updateReason; 
    } 
 
    public function setUpdateReason(?string $updateReason): self 
    { 
        $this->updateReason = $updateReason; 
 
        return $this; 
    } 
 
    public function getSummaryFileName(): ?string 
    { 
        return $this->summaryFileName; 
    } 
 
    public function setSummaryFileName(?string $summaryFileName): self 
    { 
        $this->summaryFileName = $summaryFileName; 
 
        return $this; 
    } 
 
    public function getIllustrationsFileName(): ?string 
    { 
        return $this->illustrationsFileName; 
    } 
 
    public function setIllustrationsFileName(?string $illustrationsFileName): self 
    { 
        $this->illustrationsFileName = $illustrationsFileName; 
 
        return $this; 
    } 
 
    public function getUrl(): ?string 
    { 
        return $this->url; 
    } 
 
    public function setUrl(?string $url): self 
    { 
        $this->url = $url; 
 
        return $this; 
    } 
 
    public function isIsApplicable(): ?bool 
    { 
        return $this->isApplicable; 
    } 
 
    public function setIsApplicable(?bool $isApplicable): self 
    { 
        $this->isApplicable = $isApplicable; 
 
        return $this; 
    } 
 
    public function getTheme(): ?Category 
    { 
        return $this->theme; 
    } 
 
    public function setTheme(?Category $theme): self 
    { 
        $this->theme = $theme; 
 
        return $this; 
    } 
 
    public function getDomain(): ?Category 
    { 
        return $this->domain; 
    } 
 
    public function setDomain(?Category $domain): self 
    { 
        $this->domain = $domain; 
 
        return $this; 
    } 
 
    public function getSubDomain(): ?Category 
    { 
        return $this->subDomain; 
    } 
 
    public function setSubDomain(?Category $subDomain): self 
    { 
        $this->subDomain = $subDomain; 
 
        return $this; 
    } 
 
    public function getCountry(): ?Country 
    { 
        return $this->country; 
    } 
 
    public function setCountry(?Country $country): self 
    { 
        $this->country = $country; 
 
        return $this; 
    } 
 
    public function getStatus(): ?string 
    { 
        return $this->status; 
    } 
 
    public function setStatus(?string $status): self 
    { 
        $this->status = $status; 
 
        return $this; 
    } 
 
    /** 
     * @return Collection<int, Affectation> 
     */ 
    public function getAffectations(): Collection 
    { 
        return $this->affectations; 
    } 
 
    public function addAffectation(Affectation $affectation): self 
    { 
        if (!$this->affectations->contains($affectation)) { 
            $this->affectations->add($affectation); 
            $affectation->setDocument($this); 
        } 
 
        return $this; 
    } 
 
    public function removeAffectation(Affectation $affectation): self 
    { 
        if ($this->affectations->removeElement($affectation)) { 
            if ($affectation->getDocument() === $this) { 
                $affectation->setDocument(null); 
            } 
        } 
 
        return $this; 
    } 
 
    public function getCreationAt() 
    { 
        return $this->creationAt; 
    } 
 
    public function setCreationAt($creationAt): self 
    { 
        $this->creationAt = $creationAt; 
 
        return $this; 
    } 
 
    /** 
     * @return Collection<int, Compliance> 
     */ 
    public function getCompliances(): Collection 
    { 
        return $this->compliances; 
    } 
 
    public function getDocumentStatus(): ?int 
    { 
        return $this->documentStatus; 
    } 
 
    public function setDocumentStatus(?int $documentStatus): self 
    { 
        $this->documentStatus = $documentStatus; 
 
        return $this; 
    } 
 
    /** 
     * @return Collection<int, Evaluation> 
     */ 
    public function getEvaluations(): Collection 
    { 
        return $this->evaluations; 
    } 
 
    public function addEvaluation(Evaluation $evaluation): self 
    { 
        if (!$this->evaluations->contains($evaluation)) { 
            $this->evaluations->add($evaluation); 
            $evaluation->setDocument($this); 
        } 
 
        return $this; 
    } 
 
    public function removeEvaluation(Evaluation $evaluation): self 
    { 
        if ($this->evaluations->removeElement($evaluation)) { 
            // set the owning side to null (unless already changed) 
            if ($evaluation->getDocument() === $this) { 
                $evaluation->setDocument(null); 
            } 
        } 
 
        return $this; 
    } 
 
    public function getConformity(): int 
    { 
        return $this->conformity; 
    } 
 
    public function setConformity(int $conformity): self 
    { 
        $this->conformity = $conformity; 
 
        return $this; 
    } 
 
    public function getProgression(): int 
    { 
        return $this->progression; 
    } 
 
    public function setProgression(int $progression): self 
    { 
        $this->progression = $progression; 
 
        return $this; 
    } 
 
    /** 
     * @return Collection 
     */ 
    public function getSections(): Collection 
    { 
        return $this->sections; 
    } 
 
    #[Groups(['document.get'])] 
    public function getLiveStatus() 
    { 
        $updatedDaysAgo = false; 
        $lastUpdateComplianceAgo = false; 
        $createdDaysAgo = 365; 
        if ($this->status) { 
            $status = $this->status; 
        } else { 
            $status = 39; 
        } 
        if (!empty($this->datedAt)) 
            $createdDaysAgo = (new \DateTimeImmutable('now'))->diff($this->datedAt)->format('%a'); 
        if (!empty($this->lastUpdatedAt)) 
            $updatedDaysAgo = (new \DateTimeImmutable('now'))->diff($this->lastUpdatedAt)->format('%a'); 
        if (!empty($this->lastUpdateCompliance)) 
            $lastUpdateComplianceAgo = (new \DateTimeImmutable('now'))->diff($this->lastUpdateCompliance)->format('%a'); 
 
        $documentStatusDaysAgo = EvaluationRepository::DOCUMENT_STATUS_DAYS_AGO; 
 
        if (($this->status === DocumentStatus::UNDER_PROJECT_STATUS) 
            || ($this->status === DocumentStatus::UNDER_PROJECT_STATUS) 
        ) { 
            $status = $this->status; 
        } 
        else if ($this->status === DocumentStatus::REPEALED_STATUS){ 
            $status = $this->status; 
        } 
        else if (isset($createdDaysAgo) && ($createdDaysAgo === 0 || $createdDaysAgo === "0" || !empty($createdDaysAgo)) && $createdDaysAgo < $documentStatusDaysAgo) { 
            $status = DocumentStatus::NEW_STATUS; 
 
 
        } else if ((isset($updatedDaysAgo) && ($updatedDaysAgo === 0 || $updatedDaysAgo === "0" || !empty($updatedDaysAgo)) && $updatedDaysAgo < $documentStatusDaysAgo) 
            || (isset($lastUpdateComplianceAgo) && ($lastUpdateComplianceAgo === 0 || $lastUpdateComplianceAgo === "0" || !empty($lastUpdateComplianceAgo)) && $lastUpdateComplianceAgo < $documentStatusDaysAgo)) { 
 
            $status = DocumentStatus::EDITED_STATUS; 
        } 
 
        return DocumentStatus::STATUSES[$status]; 
    } 
 
    public function getTerm(): ?string 
    { 
        return $this->term; 
    } 
 
    public function setTerm(?string $term): self 
    { 
        $this->term = $term; 
 
        return $this; 
    } 
 
    #[PrePersist] 
    #[PreUpdate] 
    public function updateTerm() 
    { 
        $this->term = $this->title . " " . $this->description; 
    } 
 
    public function getAnnotationNovallia(): ?string 
    { 
        return $this->annotationNovallia; 
    } 
 
    public function setAnnotationNovallia(?string $annotationNovallia): self 
    { 
        $this->annotationNovallia = $annotationNovallia; 
 
        return $this; 
    } 
 
    public function getIllustrationsFile(): ?Media 
    { 
        return $this->illustrationsFile; 
    } 
 
    public function setIllustrationsFile(?Media $illustrationsFile): self 
    { 
        $this->illustrationsFile = $illustrationsFile; 
 
        return $this; 
    } 
 
    public function getSummaryFile(): ?Media 
    { 
        return $this->summaryFile; 
    } 
 
    public function setSummaryFile(?Media $summaryFile): self 
    { 
        $this->summaryFile = $summaryFile; 
 
        return $this; 
    } 
 
    public function getLastUpdateCompliance(): ?\DateTimeInterface 
    { 
        return $this->lastUpdateCompliance; 
    } 
 
    public function setLastUpdateCompliance(?\DateTimeInterface $lastUpdateCompliance): self 
    { 
        $this->lastUpdateCompliance = $lastUpdateCompliance; 
 
        return $this; 
    } 
 
    /** 
     * @return Collection<int, Discussion> 
     */ 
    public function getDiscussions(): Collection 
    { 
        return $this->discussions; 
    } 
 
    public function addDiscussion(Discussion $discussion): self 
    { 
        if (!$this->discussions->contains($discussion)) { 
            $this->discussions->add($discussion); 
            $discussion->setDocument($this); 
        } 
 
        return $this; 
    } 
 
    public function removeDiscussion(Discussion $discussion): self 
    { 
        if ($this->discussions->removeElement($discussion)) { 
            // set the owning side to null (unless already changed) 
            if ($discussion->getDocument() === $this) { 
                $discussion->setDocument(null); 
            } 
        } 
 
        return $this; 
    } 
 
    public function isLocalTextRte(): ?bool 
    { 
        return $this->localTextRte; 
    } 
 
    public function setLocalTextRte(?bool $localTextRte): self 
    { 
        $this->localTextRte = $localTextRte; 
 
        return $this; 
    } 
 
    public function getUpdatedBy(): ?User 
    { 
        return $this->updatedBy; 
    } 
 
    public function setUpdatedBy(?User $updatedBy): self 
    { 
        $this->updatedBy = $updatedBy; 
 
        return $this; 
    } 
 
    public function isDashboardRatp(): ?bool 
    { 
        return $this->dashboardRatp; 
    } 
 
    public function setDashboardRatp(?bool $dashboardRatp): self 
    { 
        $this->dashboardRatp = $dashboardRatp; 
 
        return $this; 
    } 
}