<?php
namespace App\Entity\Channel;
use App\Entity\Account\User;
use App\Entity\Channel\Google\ChannelGoogleDriveFolder;
use App\Entity\Sync\SyncableInterface;
use App\Enum\ChannelStatusEnum;
use App\Repository\Channel\ChannelRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Drosalys\Bundle\ApiBundle\Serializer\Attributes\IdGroups;
use DrosalysWeb\ObjectExtensions\Blame\Model\BlameInterface;
use DrosalysWeb\ObjectExtensions\Blame\Model\BlameTrait;
use DrosalysWeb\ObjectExtensions\Timestamp\Model\TimestampInterface;
use DrosalysWeb\ObjectExtensions\Timestamp\Model\TimestampTrait;
use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelInterface;
use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelMethodTrait;
use Nellapp\Bundle\SDKBundle\Channel\Entity\ChannelWhiteLabel\ChannelWhiteLabelInterface;
use Nellapp\Bundle\SDKBundle\Sync\EntityKeys;
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation as Serial;
use Symfony\Component\Validator\Constraints as Assert;
#[
ORM\Entity(repositoryClass: ChannelRepository::class),
ORM\Table(name: 'channel_channels'),
ORM\Index(columns: ['name'], flags: ['fulltext']),
]
class Channel implements TimestampInterface, BlameInterface, SyncableInterface, ChannelInterface
{
use ChannelMethodTrait;
use BlameTrait;
use TimestampTrait;
#[ORM\Id, ORM\GeneratedValue(strategy: 'CUSTOM'), ORM\CustomIdGenerator(class: UuidGenerator::class), ORM\Column(type: 'string', length: 36)]
#[Serial\Groups(['Manager', 'Sync', 'GlobalJSVariable', 'partner_api_channels_index'])]
private ?string $id = null;
#[ORM\Column(type: 'string', length: 63)]
#[Serial\Groups(['Manager', 'Sync', 'GlobalJSVariable', 'partner_api_channels_index'])]
#[Assert\NotBlank(
message: 'channel.channel.name.NotBlank',
)]
#[Assert\Length(
min: 2,
max: 63,
minMessage: 'channel.channel.name.Length.min',
maxMessage: 'channel.channel.name.Length.max',
)]
private ?string $name = null;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Assert\Length(
min: 5,
max: 255,
minMessage: 'channel.channel.slogan.Length.min',
maxMessage: 'channel.channel.slogan.Length.max'
)]
private ?string $slogan = null;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Serial\Groups(['partner_api_channels_index'])]
#[Assert\Length(
max: 255,
maxMessage: 'channel.channel.slogan.Length.max'
)]
private ?string $website = null;
#[ORM\Column(type: 'string', length: 20, nullable: true)]
#[Serial\Groups(['partner_api_channels_index'])]
#[Assert\Length(
min: 8,
max: 20,
minMessage: 'user.entity.phone.Length.min',
maxMessage: 'user.entity.phone.Length.max'
)
]
private ?string $phoneNumber = null;
#[ORM\Column(type: 'boolean', nullable: false)]
#[Serial\Groups(['Sync'])]
#[Assert\Type(
type: 'boolean',
message: 'channel.channel.approved.Type',
)]
private bool $approved = false;
#[ORM\Column(type: 'boolean', nullable: false)]
private bool $canShareContent = false;
#[ORM\ManyToOne(targetEntity: User::class), ORM\JoinColumn(nullable: false)]
#[IdGroups(['Manager', 'Sync'])]
#[Assert\NotNull(
message: 'channel.channel.owner.NotNull',
)]
private ?User $owner = null;
#[ORM\OneToMany(mappedBy: 'channel', targetEntity: Organization::class, cascade: ['persist'], fetch: 'LAZY', orphanRemoval: true)]
private Collection $organizations;
#[ORM\Column(type: 'text', nullable: true)]
#[Serial\Groups(['Sync'])]
private ?string $imagePath = null;
#[ORM\Column(type: 'boolean', nullable: false, options: ['default' => false])]
#[Serial\Groups(['Sync'])]
private bool $paymentAlert = false;
#[ORM\Column(type: 'boolean', nullable: false, options: ['default' => false])]
private bool $sepaMandate = false;
#[ORM\Column(type: 'integer', nullable: false, options: ['default' => 2000])] // => default 20%
private int $tva = 2000;
#[ORM\Column(type: 'integer', nullable: false, options: ['default' => ChannelStatusEnum::ACTIVE])]
private int $status = ChannelStatusEnum::ACTIVE;
#[ORM\OneToMany(mappedBy: 'channel', targetEntity: ChannelUserRole::class, cascade: ['persist', 'remove'], fetch: 'LAZY', orphanRemoval: true)]
private ?Collection $channelUserRoles;
#[ORM\OneToOne(mappedBy: 'channel', targetEntity: ChannelWhiteLabel::class, cascade: ['persist', 'remove'], fetch: 'LAZY', orphanRemoval: true)]
private ?ChannelWhiteLabel $whiteLabel = null;
#[ORM\Column(type: 'boolean', nullable: false, options: ['default' => false])]
#[Serial\Groups(['Sync'])]
private bool $enabledIndexing = false;
#[ORM\Column(type: 'boolean', nullable: false, options: ['default' => false])]
#[Serial\Groups(['Sync'])]
private bool $enabledChatBot = false;
#[ORM\Column(type: 'boolean', nullable: false, options: ['default' => true])]
#[Serial\Groups(['Sync'])]
private bool $tuaProposal = true;
#[ORM\OneToOne(inversedBy: 'channel', targetEntity: ChannelGoogleDriveFolder::class, cascade: ['persist', 'remove'], fetch: 'EXTRA_LAZY', orphanRemoval: true)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
private ?ChannelGoogleDriveFolder $channelGoogleDriveFolder = null;
#[ORM\OneToOne(inversedBy: 'channel', targetEntity: ChannelConfiguration::class, cascade: ['persist', 'remove'], fetch: 'LAZY', orphanRemoval: true)]
#[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')]
private ?ChannelConfiguration $configuration = null;
public function __construct()
{
$this->channelUserRoles = new ArrayCollection();
$this->organizations = new ArrayCollection();
}
public static function getSyncKey(): string
{
return EntityKeys::CHANNEL;
}
public function getSyncDisplayLabel(): string
{
return $this->__toString();
}
public function toggleApproved(): static
{
$this->approved = !$this->approved;
return $this;
}
public function togglePaymentAlert(): static
{
$this->paymentAlert = !$this->paymentAlert;
return $this;
}
public function isOwner(?UserInterface $user): bool
{
return $user && $this->owner->isEqualTo($user);
}
public function getOrganizations(): Collection
{
return $this->organizations ?? $this->organizations = new ArrayCollection();
}
public function setOrganizations(Collection $organizations): Channel
{
$this->organizations = $organizations;
return $this;
}
public function addOrganization(Organization $organization): Channel
{
if (!$this->getOrganizations()->contains($organization)) {
$this->getOrganizations()->add($organization);
$organization->setChannel($this);
}
return $this;
}
public function getWebsite(): ?string
{
return $this->website;
}
public function setWebsite(?string $website): Channel
{
$this->website = $website;
return $this;
}
public function getPhoneNumber(): ?string
{
return $this->phoneNumber;
}
public function setPhoneNumber(?string $phoneNumber): Channel
{
$this->phoneNumber = $phoneNumber;
return $this;
}
public function isSepaMandate(): bool
{
return $this->sepaMandate;
}
public function setSepaMandate(bool $sepaMandate): Channel
{
$this->sepaMandate = $sepaMandate;
return $this;
}
public function toggleSepaMandate(): Channel
{
$this->sepaMandate = !$this->sepaMandate;
return $this;
}
public function getTva(): int
{
return $this->tva;
}
public function setTva(int $tva): void
{
$this->tva = $tva;
}
public function getTvaDisplayed(): float
{
return $this->tva / 100;
}
public function getStatus(): int
{
return $this->status;
}
public function setStatus(int $status): Channel
{
$this->status = $status;
return $this;
}
public function toggleStatus(): Channel
{
$this->status = !$this->status;
return $this;
}
public function getChannelUserRoles(): Collection
{
return $this->channelUserRoles ?? $this->channelUserRoles = new ArrayCollection();
}
public function setChannelUserRoles(?Collection $channelUserRoles): Channel
{
$this->channelUserRoles = $channelUserRoles;
return $this;
}
public function addChannelUserRole(ChannelUserRole $channelUserRole): static
{
if (!$this->getChannelUserRoles()->contains($channelUserRole)) {
$this->getChannelUserRoles()->add($channelUserRole);
$channelUserRole->setChannel($this);
}
return $this;
}
public function getWhiteLabel(): ?ChannelWhiteLabelInterface
{
return $this->whiteLabel;
}
public function setWhiteLabel(?ChannelWhiteLabelInterface $whiteLabel): static
{
$this->whiteLabel = $whiteLabel;
return $this;
}
public function toggleEnabledChatBot(): static
{
$this->enabledChatBot = !$this->enabledChatBot;
return $this;
}
public function isTuaProposal(): bool
{
return $this->tuaProposal;
}
public function setTuaProposal(bool $tuaProposal): static
{
$this->tuaProposal = $tuaProposal;
return $this;
}
public function toggleTuaProposal(): static
{
$this->tuaProposal = !$this->tuaProposal;
return $this;
}
public function getChannelGoogleDriveFolder(): ?ChannelGoogleDriveFolder
{
return $this->channelGoogleDriveFolder;
}
public function setChannelGoogleDriveFolder(?ChannelGoogleDriveFolder $channelGoogleDriveFolder): Channel
{
$this->channelGoogleDriveFolder = $channelGoogleDriveFolder;
return $this;
}
public function isEnabledGoogleDrive(): bool
{
return $this->getChannelGoogleDriveFolder() !== null;
}
public function getConfiguration(): ?ChannelConfiguration
{
return $this->configuration;
}
public function setConfiguration(?ChannelConfiguration $configuration): static
{
$this->configuration = $configuration;
$this->configuration?->setChannel($this);
return $this;
}
}