src/Entity/Package.php line 16

  1. <?php
  2. namespace App\Entity;
  3. use App\Repository\PackageRepository;
  4. use App\Traits\TimeStampTrait;
  5. use Doctrine\Common\Collections\ArrayCollection;
  6. use Doctrine\Common\Collections\Collection;
  7. use Doctrine\DBAL\Types\Types;
  8. use Doctrine\ORM\Mapping as ORM;
  9. use Symfony\Component\Validator\Constraints as Assert;
  10. #[ORM\Entity(repositoryClassPackageRepository::class)]
  11. #[ORM\HasLifecycleCallbacks]
  12. class Package
  13. {
  14.     use TimeStampTrait;
  15.     public const STARTER 'Starter';
  16.     public const STANDARD 'Standard';
  17.     public const PRO 'Pro';
  18.     public const BUSINESS 'Business';
  19.     #[ORM\Id]
  20.     #[ORM\GeneratedValue]
  21.     #[ORM\Column(type'integer')]
  22.     private ?int $id null;
  23.     /**
  24.      * Billing type (e.g. "monthly", "yearly") or any internal categorization you use.
  25.      * Avoid “interval” (reserved in SQL).
  26.      */
  27.     #[ORM\Column(length100)]
  28.     #[Assert\NotBlank]
  29.     #[Assert\Length(max100)]
  30.     private ?string $type null;
  31.     #[ORM\Column(length255)]
  32.     #[Assert\NotBlank]
  33.     #[Assert\Length(max255)]
  34.     private ?string $description null;
  35.     #[ORM\Column(options: ['default' => true])]
  36.     private ?bool $publish true;
  37.     #[ORM\OneToMany(mappedBy'package'targetEntitySubscription::class)]
  38.     private Collection $entreprisePackages;
  39.     #[ORM\Column(length25)]
  40.     #[Assert\NotBlank]
  41.     #[Assert\Length(max25)]
  42.     private ?string $name null;
  43.     // Decimal columns map to string in PHP with Doctrine.
  44.     #[ORM\Column(typeTypes::DECIMALprecision10scale2)]
  45.     #[Assert\NotBlank]
  46.     #[Assert\Regex('/^\d+(\.\d{1,2})?$/')]
  47.     private ?string $price null// monthly price
  48.     #[ORM\OneToMany(mappedBy'package'targetEntityEntreprise::class)]
  49.     private Collection $entreprises;
  50.     #[ORM\Column(typeTypes::DECIMALprecision10scale2nullabletrue)]
  51.     #[Assert\Regex('/^\d+(\.\d{1,2})?$/')]
  52.     private ?string $priceannuel null;
  53.     /**
  54.      * Maximum allowed “lots/units” for this package. NULL = unlimited.
  55.      */
  56.     #[ORM\Column(type'integer'nullabletrueoptions: ['unsigned' => true])]
  57.     #[Assert\Positive]
  58.     private ?int $maxUnits null;
  59.     /**
  60.      * Number of free trial months (default: 2).
  61.      */
  62.     #[ORM\Column(type'smallint'options: ['unsigned' => true'default' => 2])]
  63.     #[Assert\PositiveOrZero]
  64.     private int $trialMonths 2;
  65.     public function __construct()
  66.     {
  67.         $this->entreprisePackages = new ArrayCollection();
  68.         $this->entreprises = new ArrayCollection();
  69.     }
  70.     // -----------------------
  71.     // Core getters / setters
  72.     // -----------------------
  73.     public function getId(): ?int
  74.     {
  75.         return $this->id;
  76.     }
  77.     public function setId(?int $id): void
  78.     {
  79.         $this->id $id;
  80.     }
  81.     public function getType(): ?string
  82.     {
  83.         return $this->type;
  84.     }
  85.     public function setType(?string $type): void
  86.     {
  87.         $this->type $type;
  88.     }
  89.     public function getDescription(): ?string
  90.     {
  91.         return $this->description;
  92.     }
  93.     public function setDescription(?string $description): void
  94.     {
  95.         $this->description $description;
  96.     }
  97.     public function getPublish(): ?bool
  98.     {
  99.         return $this->publish;
  100.     }
  101.     public function setPublish(?bool $publish): void
  102.     {
  103.         $this->publish $publish;
  104.     }
  105.     /**
  106.      * @return Collection<int, Subscription>
  107.      */
  108.     public function getEntreprisePackages(): Collection
  109.     {
  110.         return $this->entreprisePackages;
  111.     }
  112.     public function addEntreprisePackage(Subscription $entreprisePackage): static
  113.     {
  114.         if (!$this->entreprisePackages->contains($entreprisePackage)) {
  115.             $this->entreprisePackages->add($entreprisePackage);
  116.             $entreprisePackage->setPackage($this);
  117.         }
  118.         return $this;
  119.     }
  120.     public function removeEntreprisePackage(Subscription $entreprisePackage): static
  121.     {
  122.         if ($this->entreprisePackages->removeElement($entreprisePackage)) {
  123.             if ($entreprisePackage->getPackage() === $this) {
  124.                 $entreprisePackage->setPackage(null);
  125.             }
  126.         }
  127.         return $this;
  128.     }
  129.     public function getName(): ?string
  130.     {
  131.         return $this->name;
  132.     }
  133.     public function setName(string $name): static
  134.     {
  135.         $this->name $name;
  136.         return $this;
  137.     }
  138.     public function getPrice(): ?string
  139.     {
  140.         return $this->price;
  141.     }
  142.     public function setPrice(string $price): static
  143.     {
  144.         $this->price $price;
  145.         return $this;
  146.     }
  147.     /**
  148.      * @return Collection<int, Entreprise>
  149.      */
  150.     public function getEntreprises(): Collection
  151.     {
  152.         return $this->entreprises;
  153.     }
  154.     public function addEntreprise(Entreprise $entreprise): static
  155.     {
  156.         if (!$this->entreprises->contains($entreprise)) {
  157.             $this->entreprises->add($entreprise);
  158.             $entreprise->setPackage($this);
  159.         }
  160.         return $this;
  161.     }
  162.     public function removeEntreprise(Entreprise $entreprise): static
  163.     {
  164.         if ($this->entreprises->removeElement($entreprise)) {
  165.             if ($entreprise->getPackage() === $this) {
  166.                 $entreprise->setPackage(null);
  167.             }
  168.         }
  169.         return $this;
  170.     }
  171.     public function getPriceannuel(): ?string
  172.     {
  173.         return $this->priceannuel;
  174.     }
  175.     public function setPriceannuel(?string $priceannuel): static
  176.     {
  177.         $this->priceannuel $priceannuel;
  178.         return $this;
  179.     }
  180.     public function getMaxUnits(): ?int
  181.     {
  182.         return $this->maxUnits;
  183.     }
  184.     public function setMaxUnits(?int $maxUnits): static
  185.     {
  186.         $this->maxUnits $maxUnits;
  187.         return $this;
  188.     }
  189.     public function getTrialMonths(): int
  190.     {
  191.         return $this->trialMonths;
  192.     }
  193.     public function setTrialMonths(int $trialMonths): static
  194.     {
  195.         $this->trialMonths $trialMonths;
  196.         return $this;
  197.     }
  198.     // -------------
  199.     // Helper API
  200.     // -------------
  201.     public function hasUnlimitedUnits(): bool
  202.     {
  203.         return $this->maxUnits === null;
  204.     }
  205.     public function getLotsLimitLabel(): string
  206.     {
  207.         return $this->hasUnlimitedUnits() ? 'Illimité' : (string)$this->maxUnits;
  208.     }
  209.     /** Float accessors for easier math (Doctrine stores DECIMAL as string) */
  210.     public function getMonthlyPriceFloat(): ?float
  211.     {
  212.         return $this->price !== null ? (float)$this->price null;
  213.     }
  214.     public function getAnnualPriceFloat(): ?float
  215.     {
  216.         return $this->priceannuel !== null ? (float)$this->priceannuel null;
  217.     }
  218.     /** Trial end from a given start date (e.g., signup date) */
  219.     public function getTrialEndFrom(\DateTimeInterface $start): \DateTimeImmutable
  220.     {
  221.         $dt \DateTimeImmutable::createFromInterface($start);
  222.         return $dt->modify('+' max(0$this->trialMonths) . ' months');
  223.     }
  224.     public function __toString(): string
  225.     {
  226.         return sprintf('%s (%s)'$this->name ?? 'Package'$this->type ?? 'type');
  227.     }
  228. }
  229. //
  230. //namespace App\Entity;
  231. //
  232. //use App\Repository\PackageRepository;
  233. //use App\Traits\TimeStampTrait;
  234. //use Doctrine\Common\Collections\ArrayCollection;
  235. //use Doctrine\Common\Collections\Collection;
  236. //use Doctrine\DBAL\Types\Types;
  237. //use Doctrine\ORM\Mapping as ORM;
  238. //
  239. //#[ORM\Entity(repositoryClass: PackageRepository::class)]
  240. //class Package
  241. //{
  242. //    use TimeStampTrait;
  243. //
  244. //    #[ORM\Id]
  245. //    #[ORM\GeneratedValue]
  246. //    #[ORM\Column(type: 'integer')]
  247. //    private ?int $id = null;
  248. //
  249. //    #[ORM\Column(length: 100)]
  250. //    private ?string $type = null;
  251. //
  252. //    #[ORM\Column(length: 255)]
  253. //    private ?string $description = null;
  254. //
  255. //    #[ORM\Column]
  256. //    private ?bool $publish = null;
  257. //
  258. //    #[ORM\OneToMany(mappedBy: 'package', targetEntity: Subscription::class)]
  259. //    private Collection $entreprisePackages;
  260. //
  261. //    #[ORM\Column(length: 25)]
  262. //    private ?string $name = null;
  263. //
  264. //    #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2)]
  265. //    private ?string $price = null;
  266. //
  267. //    #[ORM\OneToMany(mappedBy: 'package', targetEntity: Entreprise::class)]
  268. //    private Collection $entreprises;
  269. //
  270. //    #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2, nullable: true)]
  271. //    private ?string $priceannuel = null;
  272. //
  273. //    public function __construct()
  274. //    {
  275. //        $this->entreprisePackages = new ArrayCollection();
  276. //        $this->entreprises = new ArrayCollection();
  277. //    }
  278. //
  279. //    /**
  280. //     * @return int|null
  281. //     */
  282. //    public function getId(): ?int
  283. //    {
  284. //        return $this->id;
  285. //    }
  286. //
  287. //    /**
  288. //     * @param int|null $id
  289. //     */
  290. //    public function setId(?int $id): void
  291. //    {
  292. //        $this->id = $id;
  293. //    }
  294. //
  295. //    /**
  296. //     * @return string|null
  297. //     */
  298. //    public function getType(): ?string
  299. //    {
  300. //        return $this->type;
  301. //    }
  302. //
  303. //    /**
  304. //     * @param string|null $type
  305. //     */
  306. //    public function setType(?string $type): void
  307. //    {
  308. //        $this->type = $type;
  309. //    }
  310. //
  311. //    /**
  312. //     * @return string|null
  313. //     */
  314. //    public function getDescription(): ?string
  315. //    {
  316. //        return $this->description;
  317. //    }
  318. //
  319. //    /**
  320. //     * @param string|null $description
  321. //     */
  322. //    public function setDescription(?string $description): void
  323. //    {
  324. //        $this->description = $description;
  325. //    }
  326. //
  327. //    /**
  328. //     * @return bool|null
  329. //     */
  330. //    public function getPublish(): ?bool
  331. //    {
  332. //        return $this->publish;
  333. //    }
  334. //
  335. //    /**
  336. //     * @param bool|null $publish
  337. //     */
  338. //    public function setPublish(?bool $publish): void
  339. //    {
  340. //        $this->publish = $publish;
  341. //    }
  342. //
  343. //    /**
  344. //     * @return Collection<int, Subscription>
  345. //     */
  346. //    public function getEntreprisePackages(): Collection
  347. //    {
  348. //        return $this->entreprisePackages;
  349. //    }
  350. //
  351. //    public function addEntreprisePackage(Subscription $entreprisePackage): static
  352. //    {
  353. //        if (!$this->entreprisePackages->contains($entreprisePackage)) {
  354. //            $this->entreprisePackages->add($entreprisePackage);
  355. //            $entreprisePackage->setPackage($this);
  356. //        }
  357. //
  358. //        return $this;
  359. //    }
  360. //
  361. //    public function removeEntreprisePackage(Subscription $entreprisePackage): static
  362. //    {
  363. //        if ($this->entreprisePackages->removeElement($entreprisePackage)) {
  364. //            // set the owning side to null (unless already changed)
  365. //            if ($entreprisePackage->getPackage() === $this) {
  366. //                $entreprisePackage->setPackage(null);
  367. //            }
  368. //        }
  369. //
  370. //        return $this;
  371. //    }
  372. //
  373. //    public function getName(): ?string
  374. //    {
  375. //        return $this->name;
  376. //    }
  377. //
  378. //    public function setName(string $name): static
  379. //    {
  380. //        $this->name = $name;
  381. //
  382. //        return $this;
  383. //    }
  384. //
  385. //    public function getPrice(): ?string
  386. //    {
  387. //        return $this->price;
  388. //    }
  389. //
  390. //    public function setPrice(string $price): static
  391. //    {
  392. //        $this->price = $price;
  393. //
  394. //        return $this;
  395. //    }
  396. //
  397. //    /**
  398. //     * @return Collection<int, Entreprise>
  399. //     */
  400. //    public function getEntreprises(): Collection
  401. //    {
  402. //        return $this->entreprises;
  403. //    }
  404. //
  405. //    public function addEntreprise(Entreprise $entreprise): static
  406. //    {
  407. //        if (!$this->entreprises->contains($entreprise)) {
  408. //            $this->entreprises->add($entreprise);
  409. //            $entreprise->setPackage($this);
  410. //        }
  411. //
  412. //        return $this;
  413. //    }
  414. //
  415. //    public function removeEntreprise(Entreprise $entreprise): static
  416. //    {
  417. //        if ($this->entreprises->removeElement($entreprise)) {
  418. //            // set the owning side to null (unless already changed)
  419. //            if ($entreprise->getPackage() === $this) {
  420. //                $entreprise->setPackage(null);
  421. //            }
  422. //        }
  423. //
  424. //        return $this;
  425. //    }
  426. //
  427. //    public function getPriceannuel(): ?string
  428. //    {
  429. //        return $this->priceannuel;
  430. //    }
  431. //
  432. //    public function setPriceannuel(?string $priceannuel): static
  433. //    {
  434. //        $this->priceannuel = $priceannuel;
  435. //
  436. //        return $this;
  437. //    }
  438. //}