app/Entity/Schema/ORM/Organization.php line 17

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Sq\Entity\Schema\ORM;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\Common\Collections\Collection;
  5. use Doctrine\ORM\Mapping as ORM;
  6. use ReflectionClass;
  7. use Sq\Entity\Schema\Column\OrganizationBillingCycle;
  8. use Sq\Entity\Schema\Column\OrganizationSubscriptionStatus;
  9. use Sq\Entity\Schema\Column\OrganizationSuspended;
  10. use Sq\Service\Repository\ORM\OrganizationRepository;
  11. use Symfony\Component\Uid\Uuid;
  12. #[ORM\Entity(repositoryClassOrganizationRepository::class)]
  13. #[ORM\Table(name'organizations')]
  14. class Organization
  15. {
  16.     /**
  17.      *
  18.      * @var int|null
  19.      */
  20.     #[ORM\Id]
  21.     #[ORM\GeneratedValue(strategy'AUTO')]
  22.     #[ORM\Column(name'o_id'type'integer'nullablefalseoptions: ['unsigned' => true])]
  23.     private $id;
  24.     /**
  25.      *
  26.      * @var Member
  27.      */
  28.     #[ORM\OneToOne(targetEntityMember::class, inversedBy'organization'fetch'EAGER'cascade: ['persist'])]
  29.     #[ORM\JoinColumn(name'o_m_id'referencedColumnName'm_id'nullablefalse)]
  30.     private $legacyMember;
  31.     /**
  32.      * @var string
  33.      */
  34.     #[ORM\Column(name'o_name'type'string'nullablefalse)]
  35.     private $name;
  36.     /**
  37.      * @var Collection
  38.      */
  39.     #[ORM\OneToMany(targetEntityWorkspace::class, mappedBy'organization'fetch'LAZY'cascade: ['persist'])]
  40.     private $workspaces;
  41.     /**
  42.      * @var OrganizationSettings
  43.      */
  44.     #[ORM\OneToOne(targetEntityOrganizationSettings::class, mappedBy'organization'cascade: ['persist'])]
  45.     private $settings;
  46.     /**
  47.      * @var Collection
  48.      */
  49.     #[ORM\OneToMany(targetEntityUserOrganizationAssignment::class, mappedBy'organization'fetch'LAZY'orphanRemovaltrue)]
  50.     private $userAssignments;
  51.     /**
  52.      * @var Collection
  53.      */
  54.     #[ORM\OneToMany(targetEntityUserInvitation::class, mappedBy'organization'fetch'LAZY')]
  55.     private $userInvitations;
  56.     /**
  57.     * @var Collection<Bitly>
  58.     */
  59.     #[ORM\OneToMany(targetEntityBitly::class, mappedBy'organization'fetch'LAZY')]
  60.     private $bitlyAccounts;
  61.     /**
  62.      * @var string|null
  63.      */
  64.     #[ORM\Column(name'o_sub_status'type'string'nullablefalseoptions: ['default' => 'trial'])]
  65.     private $subscriptionStatus OrganizationSubscriptionStatus::TRIAL;
  66.     /**
  67.      * @var string|null
  68.      */
  69.     #[ORM\Column(name'o_subscription_extid'type'integer'nullabletrue)]
  70.     private $subscriptionExternalId;
  71.     /**
  72.      * @var BillingDetails|null
  73.      */
  74.     #[ORM\OneToOne(targetEntityBillingDetails::class, mappedBy'organization')]
  75.     private $billingDetails;
  76.     /**
  77.      * @var string
  78.      */
  79.     #[ORM\Column(name'o_billing_cycle'type'string'nullablefalseoptions: ['default' => 'monthly'])]
  80.     private $billingCycle OrganizationBillingCycle::MONTHLY;
  81.     /**
  82.      * @var \DateTimeInterface|null
  83.      */
  84.     #[ORM\Column(name'o_trial_expiry_local_date'type'date'nullabletrue)]
  85.     private $trialExpiryLocalDate;
  86.     /**
  87.      * @var \DateTimeInterface|null
  88.      */
  89.     #[ORM\Column(name'o_next_billing_date'type'date'nullabletrue)]
  90.     private $nextBillingDate;
  91.     /**
  92.      * @var string|null
  93.      */
  94.     #[ORM\Column(name'o_next_bill_amount'type'decimal'precision8scale2nullabletrueoptions: ['default' => '0.00'])]
  95.     private $nextBillAmount '0.00';
  96.     /**
  97.      * @var string|null
  98.      */
  99.     #[ORM\Column(name'o_balance'type'decimal'precision15scale2nullabletrueoptions: ['default' => '0.00'])]
  100.     private $balance '0.00';
  101.     /**
  102.      * @var string|null
  103.      */
  104.     #[ORM\Column(name'o_currency'type'string'length3nullabletrue)]
  105.     private $currency;
  106.     /**
  107.      * @var \DateTimeInterface|null
  108.      */
  109.     #[ORM\Column(name'o_date_activated'type'datetime'nullabletrue)]
  110.     private $dateActivated;
  111.     /**
  112.      * @var \DateTimeInterface|null
  113.      */
  114.     #[ORM\Column(name'o_date_upgraded'type'datetime'nullabletrue)]
  115.     private $dateUpgraded;
  116.     /**
  117.      * @var string|null
  118.      */
  119.     #[ORM\Column(name'o_country_code'type'string'length2nullabletrue)]
  120.     private $countryCode;
  121.     /**
  122.      * @var int
  123.      */
  124.     #[ORM\Column(name'o_plan_id'type'smallint'nullablefalseoptions: ['default' => 1'unsigned' => true])]
  125.     private $planId 1;
  126.     /**
  127.      * @var int|null
  128.      */
  129.     #[ORM\Column(name'o_plan_group'type'smallint'nullabletrueoptions: ['default' => 3'unsigned' => true])]
  130.     private $planGroup 4;
  131.     /**
  132.      * @var int|null
  133.      */
  134.     #[ORM\Column(name'o_addon_group'type'smallint'nullabletrueoptions: ['default' => 1'unsigned' => true])]
  135.     private $addonGroup 2;
  136.     /**
  137.      * @var bool|null
  138.      */
  139.     #[ORM\Column(name'o_custom_plans'type'boolean'nullabletrueoptions: ['default' => 1])]
  140.     private $customPlans true;
  141.     /**
  142.      * @var int|null
  143.      */
  144.     #[ORM\Column(name'o_onboarding'type'smallint'nullabletrueoptions: ['default' => 1])]
  145.     private $onboarding 1;
  146.     /**
  147.      * @var bool|null
  148.      */
  149.     #[ORM\Column(name'o_early_upgrade_offer'type'boolean'nullabletrueoptions: ['default' => false])]
  150.     private $earlyUpgradeOffer false;
  151.     /**
  152.      * @var int|null
  153.      */
  154.     #[ORM\Column(name'o_pricing_design'type'integer'nullabletrueoptions: ['default' => 1])]
  155.     private $pricingDesign 2;
  156.     /**
  157.      * @var string|null
  158.      */
  159.     #[ORM\Column(name'o_ref'type'string'length45nullabletrue)]
  160.     private $ref;
  161.     /**
  162.      * @var bool|null
  163.      */
  164.     #[ORM\Column(name'o_ref_gift'type'boolean'nullabletrueoptions: ['default' => false])]
  165.     private $refGift false;
  166.     /**
  167.      * @var int|null
  168.      */
  169.     #[ORM\Column(name'o_suspended'type'integer'nullabletrueoptions: ['default' => 0])]
  170.     private $suspended OrganizationSuspended::ACTIVE;
  171.     public function __construct(
  172.         string $name,
  173.         string $email,
  174.         string $timezone,
  175.         ?string $countryCode,
  176.         string $billingCycle 'monthly',
  177.         int $trialLength 14,
  178.     ) {
  179.         $name trim($name);
  180.         $this->name $name;
  181.         $this->legacyMember = new Member(
  182.             usernameUuid::v4()->toRfc4122(), // Not used for anything for overhaul, but cant be null.
  183.             email$email,
  184.             firstName$name,
  185.             timezone$timezone,
  186.             countryCode$countryCode,
  187.             billingCycle$billingCycle,
  188.             trialLength$trialLength,
  189.             organization$this,
  190.         );
  191.         $this->legacyMember->skipOnboarding();
  192.         $this->legacyMember->setInOverhaul(true);
  193.         $this->createDefaultsForNewInstance();
  194.     }
  195.     private function createDefaultsForNewInstance(): self
  196.     {
  197.         $this->settings = new OrganizationSettings($this);
  198.         $this->userAssignments = new ArrayCollection;
  199.         $this->userInvitations = new ArrayCollection;
  200.         $this->workspaces = new ArrayCollection;
  201.         $this->bitlyAccounts = new ArrayCollection;
  202.         return $this;
  203.     }
  204.     /**
  205.      * @throws \ReflectionException
  206.      */
  207.     public static function createForExistingLegacyMember(Member $member): Organization
  208.     {
  209.         $org = (new ReflectionClass(static::class))
  210.             ->newInstanceWithoutConstructor()
  211.             ->createDefaultsForNewInstance();
  212.         $org->name $member->getBusiness()?->getCompany() ?? "Default Organization for " $member->getFirstName();
  213.         $org->legacyMember $member;
  214.         return $org;
  215.     }
  216.     public function getId(): ?int
  217.     {
  218.         return $this->id;
  219.     }
  220.     /**
  221.      * Every org has a member entity for billing/subscription purposes.
  222.      */
  223.     public function getLegacyMember(): Member
  224.     {
  225.         return $this->legacyMember;
  226.     }
  227.     public function getName(): string
  228.     {
  229.         return $this->name;
  230.     }
  231.     public function setName(string $name): self
  232.     {
  233.         $this->name trim($name);
  234.         return $this;
  235.     }
  236.     public function getSettings(): OrganizationSettings
  237.     {
  238.         return $this->settings;
  239.     }
  240.     /**
  241.      * @return Collection|Workspace[]
  242.      */
  243.     public function getWorkspaces(bool $includeDeleted false): Collection
  244.     {
  245.         if ($includeDeleted)
  246.         {
  247.             return $this->workspaces;
  248.         }
  249.         return $this->workspaces->filter(
  250.             fn (Workspace $workspace): bool => !$workspace->isDeleted()
  251.         );
  252.     }
  253.     public function addWorkspace(Workspace $workspace): self
  254.     {
  255.         if (!$this->workspaces->contains($workspace))
  256.         {
  257.             $this->workspaces->add($workspace);
  258.         }
  259.         return $this;
  260.     }
  261.     public function removeWorkspace(Workspace $workspace): self
  262.     {
  263.         if ($this->workspaces->contains($workspace))
  264.         {
  265.             $this->workspaces->removeElement($workspace);
  266.         }
  267.         return $this;
  268.     }
  269.     /**
  270.      * @return Collection|User[]
  271.      */
  272.     public function getUsers(): Collection
  273.     {
  274.         return $this->userAssignments->map(function (UserOrganizationAssignment $assignment): User
  275.         {
  276.             return $assignment->getUser();
  277.         });
  278.     }
  279.     public function getOwner(): User
  280.     {
  281.         return $this->userAssignments
  282.             ->filter(fn (UserOrganizationAssignment $assignment) => $assignment->getRole() === UserOrganizationAssignment::ROLE_OWNER)
  283.             ->first()
  284.             ->getUser();
  285.     }
  286.     public function hasUser(User $user): bool
  287.     {
  288.         return $this->getUsers()->contains($user);
  289.     }
  290.     /**
  291.      * @return Collection<UserOrganizationAssignment>
  292.      */
  293.     public function getUserAssignments(): Collection
  294.     {
  295.         return $this->userAssignments;
  296.     }
  297.     public function getUserAssignment(User $user): ?UserOrganizationAssignment
  298.     {
  299.         $assignments $this->userAssignments->filter(function (UserOrganizationAssignment $assignment) use ($user)
  300.         {
  301.             return $assignment->getUser() === $user;
  302.         });
  303.         return $assignments->count() > $assignments->first() : null;
  304.     }
  305.     public function getUserInvitations(): Collection
  306.     {
  307.         return $this->userInvitations;
  308.     }
  309.     public function addUser(User $userstring $role): self
  310.     {
  311.         $user->addToOrganization($this$role);
  312.         return $this;
  313.     }
  314.     public function removeUser(User $user): self
  315.     {
  316.         $user->removeFromOrganization($this);
  317.         return $this;
  318.     }
  319.     public function getSubscriptionStatus(): ?string
  320.     {
  321.         return $this->subscriptionStatus;
  322.     }
  323.     public function setSubscriptionStatus(?string $subscriptionStatus): self
  324.     {
  325.         $this->subscriptionStatus $subscriptionStatus;
  326.         return $this;
  327.     }
  328.     public function getSubscriptionExternalId(): ?string
  329.     {
  330.         return $this->subscriptionExternalId;
  331.     }
  332.     public function setSubscriptionExternalId(?string $subscriptionExternalId): self
  333.     {
  334.         $this->subscriptionExternalId $subscriptionExternalId;
  335.         return $this;
  336.     }
  337.     public function getBillingDetails(): ?BillingDetails
  338.     {
  339.         return $this->billingDetails;
  340.     }
  341.     public function getBillingCycle(): string
  342.     {
  343.         return $this->billingCycle;
  344.     }
  345.     public function setBillingCycle(string $billingCycle): self
  346.     {
  347.         $this->billingCycle $billingCycle;
  348.         return $this;
  349.     }
  350.     public function getTrialExpiryLocalDate(): ?\DateTimeInterface
  351.     {
  352.         return $this->trialExpiryLocalDate !== null
  353.             ? clone $this->trialExpiryLocalDate
  354.             null;
  355.     }
  356.     public function setTrialExpiryLocalDate(?\DateTimeInterface $trialExpiryLocalDate): self
  357.     {
  358.         $this->trialExpiryLocalDate $trialExpiryLocalDate !== null ? clone $trialExpiryLocalDate null;
  359.         return $this;
  360.     }
  361.     public function getNextBillingDate(): ?\DateTimeInterface
  362.     {
  363.         return $this->nextBillingDate !== null
  364.             ? clone $this->nextBillingDate
  365.             null;
  366.     }
  367.     public function setNextBillingDate(?\DateTimeInterface $nextBillingDate): self
  368.     {
  369.         $this->nextBillingDate $nextBillingDate !== null ? clone $nextBillingDate null;
  370.         return $this;
  371.     }
  372.     public function getNextBillAmount(): ?string
  373.     {
  374.         return $this->nextBillAmount;
  375.     }
  376.     public function setNextBillAmount(?string $nextBillAmount): self
  377.     {
  378.         $this->nextBillAmount $nextBillAmount;
  379.         return $this;
  380.     }
  381.     public function getBalance(): ?string
  382.     {
  383.         return $this->balance;
  384.     }
  385.     public function setBalance(?string $balance): self
  386.     {
  387.         $this->balance $balance;
  388.         return $this;
  389.     }
  390.     public function getCurrency(): ?string
  391.     {
  392.         return $this->currency;
  393.     }
  394.     public function setCurrency(?string $currency): self
  395.     {
  396.         $this->currency $currency;
  397.         return $this;
  398.     }
  399.     public function getDateActivated(): ?\DateTimeInterface
  400.     {
  401.         return $this->dateActivated !== null
  402.             ? clone $this->dateActivated
  403.             null;
  404.     }
  405.     public function setDateActivated(?\DateTimeInterface $dateActivated): self
  406.     {
  407.         $this->dateActivated $dateActivated !== null ? clone $dateActivated null;
  408.         return $this;
  409.     }
  410.     public function getDateUpgraded(): ?\DateTimeInterface
  411.     {
  412.         return $this->dateUpgraded !== null
  413.             ? clone $this->dateUpgraded
  414.             null;
  415.     }
  416.     public function setDateUpgraded(?\DateTimeInterface $dateUpgraded): self
  417.     {
  418.         $this->dateUpgraded $dateUpgraded !== null ? clone $dateUpgraded null;
  419.         return $this;
  420.     }
  421.     public function getCountryCode(): ?string
  422.     {
  423.         return $this->countryCode;
  424.     }
  425.     public function setCountryCode(?string $countryCode): self
  426.     {
  427.         $this->countryCode $countryCode;
  428.         return $this;
  429.     }
  430.     public function getAddonGroup(): ?int
  431.     {
  432.         return $this->addonGroup;
  433.     }
  434.     public function setAddonGroup(?int $addonGroup): self
  435.     {
  436.         $this->addonGroup $addonGroup;
  437.         return $this;
  438.     }
  439.     public function hasCustomPlans(): ?bool
  440.     {
  441.         return $this->customPlans;
  442.     }
  443.     public function setCustomPlans(?bool $customPlans): self
  444.     {
  445.         $this->customPlans $customPlans;
  446.         return $this;
  447.     }
  448.     public function isEarlyUpgradeOffer(): ?bool
  449.     {
  450.         return $this->earlyUpgradeOffer;
  451.     }
  452.     public function setEarlyUpgradeOffer(?bool $earlyUpgradeOffer): self
  453.     {
  454.         $this->earlyUpgradeOffer $earlyUpgradeOffer;
  455.         return $this;
  456.     }
  457.     public function getPricingDesign(): ?int
  458.     {
  459.         return $this->pricingDesign;
  460.     }
  461.     public function setPricingDesign(?int $pricingDesign): self
  462.     {
  463.         $this->pricingDesign $pricingDesign;
  464.         return $this;
  465.     }
  466.     public function getRef(): ?string
  467.     {
  468.         return $this->ref;
  469.     }
  470.     public function setRef(?string $ref): self
  471.     {
  472.         $this->ref $ref;
  473.         return $this;
  474.     }
  475.     public function isRefGift(): ?bool
  476.     {
  477.         return $this->refGift;
  478.     }
  479.     public function setRefGift(?bool $refGift): self
  480.     {
  481.         $this->refGift $refGift;
  482.         return $this;
  483.     }
  484.     public function isSuspended(): ?int
  485.     {
  486.         return $this->suspended;
  487.     }
  488.     public function setSuspended(?int $suspended): self
  489.     {
  490.         $this->suspended $suspended;
  491.         return $this;
  492.     }
  493.     public function getPlan(): Plan
  494.     {
  495.         return $this->getLegacyMember()->getPlan();
  496.     }
  497.     public function changePlan(Plan $plan): self
  498.     {
  499.         $this->getLegacyMember()->changePlan($plan);
  500.         return $this;
  501.     }
  502.     /**
  503.      * @return Collection|Bitly[]
  504.      */
  505.     public function getBitlyAccounts(): Collection
  506.     {
  507.         return $this->bitlyAccounts;
  508.     }
  509. }