Entity/UserSubscription.php
<?php
/**
* @author Rafał Muszyński <rafal.muszynski@sourcefabric.org>
* @copyright 2014 Sourcefabric o.p.s.
* @license http://www.gnu.org/licenses/gpl-3.0.txt
*/
namespace Newscoop\PaywallBundle\Entity;
use Newscoop\Entity\Publication;
use Newscoop\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Newscoop\PaywallBundle\Discount\DiscountableInterface;
/**
* Subscription entity.
*
* @ORM\Entity(repositoryClass="Newscoop\PaywallBundle\Entity\Repository\UserSubscriptionRepository")
* @ORM\Table(name="plugin_paywall_user_subscriptions")
*/
class UserSubscription implements DiscountableInterface, ProlongableItemInterface, PriceableInterface
{
const TYPE_PAID = 'P';
const TYPE_PAID_NOW = 'PN';
const TYPE_TRIAL = 'T';
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer", name="Id")
*
* @var int
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Newscoop\Entity\User")
* @ORM\JoinColumn(name="IdUser", referencedColumnName="Id")
*
* @var Newscoop\Entity\User
*/
protected $user;
/**
* @ORM\ManyToOne(targetEntity="Newscoop\PaywallBundle\Entity\Subscription")
* @ORM\JoinColumn(name="IdSubscription", referencedColumnName="id")
*
* @var Newscoop\PaywallBundle\Entity\Subscriptions
*/
protected $subscription;
/**
* @ORM\ManyToOne(targetEntity="Order", inversedBy="items")
* @ORM\JoinColumn(name="order_id", referencedColumnName="id", nullable=false)
*
* @var Order
*/
protected $order;
/**
* @ORM\Column(type="integer", name="discount_total")
*
* @var int
*/
protected $discountTotal = 0;
/**
* @ORM\ManyToOne(targetEntity="Newscoop\Entity\Publication")
* @ORM\JoinColumn(name="IdPublication", referencedColumnName="Id")
*
* @var Newscoop\Entity\Publication
*/
protected $publication;
/**
* @ORM\Column(type="decimal", name="ToPay")
*
* @var float
*/
protected $toPay = 0.0;
/**
* @ORM\Column(name="Type")
*
* @var string
*/
protected $type;
/**
* @ORM\Column(name="Currency")
*
* @var string
*/
protected $currency;
/**
* @ORM\ManyToOne(targetEntity="Newscoop\PaywallBundle\Entity\Trial")
* @ORM\JoinColumn(name="trial_id", referencedColumnName="id")
*
* @var Newscoop\PaywallBundle\Entity\Trial
*/
protected $trial;
/**
* Subscription status visible for admin.
*
* @ORM\Column(name="Active")
*
* @var string
*/
protected $active;
/**
* @ORM\Column(type="datetime", name="created_at")
*
* @var DateTime
*/
protected $created_at;
/**
* @ORM\Column(type="datetime", name="expire_at", nullable=true)
*
* @var DateTime
*/
protected $expire_at;
/**
* Custom field.
*
* @ORM\Column(type="boolean", name="custom")
*
* @var bool
*/
protected $custom;
/**
* Second custom field.
*
* @ORM\Column(type="boolean", name="custom_2")
*
* @var bool
*/
protected $customOther;
/**
* To hide from users totally.
*
* @ORM\Column(type="boolean", name="is_active")
*
* @var bool
*/
protected $is_active;
/**
* Is prolonged?
*
* @ORM\Column(type="boolean", name="prolonged")
*
* @var bool
*/
protected $prolonged = false;
/**
* @ORM\Column(type="datetime", name="notify_sent_first", nullable=true)
*
* @var \DateTime
*/
protected $notifySentLevelOne;
/**
* @ORM\Column(type="datetime", name="notify_sent_second", nullable=true)
*
* @var \DateTime
*/
protected $notifySentLevelTwo;
/**
* @ORM\Column(type="datetime", name="updated_at", nullable=true)
*
* @var \DateTime
*/
protected $updated;
/**
* @ORM\Column(type="array", name="duration")
*
* @var array
*/
protected $duration;
protected $discount;
/**
* @ORM\OneToMany(targetEntity="Modification", mappedBy="orderItem", orphanRemoval=true, cascade={"all"})
*
* @var ArrayCollection
*/
protected $modifications;
/**
* @ORM\ManyToMany(targetEntity="Discount", cascade={"persist"})
* @ORM\JoinTable(name="plugin_paywall_order_item_discount",
* joinColumns={
* @ORM\JoinColumn(name="order_item_id", referencedColumnName="Id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="discount_id", referencedColumnName="id")
* }
* )
*
* @var Discount
*/
protected $discounts;
/**
* @ORM\ManyToOne(targetEntity="UserSubscription", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="Id", onDelete="SET NULL")
*
* @var UserSubscription
*/
protected $parent;
/**
* @ORM\OneToMany(targetEntity="UserSubscription", mappedBy="parent")
* @ORM\OrderBy({"created_at" = "DESC"})
*/
protected $children;
/**
* @ORM\Column(type="datetime", name="starts_at", nullable=true)
*
* @var DateTime
*/
protected $startsAt;
public function __construct()
{
$this->currency = '';
$this->active = 'N';
$this->created_at = new \DateTime();
$this->is_active = false;
$this->custom = false;
$this->customOther = false;
$this->type = self::TYPE_PAID;
$this->notifySentLevelOne = null;
$this->notifySentLevelTwo = null;
$this->modifications = new ArrayCollection();
$this->discounts = new ArrayCollection();
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
return (int) $this->id;
}
/**
* Set subscription.
*
* @param Newscoop\PaywallBundle\Entity\Subscription $subscription
*/
public function setSubscription($subscription)
{
$this->subscription = $subscription;
return $this;
}
/**
* Get subscription.
*
* @return Newscoop\PaywallBundle\Entity\Subscription_specification
*/
public function getSubscription()
{
return $this->subscription;
}
/**
* Set user.
*
* @param Newscoop\Entity\User $user
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user.
*
* @return Newscoop\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set publication.
*
* @param Newscoop\Entity\Publication $publication
*
* @return Newscoop\Entity\Subscription
*/
public function setPublication(Publication $publication)
{
$this->publication = $publication;
return $this;
}
/**
* Get publication.
*
* @return Newscoop\Entity\Publication
*/
public function getPublication()
{
return $this->publication;
}
/**
* Get publication name.
*
* @return string
*/
public function getPublicationName()
{
return $this->publication->getName();
}
/**
* Get publication id.
*
* @return int
*/
public function getPublicationId()
{
return $this->publication->getId();
}
/**
* Set to pay.
*
* @param float $toPay
*
* @return Newscoop\Entity\Subscription
*/
public function setToPay($toPay)
{
$this->toPay = (float) $toPay;
return $this;
}
/**
* Get to pay.
*
* @return float
*/
public function getToPay()
{
return (float) $this->toPay;
}
/**
* Set to pay.
*
* @param float $toPay
*
* @return Newscoop\Entity\Subscription
*/
public function setPrice($toPay)
{
$this->toPay = (float) $toPay;
return $this;
}
/**
* Get to pay.
*
* @return float
*/
public function getPrice()
{
return (float) $this->toPay;
}
/**
* Set type.
*
* @param string $type
*
* @return Newscoop\Entity\Subscription
*/
public function setType($type)
{
$this->type = strtoupper($type) === self::TYPE_TRIAL ? self::TYPE_TRIAL : self::TYPE_PAID;
return $this;
}
/**
* Get type.
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Test if is trial.
*
* @return bool
*/
public function isTrial()
{
return $this->type === self::TYPE_TRIAL;
}
/**
* Set active.
*
* @param bool $active
*
* @return Newscoop\Entity\Subscription
*/
public function setActive($active)
{
$this->active = 'N';
if ($active) {
$this->active = 'Y';
}
return $this;
}
/**
* Is active.
*
* @return bool
*/
public function isActive()
{
return strtoupper($this->active) === 'Y';
}
/**
* Get currency.
*
* @return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* Set currency.
*
* @return string
*/
public function setCurrency($currency)
{
$this->currency = $currency;
return $this;
}
/**
* Get trial.
*
* @return Trial
*/
public function getTrial()
{
return $this->trial;
}
/**
* Set trial.
*
* @return Trial
*/
public function setTrial($trial)
{
$this->trial = $trial;
return $this;
}
/**
* Get create date.
*
* @return datetime
*/
public function getCreatedAt()
{
return $this->created_at;
}
/**
* Set create date.
*
* @param datetime $created_at
*
* @return datetime
*/
public function setCreatedAt(\DateTime $created_at)
{
$this->created_at = $created_at;
return $this;
}
/**
* Get expire date.
*
* @return datetime
*/
public function getExpireAt()
{
return $this->expire_at;
}
/**
* Set expire date.
*
* @param datetime $expire_at
*
* @return datetime
*/
public function setExpireAt(\DateTime $expire_at = null)
{
$this->expire_at = $expire_at;
return $this;
}
/**
* Get status.
*
* @return bool
*/
public function getIsActive()
{
return $this->is_active;
}
/**
* Set status.
*
* @param bool $is_active
*
* @return bool
*/
public function setIsActive($is_active)
{
$this->is_active = $is_active;
return $this;
}
/**
* Gets the Custom field.
*
* @return bool
*/
public function getCustom()
{
return $this->custom;
}
/**
* Sets the Custom field.
*
* @param bool $custom the custom
*
* @return self
*/
public function setCustom($custom)
{
$this->custom = $custom;
return $this;
}
/**
* Gets the Second custom field.
*
* @return bool
*/
public function getCustomOther()
{
return $this->customOther;
}
/**
* Sets the Second custom field.
*
* @param bool $customOther the custom other
*
* @return self
*/
public function setCustomOther($customOther)
{
$this->customOther = $customOther;
return $this;
}
/**
* Gets the value of updated.
*
* @return DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Sets the value of updated.
*
* @param DateTime $updated the updated
*
* @return self
*/
public function setUpdated(\DateTime $updated)
{
$this->updated = $updated;
return $this;
}
/**
* Gets the value of notifySentLevelOne.
*
* @return \DateTime
*/
public function getNotifySentLevelOne()
{
return $this->notifySentLevelOne;
}
/**
* Sets the value of notifySentLevelOne.
*
* @param \DateTime $notifySentLevelOne the notify sent level one
*
* @return self
*/
public function setNotifySentLevelOne(\DateTime $notifySentLevelOne)
{
$this->notifySentLevelOne = $notifySentLevelOne;
return $this;
}
/**
* Gets the value of notifySentLevelTwo.
*
* @return \DateTime
*/
public function getNotifySentLevelTwo()
{
return $this->notifySentLevelTwo;
}
/**
* Sets the value of notifySentLevelTwo.
*
* @param \DateTime $notifySentLevelTwo the notify sent level two
*
* @return self
*/
public function setNotifySentLevelTwo(\DateTime $notifySentLevelTwo)
{
$this->notifySentLevelTwo = $notifySentLevelTwo;
return $this;
}
/**
* Gets the value of discount.
*
* @return array
*/
public function getDiscount()
{
return $this->discount;
}
/**
* Sets the value of discount.
*
* @param array $discount the discount
*
* @return self
*/
public function setDiscount($discount)
{
$this->discount = $discount;
return $this;
}
/**
* Gets the value of duration.
*
* @return array
*/
public function getDuration()
{
return $this->duration;
}
/**
* Sets the value of duration.
*
* @param array $duration the duration
*
* @return self
*/
public function setDuration($duration)
{
$this->duration = $duration;
return $this;
}
/**
* Gets the value of order.
*
* @return Order
*/
public function getOrder()
{
return $this->order;
}
/**
* Sets the value of order.
*
* @param Order $order the order
*
* @return self
*/
public function setOrder(Order $order)
{
$this->order = $order;
return $this;
}
/**
* {@inheritdoc}
*/
public function getDiscountTotal()
{
return $this->discountTotal / 100;
}
/**
* {@inheritdoc}
*/
public function setDiscountTotal($discountTotal)
{
$this->discountTotal = $discountTotal * 100;
return $this;
}
/**
* Gets the value of modifications.
* Can filter modifications by type.
*
* @return ArrayCollection
*/
public function getModifications($type = null)
{
if (null === $type) {
return $this->modifications;
}
return $this->modifications->filter(function (Modification $modification) use ($type) {
return $type === $modification->getLabel();
});
}
/**
* Sets the value of modifications.
*
* @param ArrayCollection $modifications the modifications
*
* @return self
*/
public function setModifications(ArrayCollection $modifications)
{
$this->modifications = $modifications;
return $this;
}
public function addModification(Modification $modification)
{
if (!$this->hasModification($modification)) {
$modification->setOrderItem($this);
$this->modifications->add($modification);
}
return $this;
}
public function hasModification(Modification $modification)
{
return $this->modifications->contains($modification);
}
public function removeModification(Modification $modification)
{
if ($this->hasModification($modification)) {
$modification->setOrderItem(null);
$this->modifications->removeElement($modification);
}
return $this;
}
public function addDiscount($discount)
{
if (!$this->hasDiscount($discount)) {
$this->discounts->add($discount);
}
return $this;
}
public function hasDiscount($discount)
{
return $this->discounts->contains($discount);
}
public function removeDiscount($discount)
{
if ($this->hasDiscount($discount)) {
$this->discounts->removeElement($discount);
}
return $this;
}
/**
* Gets the discounts.
*
* @return Discount
*/
public function getDiscounts()
{
return $this->discounts;
}
/**
* Sets the discounts.
*
* @param ArrayCollection $discounts the discounts
*
* @return self
*/
public function setDiscounts($discounts)
{
$this->discounts = $discounts;
return $this;
}
public function calculateToPay()
{
$this->calculateModificationsAndToPay();
return $this;
}
/**
* Calculates all the modifications together with
* the total discount and unit price for single item.
*
* @return self
*/
public function calculateModificationsAndToPay()
{
$this->discountTotal = 0;
foreach ($this->modifications as $modification) {
$this->toPay -= $modification->getAmount();
$this->discountTotal -= $modification->getAmount() * $this->duration['value'] * 100;
}
$this->toPay = (float) $this->toPay * $this->duration['value'];
if ($this->toPay < 0) {
$this->toPay = 0;
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getProlonged()
{
return $this->prolonged;
}
/**
* {@inheritdoc}
*/
public function setProlonged($prolonged)
{
$this->prolonged = $prolonged;
return $this;
}
/**
* Gets the value of parent.
*
* @return UserSubscription
*/
public function getParent()
{
return $this->parent;
}
/**
* Sets the value of parent.
*
* @param UserSubscription $parent the parent
*
* @return self
*/
public function setParent(UserSubscription $parent)
{
$this->parent = $parent;
return $this;
}
/**
* Gets the value of children.
*
* @return mixed
*/
public function getChildren()
{
return $this->children;
}
/**
* Sets the value of children.
*
* @param mixed $children the children
*
* @return self
*/
public function setChildren($children)
{
$this->children = $children;
return $this;
}
/**
* Gets the value of startsAt.
*
* @return DateTime
*/
public function getStartsAt()
{
return $this->startsAt;
}
/**
* Sets the value of startsAt.
*
* @param DateTime $startsAt the starts at
*
* @return self
*/
public function setStartsAt(\DateTime $startsAt)
{
$this->startsAt = $startsAt;
return $this;
}
}