<?php
namespace App\Entity\Membership;
use App\Enum\Billwerk\ComponentContext;
use App\Utility\ReflectionHelper;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use InvalidArgumentException;
use JanusHercules\SelfServiceTrafficCampaign\Domain\Entity\SelfServiceTrafficCampaignBooking;
use LogicException;
/**
* @ORM\Entity()
*
* @ORM\Table(
* name="billwerk_component_subscriptions"
* )
*
* Note that this entity is actually used to represent two different Billwerk entities: component subscriptions and usages,
* which are very similar in nature but not the same things. Component subscriptions are used to back the recurrent job bookings
* while the user's contract is in trial, and upon renewal, usages are used to back the recurrent job bookings.
*/
class BillwerkComponentSubscription
{
public const COMPONENT_SUBSCRIPTION_TYPE_COMPONENT_SUBSCRIPTION = 0;
public const COMPONENT_SUBSCRIPTION_TYPE_USAGE_COMPONENT = 1;
public function __construct(
int $type,
string $id,
BillwerkContract $billwerkContract,
string $componentId,
DateTime $startDate,
DateTime $endDate,
?RecurrentJobBooking $recurrentJobBooking = null,
?SelfServiceTrafficCampaignBooking $selfServiceTrafficCampaignBooking = null,
bool $includedInInterimBilling = false
) {
if (!ReflectionHelper::hasConstWithValue(self::class, 'COMPONENT_SUBSCRIPTION_TYPE_', $type)) {
throw new InvalidArgumentException("No component subscription type for value '$type'.");
}
if (is_null($recurrentJobBooking) && is_null($selfServiceTrafficCampaignBooking)) {
throw new InvalidArgumentException('Either recurrentJobBooking or selfServiceTrafficCampaignBooking must be provided.');
}
if (!is_null($recurrentJobBooking) && !is_null($selfServiceTrafficCampaignBooking)) {
throw new InvalidArgumentException('Cannot provide both recurrentJobBooking and selfServiceTrafficCampaignBooking.');
}
$this->type = $type;
$this->id = $id;
$this->billwerkContract = $billwerkContract;
$this->componentId = $componentId;
$this->startDate = $startDate;
$this->endDate = $endDate;
$this->recurrentJobBooking = $recurrentJobBooking;
$this->selfServiceTrafficCampaignBooking = $selfServiceTrafficCampaignBooking;
$this->includedInInterimBilling = $includedInInterimBilling;
}
/**
* @ORM\Column(name="id", type="string")
*
* @ORM\Id
*/
private string $id;
public function getId(): string
{
return $this->id;
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Membership\BillwerkContract")
*
* @ORM\JoinColumn(name="billwerk_contracts_id", onDelete="CASCADE", nullable=false)
*/
private BillwerkContract $billwerkContract;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Membership\RecurrentJobBooking", inversedBy="billwerkComponentSubscriptions", cascade={"persist"})
*
* @ORM\JoinColumn(name="recurrent_job_bookings_id", onDelete="CASCADE", nullable=true)
*/
private ?RecurrentJobBooking $recurrentJobBooking;
public function getRecurrentJobBooking(): ?RecurrentJobBooking
{
return $this->recurrentJobBooking;
}
/**
* @ORM\OneToOne(targetEntity="JanusHercules\SelfServiceTrafficCampaign\Domain\Entity\SelfServiceTrafficCampaignBooking", inversedBy="billwerkComponentSubscription")
*
* @ORM\JoinColumn(name="self_service_traffic_campaign_bookings_id", onDelete="CASCADE", nullable=true)
*/
private ?SelfServiceTrafficCampaignBooking $selfServiceTrafficCampaignBooking;
public function getSelfServiceTrafficCampaignBooking(): ?SelfServiceTrafficCampaignBooking
{
return $this->selfServiceTrafficCampaignBooking;
}
/**
* @ORM\Column(name="component_id", type="string", length=255, nullable=false)
*/
private string $componentId;
public function getComponentId(): string
{
return $this->componentId;
}
/**
* @ORM\Column(name="start_date", type="datetime")
*/
private DateTime $startDate;
public function getStartDate(): DateTime
{
return $this->startDate;
}
/**
* @ORM\Column(name="end_date", type="datetime")
*/
private DateTime $endDate;
public function getEndDate(): DateTime
{
return $this->endDate;
}
public function setEndDate(DateTime $endDate): void
{
$this->endDate = $endDate;
}
/**
* @ORM\Column(name="type", type="integer", nullable=false)
*/
private int $type;
public function getType(): int
{
return $this->type;
}
/**
* @ORM\Column(name="included_in_interim_billing", type="boolean", nullable=false)
*/
private bool $includedInInterimBilling;
public function isIncludedInInterimBilling(): bool
{
return $this->includedInInterimBilling;
}
public function setIsIncludedInInterimBilling(bool $includedInInterimBilling): void
{
$this->includedInInterimBilling = $includedInInterimBilling;
}
public function getComponentContext(): ComponentContext
{
if ($this->recurrentJobBooking !== null) {
return ComponentContext::PLUS_RECURRENT_JOB;
}
if ($this->selfServiceTrafficCampaignBooking !== null) {
return ComponentContext::SELF_SERVICE_TRAFFIC_CAMPAIGN;
}
throw new LogicException('Could not determine component context for BillwerkComponentSubscription: Neither a RecurrentJobBooking nor a SelfServiceTrafficCampaignBooking is set.');
}
}