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.         ?\DateTimeInterface $firstVisit null,
  179.     ) {
  180.         $name trim($name);
  181.         $this->name $name;
  182.         $this->legacyMember = new Member(
  183.             usernameUuid::v4()->toRfc4122(), // Not used for anything for overhaul, but cant be null.
  184.             email$email,
  185.             firstName$name,
  186.             timezone$timezone,
  187.             countryCode$countryCode,
  188.             billingCycle$billingCycle,
  189.             trialLength$trialLength,
  190.             organization$this,
  191.             firstVisit$firstVisit
  192.         );
  193.         $this->legacyMember->skipOnboarding();
  194.         $this->legacyMember->setInOverhaul(true);
  195.         $this->createDefaultsForNewInstance();
  196.     }
  197.     private function createDefaultsForNewInstance(): self
  198.     {
  199.         $this->settings = new OrganizationSettings($this);
  200.         $this->userAssignments = new ArrayCollection;
  201.         $this->userInvitations = new ArrayCollection;
  202.         $this->workspaces = new ArrayCollection;
  203.         $this->bitlyAccounts = new ArrayCollection;
  204.         return $this;
  205.     }
  206.     /**
  207.      * @throws \ReflectionException
  208.      */
  209.     public static function createForExistingLegacyMember(Member $member): Organization
  210.     {
  211.         $org = (new ReflectionClass(static::class))
  212.             ->newInstanceWithoutConstructor()
  213.             ->createDefaultsForNewInstance();
  214.         $org->name $member->getBusiness()?->getCompany() ?? "Default Organization for " $member->getFirstName();
  215.         $org->legacyMember $member;
  216.         return $org;
  217.     }
  218.     public function getId(): ?int
  219.     {
  220.         return $this->id;
  221.     }
  222.     /**
  223.      * Every org has a member entity for billing/subscription purposes.
  224.      */
  225.     public function getLegacyMember(): Member
  226.     {
  227.         return $this->legacyMember;
  228.     }
  229.     public function getName(): string
  230.     {
  231.         return $this->name;
  232.     }
  233.     public function setName(string $name): self
  234.     {
  235.         $this->name trim($name);
  236.         return $this;
  237.     }
  238.     public function getSettings(): OrganizationSettings
  239.     {
  240.         return $this->settings;
  241.     }
  242.     /**
  243.      * @return Collection|Workspace[]
  244.      */
  245.     public function getWorkspaces(bool $includeDeleted false): Collection
  246.     {
  247.         if ($includeDeleted)
  248.         {
  249.             return $this->workspaces;
  250.         }
  251.         return $this->workspaces->filter(
  252.             fn (Workspace $workspace): bool => !$workspace->isDeleted()
  253.         );
  254.     }
  255.     public function addWorkspace(Workspace $workspace): self
  256.     {
  257.         if (!$this->workspaces->contains($workspace))
  258.         {
  259.             $this->workspaces->add($workspace);
  260.         }
  261.         return $this;
  262.     }
  263.     public function removeWorkspace(Workspace $workspace): self
  264.     {
  265.         if ($this->workspaces->contains($workspace))
  266.         {
  267.             $this->workspaces->removeElement($workspace);
  268.         }
  269.         return $this;
  270.     }
  271.     /**
  272.      * @return Collection|User[]
  273.      */
  274.     public function getUsers(): Collection
  275.     {
  276.         return $this->userAssignments->map(function (UserOrganizationAssignment $assignment): User
  277.         {
  278.             return $assignment->getUser();
  279.         });
  280.     }
  281.     public function getOwner(): User
  282.     {
  283.         return $this->userAssignments
  284.             ->filter(fn (UserOrganizationAssignment $assignment) => $assignment->getRole() === UserOrganizationAssignment::ROLE_OWNER)
  285.             ->first()
  286.             ->getUser();
  287.     }
  288.     public function hasUser(User $user): bool
  289.     {
  290.         return $this->getUsers()->contains($user);
  291.     }
  292.     /**
  293.      * @return Collection<UserOrganizationAssignment>
  294.      */
  295.     public function getUserAssignments(): Collection
  296.     {
  297.         return $this->userAssignments;
  298.     }
  299.     public function getUserAssignment(User $user): ?UserOrganizationAssignment
  300.     {
  301.         $assignments $this->userAssignments->filter(function (UserOrganizationAssignment $assignment) use ($user)
  302.         {
  303.             return $assignment->getUser() === $user;
  304.         });
  305.         return $assignments->count() > $assignments->first() : null;
  306.     }
  307.     public function getUserInvitations(): Collection
  308.     {
  309.         return $this->userInvitations;
  310.     }
  311.     public function addUser(User $userstring $role): self
  312.     {
  313.         $user->addToOrganization($this$role);
  314.         return $this;
  315.     }
  316.     public function removeUser(User $user): self
  317.     {
  318.         $user->removeFromOrganization($this);
  319.         return $this;
  320.     }
  321.     public function getSubscriptionStatus(): ?string
  322.     {
  323.         return $this->subscriptionStatus;
  324.     }
  325.     public function setSubscriptionStatus(?string $subscriptionStatus): self
  326.     {
  327.         $this->subscriptionStatus $subscriptionStatus;
  328.         return $this;
  329.     }
  330.     public function getSubscriptionExternalId(): ?string
  331.     {
  332.         return $this->subscriptionExternalId;
  333.     }
  334.     public function setSubscriptionExternalId(?string $subscriptionExternalId): self
  335.     {
  336.         $this->subscriptionExternalId $subscriptionExternalId;
  337.         return $this;
  338.     }
  339.     public function getBillingDetails(): ?BillingDetails
  340.     {
  341.         return $this->billingDetails;
  342.     }
  343.     public function getBillingCycle(): string
  344.     {
  345.         return $this->billingCycle;
  346.     }
  347.     public function setBillingCycle(string $billingCycle): self
  348.     {
  349.         $this->billingCycle $billingCycle;
  350.         return $this;
  351.     }
  352.     public function getTrialExpiryLocalDate(): ?\DateTimeInterface
  353.     {
  354.         return $this->trialExpiryLocalDate !== null
  355.             ? clone $this->trialExpiryLocalDate
  356.             null;
  357.     }
  358.     public function setTrialExpiryLocalDate(?\DateTimeInterface $trialExpiryLocalDate): self
  359.     {
  360.         $this->trialExpiryLocalDate $trialExpiryLocalDate !== null ? clone $trialExpiryLocalDate null;
  361.         return $this;
  362.     }
  363.     public function getNextBillingDate(): ?\DateTimeInterface
  364.     {
  365.         return $this->nextBillingDate !== null
  366.             ? clone $this->nextBillingDate
  367.             null;
  368.     }
  369.     public function setNextBillingDate(?\DateTimeInterface $nextBillingDate): self
  370.     {
  371.         $this->nextBillingDate $nextBillingDate !== null ? clone $nextBillingDate null;
  372.         return $this;
  373.     }
  374.     public function getNextBillAmount(): ?string
  375.     {
  376.         return $this->nextBillAmount;
  377.     }
  378.     public function setNextBillAmount(?string $nextBillAmount): self
  379.     {
  380.         $this->nextBillAmount $nextBillAmount;
  381.         return $this;
  382.     }
  383.     public function getBalance(): ?string
  384.     {
  385.         return $this->balance;
  386.     }
  387.     public function setBalance(?string $balance): self
  388.     {
  389.         $this->balance $balance;
  390.         return $this;
  391.     }
  392.     public function getCurrency(): ?string
  393.     {
  394.         return $this->currency;
  395.     }
  396.     public function setCurrency(?string $currency): self
  397.     {
  398.         $this->currency $currency;
  399.         return $this;
  400.     }
  401.     public function getDateActivated(): ?\DateTimeInterface
  402.     {
  403.         return $this->dateActivated !== null
  404.             ? clone $this->dateActivated
  405.             null;
  406.     }
  407.     public function setDateActivated(?\DateTimeInterface $dateActivated): self
  408.     {
  409.         $this->dateActivated $dateActivated !== null ? clone $dateActivated null;
  410.         return $this;
  411.     }
  412.     public function getDateUpgraded(): ?\DateTimeInterface
  413.     {
  414.         return $this->dateUpgraded !== null
  415.             ? clone $this->dateUpgraded
  416.             null;
  417.     }
  418.     public function setDateUpgraded(?\DateTimeInterface $dateUpgraded): self
  419.     {
  420.         $this->dateUpgraded $dateUpgraded !== null ? clone $dateUpgraded null;
  421.         return $this;
  422.     }
  423.     public function getCountryCode(): ?string
  424.     {
  425.         return $this->countryCode;
  426.     }
  427.     public function setCountryCode(?string $countryCode): self
  428.     {
  429.         $this->countryCode $countryCode;
  430.         return $this;
  431.     }
  432.     public function getAddonGroup(): ?int
  433.     {
  434.         return $this->addonGroup;
  435.     }
  436.     public function setAddonGroup(?int $addonGroup): self
  437.     {
  438.         $this->addonGroup $addonGroup;
  439.         return $this;
  440.     }
  441.     public function hasCustomPlans(): ?bool
  442.     {
  443.         return $this->customPlans;
  444.     }
  445.     public function setCustomPlans(?bool $customPlans): self
  446.     {
  447.         $this->customPlans $customPlans;
  448.         return $this;
  449.     }
  450.     public function getOnboardingVersion(): int
  451.     {
  452.         return $this->onboarding ?? 1// TODO Default to the minimum available onboarding version.
  453.     }
  454.     public function setOnboardingVersion(int $onboarding): self
  455.     {
  456.         $this->onboarding $onboarding;
  457.         return $this;
  458.     }
  459.     public function isEarlyUpgradeOffer(): ?bool
  460.     {
  461.         return $this->earlyUpgradeOffer;
  462.     }
  463.     public function setEarlyUpgradeOffer(?bool $earlyUpgradeOffer): self
  464.     {
  465.         $this->earlyUpgradeOffer $earlyUpgradeOffer;
  466.         return $this;
  467.     }
  468.     public function getPricingDesign(): ?int
  469.     {
  470.         return $this->pricingDesign;
  471.     }
  472.     public function setPricingDesign(?int $pricingDesign): self
  473.     {
  474.         $this->pricingDesign $pricingDesign;
  475.         return $this;
  476.     }
  477.     public function getRef(): ?string
  478.     {
  479.         return $this->ref;
  480.     }
  481.     public function setRef(?string $ref): self
  482.     {
  483.         $this->ref $ref;
  484.         return $this;
  485.     }
  486.     public function isRefGift(): ?bool
  487.     {
  488.         return $this->refGift;
  489.     }
  490.     public function setRefGift(?bool $refGift): self
  491.     {
  492.         $this->refGift $refGift;
  493.         return $this;
  494.     }
  495.     public function isSuspended(): ?int
  496.     {
  497.         return $this->suspended;
  498.     }
  499.     public function setSuspended(?int $suspended): self
  500.     {
  501.         $this->suspended $suspended;
  502.         return $this;
  503.     }
  504.     public function getPlan(): Plan
  505.     {
  506.         return $this->getLegacyMember()->getPlan();
  507.     }
  508.     public function changePlan(Plan $plan): self
  509.     {
  510.         $this->getLegacyMember()->changePlan($plan);
  511.         return $this;
  512.     }
  513.     /**
  514.      * @return Collection|Bitly[]
  515.      */
  516.     public function getBitlyAccounts(): Collection
  517.     {
  518.         return $this->bitlyAccounts;
  519.     }
  520. }