src/Entity/PurchaseItem.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\Common\Collections\Collection;
  5. use Doctrine\ORM\Mapping as ORM;
  6. /**
  7.  * @ORM\Entity(repositoryClass="App\Repository\PurchaseItemRepository")
  8.  * 
  9.  * 
  10.  * TODO - should we link all purchse meta into a PurchaseItemMeta object instead
  11.  * of storing in the associated Content object?
  12.  * 
  13.  */
  14. class PurchaseItem implements \Serializable 
  15. {
  16.     const STATUS_CURRENT = -2//< the item currently being edited...
  17.     const STATUS_REPLACED = -1;
  18.     const STATUS_INACTIVE 0//< expired...
  19.     const STATUS_ACTIVE 1;   //< active, will not renew item
  20.     const STATUS_ACTIVE_RENEWING 2//< active, will renew
  21.     const STATUS_ACTIVE_RENEWING_FINAL 3//< active, will renew - previously failed an auto-renew attempt and will now retry
  22.     
  23.     // we will add more types in the future
  24.     // *is this necessary? can we just look at the product's type?
  25.     const TYPE_CLASSIFIED "classified";
  26.     const TYPE_DIRECTORY "directory";
  27.     const TYPE_MEMBERSHIP "membership";
  28.     const TYPE_SHOP "shop";
  29.     const TYPE_OTHER "other";
  30.     
  31.     /**
  32.      * @ORM\Id()
  33.      * @ORM\GeneratedValue()
  34.      * @ORM\Column(type="bigint")
  35.      */
  36.     private $id;
  37.     /**
  38.      * @ORM\ManyToOne(targetEntity="App\Entity\Product", inversedBy="purchase_items")
  39.      * @ORM\JoinColumn(nullable=true)
  40.      */
  41.     private $product;
  42.     /**
  43.      * @ORM\Column(type="datetime")
  44.      */
  45.     private $purchase_date;
  46.     /**
  47.      * @ORM\Column(type="integer")
  48.      */
  49.     private $status;
  50.     /**
  51.      * @ORM\Column(type="integer")
  52.      */
  53.     private $payment_failed;
  54.     
  55.     /**
  56.      * @ORM\Column(type="integer")
  57.      */
  58.     private $quantity;
  59.     /**
  60.      * @ORM\ManyToOne(targetEntity="App\Entity\Content", inversedBy="purchase_items", cascade={"persist"})
  61.      * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
  62.      */
  63.     private $content;
  64.     /**
  65.      * @ORM\Column(type="string", length=255)
  66.      */
  67.     private $old_status;
  68.     
  69.     /**
  70.      * @ORM\Column(type="integer")
  71.      */
  72.     private $amount;
  73.     
  74.     /**
  75.      * @ORM\Column(type="integer")
  76.      */
  77.     private $tax;
  78.     /**
  79.      * @ORM\Column(type="datetime", nullable=true)
  80.      */
  81.     private $expires_at;
  82.     /**
  83.      * @ORM\ManyToOne(targetEntity="App\Entity\Purchase", inversedBy="items")
  84.      * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
  85.      */
  86.     private $purchase;
  87.     /**
  88.      * @ORM\Column(type="string", length=255)
  89.      */
  90.     private $type;
  91.     /**
  92.      * @ORM\ManyToOne(targetEntity="App\Entity\PurchaseItem")
  93.      * @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
  94.      */
  95.     private $original_item;
  96.     
  97.     /**
  98.      * @ORM\Column(type="string", length=128)
  99.      */
  100.     private $transaction_id;
  101.     
  102.     /**
  103.      * @ORM\Column(type="integer")
  104.      */
  105.     private $months_renewed;
  106.     /**
  107.      * @ORM\ManyToMany(targetEntity="App\Entity\ProductOptionValue", inversedBy="purchase_items")
  108.      */
  109.     private $product_option_values;
  110.     public function __construct()
  111.     {
  112.         $this->status 0;
  113.         $this->payment_failed 0;
  114.         $this->quantity 1;
  115.         $this->old_status "";
  116.         $this->amount 0;
  117.         $this->tax 0;
  118.         $this->expires_at null;
  119.         $this->purchase_date = new \DateTime("now");
  120.         $this->transaction_id "";
  121.         $this->months_renewed 0;
  122.         $this->purchased_data "";
  123.         $this->product_option_values = new ArrayCollection();
  124.     }
  125.     public function getId()
  126.     {
  127.         return $this->id;
  128.     }
  129.     public function getProduct(): ?Product
  130.     {
  131.         return $this->product;
  132.     }
  133.     public function setProduct(?Product $product): self
  134.     {
  135.         $this->product $product;
  136.         
  137.         // if setting the product - update the amount
  138.         if ($product) {
  139.             $this->amount $product->getPrice();
  140.         }
  141.         return $this;
  142.     }
  143.     public function getPurchaseDate(): ?\DateTimeInterface
  144.     {
  145.         return $this->purchase_date;
  146.     }
  147.     public function setPurchaseDate(\DateTimeInterface $purchase_date): self
  148.     {
  149.         $this->purchase_date $purchase_date;
  150.         return $this;
  151.     }
  152.     
  153.     public function getStatusText ()
  154.     {
  155.         switch ($this->status) {
  156.             /*
  157.             case self::STATUS_EXPIRED:
  158.                 return "Expired";
  159.             */
  160.             case self::STATUS_CURRENT:
  161.                 return "Current";
  162.             
  163.             case self::STATUS_REPLACED:
  164.                 return "Replaced";
  165.                 
  166.             case self::STATUS_ACTIVE:
  167.                 return "Active";
  168.                 
  169.             case self::STATUS_INACTIVE :
  170.             default: 
  171.                 return "Inactive";
  172.         }
  173.     }
  174.     public function getStatus(): ?int
  175.     
  176.         return $this->status;
  177.     }
  178.     public function setStatus(int $status): self
  179.     {
  180.         $this->status $status;
  181.         return $this;
  182.     }
  183.     public function getPaymentFailed(): ?int
  184.     
  185.         return $this->payment_failed;
  186.     }
  187.     public function setPaymentFailed(int $payment_failed): self
  188.     {
  189.         $this->payment_failed $payment_failed;
  190.         return $this;
  191.     }
  192.     public function getQuantity(): ?int
  193.     
  194.         return $this->quantity;
  195.     }
  196.     public function setQuantity(int $quantity): self
  197.     {
  198.         $this->quantity $quantity;
  199.         return $this;
  200.     }
  201.     public function getRecurringDate(): ?\DateTimeInterface
  202.     {
  203.         return $this->recurring_date;
  204.     }
  205.     public function setRecurringDate(\DateTimeInterface $recurring_date): self
  206.     {
  207.         $this->recurring_date $recurring_date;
  208.         return $this;
  209.     }
  210.     public function getModifiedAt(): ?\DateTimeInterface
  211.     {
  212.         return $this->modified_at;
  213.     }
  214.     public function setModifiedAt(\DateTimeInterface $modified_at): self
  215.     {
  216.         $this->modified_at $modified_at;
  217.         return $this;
  218.     }
  219.     public function getCreatedAt(): ?\DateTimeInterface
  220.     {
  221.         return $this->created_at;
  222.     }
  223.     public function setCreatedAt(\DateTimeInterface $created_at): self
  224.     {
  225.         $this->created_at $created_at;
  226.         return $this;
  227.     }
  228.     public function getContent(): ?Content
  229.     {
  230.         return $this->content;
  231.     }
  232.     public function setContent(?Content $content): self
  233.     {
  234.         $this->content $content;
  235.         return $this;
  236.     }
  237.     public function getOldStatus(): ?string
  238.     {
  239.         return $this->old_status;
  240.     }
  241.     public function setOldStatus(string $old_status null): self
  242.     {
  243.         $this->old_status $old_status $old_status "";
  244.         return $this;
  245.     }
  246.     
  247.     //calculate and get the subtotal
  248.     public function getAmount ()
  249.     {
  250.         if($this->getProduct()) {
  251.             $amount $this->getProduct()->getPrice();
  252.             $amount *= $this->getQuantity();
  253.             //$amount += $this->getTax();
  254.             
  255.             
  256.             if(true) { //if dynamic classified ad
  257.                 $firstRegion true;
  258.                 $firstSite true;
  259.                 $featured false;
  260.                 foreach($this->product_option_values as $productOptionValue) {
  261.                     if($productOptionValue->getProductOption() && $productOptionValue->getProductOption()->getTitle() == "graphics" && $productOptionValue->getValue() == "featured") {
  262.                         $amount $productOptionValue->getPrice();
  263.                         $featured true;
  264.                     }
  265.                 }
  266.                 
  267.                 if($featured) {
  268.                     $months 1;
  269.                     foreach($this->product_option_values as $productOptionValue) {
  270.                         if($productOptionValue->getProductOption() && $productOptionValue->getProductOption()->getTitle() == "duration") {
  271.                             switch ($productOptionValue->getValue()) {
  272.                                 case "30":
  273.                                     $months 1;
  274.                                     break;
  275.                                 case "60":
  276.                                     $months 2;
  277.                                     break;
  278.                                 case "90":
  279.                                     $months 3;
  280.                                     break;
  281.                             }
  282.                         }
  283.                     }
  284.                     $amount $amount $months;
  285.                     foreach($this->product_option_values as $productOptionValue) {
  286.                         
  287.                         if($productOptionValue->getProductOption() && $productOptionValue->getProductOption()->getTitle() == "sites") {
  288.                             if($firstSite) {
  289.                                 $firstSite false;
  290.                                 continue;
  291.                             }
  292.                             
  293.                             $amount += $productOptionValue->getPrice();
  294.                         }
  295.                         
  296.                     }
  297.                 }
  298.                 else {
  299.                 
  300.                     foreach($this->product_option_values as $productOptionValue) {
  301.                         //Exception: First region is free for classified ads.
  302.                         if($firstRegion && $productOptionValue->getProductOption() && $productOptionValue->getProductOption()->getTitle() == "regions"
  303.                             && $productOptionValue->getValue() != "All Regions") {
  304.                             $firstRegion false;
  305.                             continue;
  306.                         }
  307.                         //Exception: First site is free
  308.                         if($firstSite && $productOptionValue->getProductOption() && $productOptionValue->getProductOption()->getTitle() == "sites") {
  309.                             $firstSite false;
  310.                             continue;
  311.                         }
  312.                         
  313.                         $amount += $productOptionValue->getPrice();
  314.                         
  315.                     }
  316.                     
  317.                 }
  318.             }
  319.             $this->amount $amount;
  320.         }
  321.         return $this->amount;
  322.     }
  323.     
  324.     //get the stored amount value without calculating it
  325.     public function getStoredAmount ()
  326.     {
  327.         return $this->amount;
  328.     }
  329.     
  330.     public function setAmount ($amount 0)
  331.     {
  332.         $this->amount $amount;
  333.         return $this;
  334.     }
  335.     
  336.     //calculate and get tax
  337.     //*Note: No longer used for purchase items. Instead, tax is calculated per Purchase AFTER all deductions / coupons are applied.
  338.     public function getTax ()
  339.     {
  340.         if($this->getProduct() && $this->getProduct()->getType() == Product::PRODUCT_TYPE_SHOP) {
  341.             //for now, just tax all shop items 7.25%
  342.             $tax_rate 0.0725;
  343.             $amount $this->getProduct()->getPrice();
  344.             $amount *= $this->getQuantity();
  345.             $this->tax $amount $tax_rate;
  346.         }
  347.         return $this->tax;
  348.     }
  349.     
  350.     //get the stored tax value without calculating it
  351.     public function getStoredTax ()
  352.     {
  353.         return $this->tax;
  354.     }
  355.     
  356.     public function setTax ($tax 0)
  357.     {
  358.         $this->tax $tax;
  359.         return $this;
  360.     }
  361.     public function getExpiresAt(): ?\DateTimeInterface
  362.     {
  363.         return $this->expires_at;
  364.     }
  365.     public function setExpiresAt(?\DateTimeInterface $expires_at): self
  366.     {
  367.         $this->expires_at $expires_at;
  368.         return $this;
  369.     }
  370.     public function getPurchase(): ?Purchase
  371.     {
  372.         return $this->purchase;
  373.     }
  374.     public function setPurchase(?Purchase $purchase): self
  375.     {
  376.         $this->purchase $purchase;
  377.         return $this;
  378.     }
  379.     
  380.     public function __toString ()
  381.     {
  382.         return "Purchase Item: {$this->id}";
  383.     }
  384.     public function getType(): ?string
  385.     {
  386.         return $this->type;
  387.     }
  388.     public function setType(string $type null): self
  389.     {
  390.         $this->type $type $type "";
  391.         return $this;
  392.     }
  393.     
  394.     public function getFullAmount ()
  395.     {
  396.         return "$" number_format(($this->getAmount() / 100), 2);
  397.     }
  398.     
  399.     public function getStoredFullAmount ()
  400.     {
  401.         return "$" number_format(($this->getStoredAmount() / 100), 2);
  402.     }
  403.     
  404.     public function getFullTax ()
  405.     {
  406.         return "$" number_format(($this->getTax() / 100), 2);
  407.     }
  408.     
  409.     public function getStoredFullTax ()
  410.     {
  411.         return "$" number_format(($this->getStoredTax() / 100), 2);
  412.     }
  413.     /**
  414.      * @return Collection|PurchaseItem[]
  415.      */
  416.     public function getRenewedItems(): Collection
  417.     {
  418.         return $this->renewed_items;
  419.     }
  420.     public function addRenewedItem(PurchaseItem $renewedItem): self
  421.     {
  422.         if (!$this->renewed_items->contains($renewedItem)) {
  423.             $this->renewed_items[] = $renewedItem;
  424.             $renewedItem->setOriginalItem($this);
  425.         }
  426.         return $this;
  427.     }
  428.     public function removeRenewedItem(PurchaseItem $renewedItem): self
  429.     {
  430.         if ($this->renewed_items->contains($renewedItem)) {
  431.             $this->renewed_items->removeElement($renewedItem);
  432.             // set the owning side to null (unless already changed)
  433.             if ($renewedItem->getOriginalItem() === $this) {
  434.                 $renewedItem->setOriginalItem(null);
  435.             }
  436.         }
  437.         return $this;
  438.     }
  439.     public function getOriginalItem(): ?self
  440.     {
  441.         return $this->original_item;
  442.     }
  443.     /**
  444.      * This is used when a new purchase item is replacing 
  445.      */
  446.     public function setOriginalItem(?self $original_item): self
  447.     {
  448.         $this->original_item $original_item;
  449.         return $this;
  450.     }
  451.     
  452.     public function getTransactionId(): ?int
  453.     {
  454.         return $this->transaction_id;
  455.     }
  456.     public function setTransactionId(string $transaction_id null): self
  457.     {
  458.         $this->transaction_id $transaction_id $transaction_id "";
  459.         return $this;
  460.     }
  461.     
  462.     public function getMonthsRenewed(): ?int
  463.     {
  464.         return $this->months_renewed;
  465.     }
  466.     public function setMonthsRenewed(int $months_renewed): self
  467.     {
  468.         $this->months_renewed $months_renewed;
  469.         
  470.         return $this;
  471.     }
  472.     public function getProductOptionValues(): Collection
  473.     {
  474.         return $this->product_option_values;
  475.     }
  476.     
  477.     public function setProductOptionValues($product_option_values)
  478.     {
  479.         $this->product_option_values $product_option_values;
  480.         return $this;
  481.     }
  482.     
  483.     public function addProductOptionValue(ProductOptionValue $product_option_value): self
  484.     {
  485.         if (!$this->product_option_values->contains($product_option_value)) {
  486.             $this->product_option_values[] = $product_option_value;
  487.             $product_option_value->addPurchaseItem($this);
  488.         }
  489.         return $this;
  490.     }
  491.     
  492.     public function resetProductOptionValues(): self
  493.     {
  494.         $this->product_option_values = new ArrayCollection();
  495.         return $this;
  496.     }
  497.     
  498.     public function removeProductOptionValue(ProductOptionValue $product_option_value): self
  499.     {
  500.         if ($this->product_option_values->contains($product_option_value)) {
  501.             $this->product_option_values->removeElement($product_option_value);
  502.             $product_option_value->removePurchaseItem($this);
  503.         }
  504.         return $this;
  505.     }
  506.     
  507.     // add fields here
  508.     public function serialize ()
  509.     {
  510.         return serialize(array(
  511.             $this->id,
  512.             $this->status,
  513.             $this->amount,
  514.             $this->quantity,
  515.             $this->type,
  516.             $this->product,
  517.         ));
  518.     }
  519.     
  520.     public function unserialize ($serialized)
  521.     {
  522.         list (
  523.             $this->id,
  524.             $this->status,
  525.             $this->amount,
  526.             $this->quantity,
  527.             $this->type,
  528.             $this->product
  529.         ) = unserialize($serialized, array ("allowed_classes" => true));
  530.     }
  531.     
  532.     
  533.     public function toJSON ()
  534.     {
  535.         return json_encode([
  536.             "id" => $this->id,
  537.             "status" => $this->status,
  538.             "amount" => $this->amount,
  539.             "quantity" => $this->quantity,
  540.             "type" => $this->type,
  541.             "product" => $this->product->toJSON(),
  542.         ]);
  543.     }
  544.     
  545.     
  546.     
  547. }