<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use \DateTime as DateTime;
use \DateInterval as DateInterval;
/**
* @ORM\Entity(repositoryClass="App\Repository\PurchaseRepository")
*
* This class is the equivalent of the user's shopping cart. Users can add multiple purchase items into
* their Purchase items
*/
class Purchase
{
const STATUS_PROCESSING = -2; //< status not in use currently
const STATUS_ACTIVE = -1; //< means that the purchase / cart is being edited still.. - TODO change to "current"
const STATUS_FAILED = 0; //< means that the purchase / cart order failed...
const STATUS_PROCESSED = 1; //< means that the purchase / cart is done and paid for...
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Version @ORM\Column(type="integer")
*/
private $version;
/**
* @ORM\OneToMany(targetEntity="App\Entity\PurchaseItem", mappedBy="purchase", cascade={"persist"})
* @ORM\JoinColumn(nullable=true)
*/
private $items;
/**
* @ORM\Column(type="bigint")
*/
private $total;
/**
* @ORM\Column(type="bigint")
*/
private $discount;
/**
* @ORM\Column(type="bigint")
*/
private $tax;
/**
* @ORM\Column(type="string", length=255) - not used
*/
private $customer;
/**
* @ORM\Column(type="string", length=255)
*/
private $address_line_1;
/**
* @ORM\Column(type="string", length=255)
*/
private $address_line_2;
/**
* @ORM\Column(type="string", length=255)
*/
private $city;
/**
* @ORM\Column(type="string", length=255)
*/
private $state_province;
/**
* @ORM\Column(type="string", length=32)
*/
private $postal_code;
/**
* @ORM\Column(type="string", length=255)
*/
private $country;
/**
* @ORM\Column(type="string", length=255)
*/
private $company;
/**
* @ORM\Column(type="string", length=255)
*/
private $email;
/**
* @ORM\Column(type="string", length=32)
*/
private $phone;
/**
* @ORM\Column(type="string", length=4)
*/
private $last4;
/**
* @ORM\Column(type="string", length=128)
*/
private $transaction_number;
/**
* @ORM\Column(type="datetime", nullable=true)
*
* not sure if this is used...
*/
private $recurring_date;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $modified_at;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $created_at;
/**
* @ORM\OneToMany(targetEntity="App\Entity\PurchaseNote", mappedBy="purchase", cascade={"persist"})
*/
private $purchaseNotes;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="purchases")
* @ORM\JoinColumn(nullable=true)
*/
private $user;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $raw_response;
/**
* @ORM\Column(type="string", length=255)
*/
private $user_agent;
/**
* @ORM\Column(type="string", length=64)
*/
private $user_ip;
/**
* @ORM\Column(type="integer")
*/
private $status;
/**
* @ORM\Column(type="string", length=255)
*/
private $first_name;
/**
* @ORM\Column(type="string", length=255)
*/
private $last_name;
/**
* @ORM\Column(type="string", length=16)
*/
private $expiration_date;
/**
* @ORM\Column(type="datetime")
*/
private $purchased_at;
/**
* @ORM\Column(type="bigint")
*/
private $purchased_amount;
/**
* @ORM\Column(type="text")
*/
private $purchased_data;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Coupon", inversedBy="purchases")
*/
private $coupons;
/**
* @ORM\Column(type="boolean")
*/
private $terms_agree;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_first_name;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_last_name;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_company;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_country;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_address_line_1;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_address_line_2;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_city;
/**
* @ORM\Column(type="string", length=255)
*/
private $shipping_state_province;
/**
* @ORM\Column(type="string", length=32)
*/
private $shipping_postal_code;
/**
* @ORM\Column(type="boolean")
*/
private $admin_quick_purchase;
public function __construct()
{
$this->total = 0;
$this->first_name = "";
$this->last_name = "";
$this->customer = "";
$this->address_line_1 = "";
$this->address_line_2 = "";
$this->city = "";
$this->state_province = "";
$this->postal_code = "";
$this->country = "";
$this->company = "";
$this->email = "";
$this->phone = "";
$this->last4 = "";
$this->transaction_number = "";
$this->recurring_date = null;
$this->modified_at = new \DateTime("now");
$this->created_at = new \DateTime("now");
$this->raw_response = "";
$this->user_agent = "";
$this->user_ip = "";
$this->status = self::STATUS_ACTIVE;
$this->items = new ArrayCollection();
$this->purchaseNotes = new ArrayCollection();
// is this considered too personal? - won't store for now...
$this->expiration_date = "";
$this->purchased_at = new \DateTime("now");
$this->coupons = new ArrayCollection();
$this->terms_agree = 0;
$this->admin_quick_purchase = 0;
$this->purchased_data = "";
$this->purchased_amount = 0;
$this->discount = 0;
$this->tax = 0;
$this->shipping_first_name = "";
$this->shipping_last_name = "";
$this->shipping_company = "";
$this->shipping_country = "";
$this->shipping_address_line_1 = "";
$this->shipping_address_line_2 = "";
$this->shipping_city = "";
$this->shipping_state_province = "";
$this->shipping_postal_code = "";
}
public function getId()
{
return $this->id;
}
public function getVersion() {
return $this->version;
}
public function getInvoiceNumber ()
{
return str_pad($this->id, 8, "0", STR_PAD_LEFT);
}
/**
* @return Collection|PurchaseNote[]
*/
public function aseNotes(): Collection
{
return $this->purchaseNotes;
}
public function addPurchaseNote(purchaseNote $purchaseNote): self
{
if (!$this->purchaseNotes->contains($purchaseNote)) {
$this->purchaseNotes[] = $purchaseNote;
$purchaseNote->setPurchase($this);
}
return $this;
}
public function removePurchaseNote(purchaseNote $purchaseNote): self
{
if ($this->purchaseNotes->contains($purchaseNote)) {
$this->purchaseNotes->removeElement($purchaseNote);
// set the owning side to null (unless already changed)
if ($purchaseNote->getPurchase() === $this) {
$purchaseNote->setPurchase(null);
}
}
return $this;
}
public function getPurchaseNotes()
{
return $this->purchaseNotes;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getCurrentItem (): ?PurchaseItem
{
for ($i = 0; $i < count($this->items); $i++) {
$item = $this->items[$i];
if ($item->getStatus() == PurchaseItem::STATUS_CURRENT) {
return $item;
}
}
return null;
}
/**
* This function will overwrite previous purchase item - not sure if this will cause issues
* when purchasing between directory and classified listing
*/
public function setCurrentItem (PurchaseItem $item): self
{
$item->setStatus(PurchaseItem::STATUS_CURRENT);
// add the total if available
$product = $item->getProduct();
if ($product) {
$this->total += $product->getPrice();
}
for ($i = 0; $i < count($this->items); $i++) {
$temp = $this->items[$i];
if ($temp->getStatus() == PurchaseItem::STATUS_CURRENT) {
$this->items[$i] = $item;
$item->setPurchase($this);
return $this;
}
}
// if reached simply add to end of array
$this->items[] = $item;
return $this;
}
/**
* @return Collection|PurchaseItem[]
*/
public function getItems(): Collection
{
return $this->items;
}
public function addItem(PurchaseItem $item): self
{
if (!$this->items->contains($item)) {
$this->items[] = $item;
$item->setPurchase($this);
}
return $this;
}
public function countTotalItems(): int
{
$count = 0;
foreach($this->getItems() as $item) {
$count += $item->getQuantity();
}
return $count;
}
public function removeItem(PurchaseItem $item): self
{
if ($this->items->contains($item)) {
$this->items->removeElement($item);
// set the owning side to null (unless already changed)
if ($item->getPurchase() === $this) {
$item->setPurchase(null);
}
}
return $this;
}
public function getProductTypes() {
$productTypes = [];
foreach($this->items as $item) {
if(!in_array($item->getType(), $productTypes)) {
$productTypes[] = $item->getType();
}
}
foreach($productTypes as &$type) {
if($type == "classified") {
$type = "Classified Listing";
}
elseif($type == "directory") {
$type = "Directory Listing";
}
elseif($type == "shop") {
$type = "RCS Gift Shop";
}
elseif($type == "membership") {
$type = "R-Club Membership";
}
else {
$type = ucwords($type);
}
}
return implode(", ", $productTypes);
}
/**
* Should be called when a purchase is finalized. - this will serialize all of the product data,
* and coupon data to keep a historical record of the purchase - this is because entity
* relations will change and update over time but we want to keep some history the same
*/
public function finalize ()
{
$items = [];
for ($i = 0; $i < count($this->items); $i++) {
$item = $this->items[$i];
$items[] = $item->toJSON();
}
$coupons = [];
for ($i = 0; $i < count($this->coupons); $i++) {
$coupon = $this->coupons[$i];
$coupons[] = $coupon->toJSON();
}
$breakdownJson = $this->calculateBreakdown();
$breakdownJson = substr($breakdownJson["json"], 1, -1); //remove the outer {}'s since we're placing in json below
// store the data
$this->purchased_data = '{"items":['.implode(",", $items).'],"coupons":['.implode(",", $coupons).'],'.$breakdownJson.'}';
$this->purchased_amount = $this->calculateTotal();
}
//return an array of the purchase breakdown (subtotal, discounts, taxes, total, and all by type)
public function calculateBreakdown ($items = null, $coupons = null)
{
if(is_null($items)) {
$items = $this->items;
}
if(is_null($coupons)) {
$coupons = $this->getCoupons();
}
$subTotalsPerType = [];
$discountsPerType = [];
$taxesPerType = [];
$finalsPerType = [];
for ($i = 0; $i < count($items); $i++) {
$amount = $items[$i]->getAmount();
$product = $items[$i]->getProduct();
if (!$amount) {
$amount = $product->getPrice();
}
if(!isset($subTotalsPerType[$product->getType()])) {
$subTotalsPerType[$product->getType()] = 0;
$discountsPerType[$product->getType()] = 0;
$taxesPerType[$product->getType()] = 0;
}
$subTotalsPerType[$product->getType()] += $amount;
}
// apply any assigned coupons... and double check that coupons are valid
foreach ($coupons as $coupon) {
//amount discount for this coupon
$amount = 0;
$prod_type = $coupon->getProductType();
if(!isset($subTotalsPerType[$prod_type])) {
continue;
}
//$subTotalsPerType[$prod_type];
switch ($coupon->getType()) {
case Coupon::TYPE_DISCOUNT:
$amount = $coupon->getAmount();
if (strpos($amount, ".") === false) {
$amount = "{$amount}00";
}
$amount = preg_replace("/[^0-9]*/", "", $amount);
break;
case Coupon::TYPE_PERCENTAGE:
$amount = $coupon->getAmount();
/*
if (strpos($amount, "%") !== false) {
// percentage amount
$amount = str_replace("%", "", $amount);
$amount = (double) $amount / 100;
$amount = ($total * $amount);
}
else if (strpos($amount, ".") !== false) {
// fraction amount
$amount = (double) $amount;
$amount = ($total * $amount);
}*/
$amount = (double) $amount / 100;
$amount = ($subTotalsPerType[$prod_type] * $amount);
break;
case Coupon::TYPE_FREE_PRODUCT:
$couponProducts = $coupon->getProducts();
// see if we have this product currently attached to the purchase
for ($j = 0; $j < count($items); $j++) {
$product = $items[$j]->getProduct();
// if the coupon contains the product add the amount to the discount
if ($couponProducts->contains($product)) {
$amount = $product->getPrice();
// set the amount in the coupon... since it was not provided
$coupon->setAmount($product->getPrice());
break;
}
}
break;
}
if ($amount) {
$discountsPerType[$prod_type] += $amount;
$discountsPerType[$prod_type] = min($discountsPerType[$prod_type], $subTotalsPerType[$prod_type]); //can't discount > 100%
}
}
$subtotal = 0;
$discount = 0;
$tax = 0;
$final = 0;
foreach($subTotalsPerType as $prod_type => $total) {
$subtotal += $total;
$finalsPerType[$prod_type] = $subTotalsPerType[$prod_type] - $discountsPerType[$prod_type];
//Calculate taxes. Current only taxing gift shop items, all purchases use California's sales tax rate.
if($prod_type == Product::PRODUCT_TYPE_SHOP) {
$tax_rate = 0.0725;
$taxesPerType[$prod_type] = $finalsPerType[$prod_type] * $tax_rate;
$finalsPerType[$prod_type] += $taxesPerType[$prod_type];
}
$discount += $discountsPerType[$prod_type];
$tax += $taxesPerType[$prod_type];
$final += $finalsPerType[$prod_type];
}
$this->discount = $discount;
$this->tax = $tax;
$return = [
"total" => $final,
"json" => json_encode([
"subTotalsPerType" => $subTotalsPerType,
"discountsPerType" => $discountsPerType,
"taxesPerType" => $taxesPerType,
"finalsPerType" => $finalsPerType,
"subtotal" => $subtotal,
"discount" => $discount,
"tax" => $tax,
"total" => $final,
])
];
return $return;
//return $final;
}
//Check if this purchase requires shipping info. Currently includes all gift shop items.
public function requiresShipping(): ?bool {
$require_shipping = false;
foreach($this->items as $item) {
$product = $item->getProduct();
if($product->getType() == Product::PRODUCT_TYPE_SHOP) {
$require_shipping = true;
}
}
return $require_shipping;
}
//Check if this purchase will require billing; either now, or in the future if recurring and coupons expire
public function requiresBilling(): ?bool {
if($this->calculateTotal() > 0) {
return true;
}
$recurringItems = [];
$recurringCoupons = [];
foreach($this->items as $item) {
$product = $item->getProduct();
if($product->getPaymentRate() && ($product->getPaymentRate() != "none")) {
$recurringItems[] = $item;
}
}
foreach($this->getCoupons() as $coupon) {
if($coupon->getRecurringType() == Coupon::RECURRING_UNLIMITED) {
$recurringCoupons[] = $coupon;
}
}
$breakdown = $this->calculateBreakdown($recurringItems, $recurringCoupons);
$total = $breakdown["total"];
return $total > 0;
}
public function calculateTotal (): ?int
{
$breakdown = $this->calculateBreakdown();
return $breakdown["total"];
}
//Return the total without any discounts / taxes
public function calculateSubTotal (): ?int
{
$subtotal = 0;
for ($i = 0; $i < count($this->items); $i++) {
$amount = $this->items[$i]->getAmount();
if (!$amount) {
$product = $this->items[$i]->getProduct();
$amount = $product->getPrice();
}
$subtotal += $amount;
}
return $subtotal;
}
public function getTotal(): ?int
{
$total = $this->calculateTotal();
/*
$total = 0;
for ($i = 0; $i < count($this->items); $i++) {
$amount = $this->items[$i]->getAmount();
if (!$amount) {
$product = $this->items[$i]->getProduct();
$amount = $product->getPrice();
}
$total += $amount;
}
// apply any assigned coupons... and make sure coupons are valid
*/
$this->total = $total;
return $this->total;
}
public function getSubTotalUsd ($asDecimal = false): string
{
$total = $this->calculateSubTotal();
if ($asDecimal) {
return number_format(($total / 100), 2, ".", "");
} else {
return "$" . number_format(($total / 100), 2);
}
}
public function getTotalUsd ($asDecimal = false): string
{
$total = $this->getTotal();
if ($asDecimal) {
return number_format(($total / 100), 2, ".", "");
} else {
return "$" . number_format(($total / 100), 2);
}
}
public function setTotal(int $total): self
{
$this->total = $total;
return $this;
}
//Total discount
public function getDiscount(): ?int
{
return $this->discount;
}
public function getDiscountUsd ($asDecimal = false): string
{
$discount = $this->getDiscount();
if ($asDecimal) {
return number_format(($discount / 100), 2, ".", "");
} else {
return "$" . number_format(($discount / 100), 2);
}
}
public function setDiscount(int $discount): self
{
$this->discount = $discount;
return $this;
}
//Total taxes
public function getTax(): ?int
{
return $this->tax;
}
public function getTaxUsd ($asDecimal = false): string
{
$tax = $this->getTax();
if ($asDecimal) {
return number_format(($tax / 100), 2, ".", "");
} else {
return "$" . number_format(($tax / 100), 2);
}
}
public function setTax(int $tax): self
{
$this->tax = $tax;
return $this;
}
public function getRecurringDate(): ?\DateTimeInterface
{
return $this->recurring_date;
}
public function setRecurringDate(\DateTimeInterface $recurring_date): self
{
$this->recurring_date = $recurring_date;
return $this;
}
public function getModifiedAt(): ?\DateTimeInterface
{
return $this->modified_at;
}
public function setModifiedAt(\DateTimeInterface $modified_at): self
{
$this->modified_at = $modified_at;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getStatus(): ?int
{
return $this->status;
}
public function getStatusText (): string
{
switch ($this->status) {
case self::STATUS_PROCESSING:
return "Processing";
case self::STATUS_ACTIVE:
return "In Cart";
case self::STATUS_FAILED:
return "Failed";
case self::STATUS_PROCESSED:
default:
return "Processed";
}
}
public function setStatus(int $status): self
{
//return if the status didn't change
if($this->status == $status) {
return $this;
}
$this->status = $status;
// if the purchase is processed - move through all purchase items and content and set appropriate
// renewal and expiration dates.
if ($status == self::STATUS_PROCESSED) {
$this->purchased_at = new \DateTime("now");
// this should really be cleaned up to follow a better flow...
$this->finalize();
for ($i = 0; $i < count($this->items); $i++) {
$item = $this->items[$i];
$product = $item->getProduct();
$rate = strtoupper($product->getPaymentRate());
$content = $item->getContent();
// grab the purchased date
$purchased = $this->getPurchasedAt();
// 1 month interval default
$interval = new DateInterval("P1M");
$intervalSet = false;
foreach($item->getProductOptionValues() as $productOptionValue) {
$productOption = $productOptionValue->getProductOption();
if($productOption && $productOption->getTitle() == "duration") {
$interval = new DateInterval("P".$productOptionValue->getValue()."D");
$intervalSet = true;
}
}
if(!$intervalSet) {
switch ($rate) {
case Product::RENEW_MONTHLY:
$interval = new DateInterval("P1M");
break;
case Product::RENEW_YEARLY:
$interval = new DateInterval("P1Y");
break;
case Product::RENEW_NOT_SET:
default:
// ugly hack ... try to determine from title of product...
$title = $product->getTitle();
if (stripos($title, "annual") !== false) {
$interval = new DateInterval("P1Y");
}
else if (stripos($title, "30 day") !== false) {
$interval = new DateInterval("P30D");
}
else if (stripos($title, "60 day") !== false) {
$interval = new DateInterval("P60D");
}
else if (stripos($title, "90 day") !== false) {
$interval = new DateInterval("P90D");
}
else {
// catch all - give the content 1 active month if can't figure out renewal time
$interval = new DateInterval("P1M");
}
break;
}
}
// set the proper expiration times ...
if ($content) {
// update the published at
$content->setPublishedAt(new DateTime("now"));
$expires = $content->getExpiresAt();
// if exists and is valid
if ($expires && new DateTime("now") < $expires) {
// content has not yet expired
$expires = clone $expires;
$content->setExpiresAt($expires->add($interval));
$content->setStatus(Content::STATUS_ACTIVE);
}
else {
// content has either expired or is invalid
$expires = clone $purchased;
$content->setExpiresAt($expires->add($interval));
$content->setStatus(Content::STATUS_ACTIVE);
}
}
//shop items don't expire
if($product->getType() == Product::PRODUCT_TYPE_SHOP) {
$item->setStatus(PurchaseItem::STATUS_ACTIVE);
}
else {
// the below really shouldn't matter because we are making a new purchase item when renewing
$expires = $item->getExpiresAt();
if ($expires && new DateTime("now") < $expires) {
$expires = clone $expires;
$item->setExpiresAt($expires->add($interval));
$item->setStatus(PurchaseItem::STATUS_ACTIVE);
}
else {
// item
$expires = clone $purchased;
$item->setExpiresAt($expires->add($interval));
$item->setStatus(PurchaseItem::STATUS_ACTIVE);
}
}
$item->setMonthsRenewed(1);
//Handle the RCS Club Membership product
if($product->getType() == Product::PRODUCT_TYPE_MEMBERSHIP) {
$user = $this->getUser();
if($user) {
$user->setMember(1);
//handle company memberships. should make this a different type, but for now just checking the title
if(strpos($product->getTitle(), 'Company') !== false) {
$user->setMember(2);
}
elseif(strpos($product->getTitle(), 'Contractor') !== false) {
$user->setMember(3);
}
//Changed to opt-in
//if(strlen($user->getUserMetaValueByKey("member_notification_forum")) == 0) {$user->setUsermetum("member_notification_forum", "1");};
//if(strlen($user->getUserMetaValueByKey("member_notification_page")) == 0) {$user->setUsermetum("member_notification_page", "1");};
//if(strlen($user->getUserMetaValueByKey("member_notification_classifieds")) == 0) {$user->setUsermetum("member_notification_classifieds", "1");};
//set to auto renew. should move this above when classified / directory auto renewal is working
$item->setStatus(PurchaseItem::STATUS_ACTIVE_RENEWING);
}
}
}
// all dates should be updated
}
return $this;
}
public function getCustomer(): ?string
{
return $this->customer;
}
public function setCustomer(string $customer = null): self
{
$this->customer = $customer ? $customer : "";
return $this;
}
public function getAddressLine1(): ?string
{
return $this->address_line_1;
}
public function setAddressLine1(string $address_line_1 = null): self
{
$this->address_line_1 = $address_line_1 ? $address_line_1 : "";
return $this;
}
public function getAddressLine2(): ?string
{
return $this->address_line_2;
}
public function setAddressLine2(string $address_line_2 = null): self
{
$this->address_line_2 = $address_line_2 ? $address_line_2 : "";
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(string $city = null): self
{
$this->city = $city ? $city : "";
return $this;
}
public function getStateProvince(): ?string
{
return $this->state_province;
}
public function setStateProvince(string $state_province = null): self
{
$this->state_province = $state_province ? $state_province : "";
return $this;
}
public function getPostalCode(): ?string
{
return $this->postal_code;
}
public function setPostalCode(string $postal_code = null): self
{
$this->postal_code = $postal_code ? $postal_code : "";
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(string $country = null): self
{
$this->country = $country ? $country : "";
return $this;
}
public function getCompany(): ?string
{
return $this->company;
}
public function setCompany(string $company = null): self
{
$this->company = $company ? $company : "";
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email = null): self
{
$this->email = $email ? $email : "";
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(string $phone = null): self
{
$this->phone = $phone ? $phone : "";
return $this;
}
public function getLast4(): ?string
{
return $this->last4;
}
public function setLast4(string $last4 = null): self
{
$this->last4 = $last4 ? $last4 : "";
return $this;
}
public function getTransactionNumber()
{
return $this->transaction_number;
}
public function setTransactionNumber(string $transaction_number = null): self
{
$this->transaction_number = $transaction_number ? $transaction_number : "";
return $this;
}
public function __toString ()
{
return "Purchase: {$this->id}";
}
public function getFirstName(): ?string
{
return $this->first_name;
}
public function setFirstName(string $first_name = null): self
{
$this->first_name = $first_name ? $first_name : "";
return $this;
}
public function getLastName(): ?string
{
return $this->last_name;
}
public function setLastName(string $last_name = null): self
{
$this->last_name = $last_name ? $last_name : "";
return $this;
}
public function getExpirationDate(): ?string
{
return $this->expiration_date;
}
public function setExpirationDate(string $expiration_date): self
{
$this->expiration_date = $expiration_date;
return $this;
}
public function getRawResponse(): ?string
{
return $this->raw_response;
}
public function setRawResponse(?string $raw_response): self
{
$this->raw_response = $raw_response;
return $this;
}
public function getUserAgent(): ?string
{
return $this->user_agent;
}
public function setUserAgent(string $user_agent): self
{
$this->user_agent = $user_agent;
return $this;
}
public function getUserIp(): ?string
{
return $this->user_ip;
}
public function setUserIp(string $user_ip): self
{
$this->user_ip = $user_ip;
return $this;
}
public function getPurchasedAt(): ?\DateTimeInterface
{
return $this->purchased_at;
}
public function setPurchasedAt(\DateTimeInterface $purchased_at): self
{
$this->purchased_at = $purchased_at;
return $this;
}
public function getPurchasedAmount(): ?int
{
return $this->purchased_amount;
}
public function setPurchasedAmount(int $purchased_amount): self
{
$this->purchased_amount = $purchased_amount;
return $this;
}
public function getPurchasedData(): ?string
{
return $this->purchased_data;
}
public function setPurchasedData(string $purchased_data): self
{
$this->purchased_data = $purchased_data;
return $this;
}
/**
* @return Collection|Coupon[]
*/
public function getCoupons(): Collection
{
return $this->coupons;
}
public function addCoupon(Coupon $coupon): self
{
if (!$this->coupons->contains($coupon)) {
$this->coupons[] = $coupon;
}
return $this;
}
public function removeCoupon(Coupon $coupon): self
{
if ($this->coupons->contains($coupon)) {
$this->coupons->removeElement($coupon);
}
return $this;
}
public function removeCoupons (): self
{
foreach ($this->coupons as $coupon) {
$this->removeCoupon($coupon);
}
return $this;
}
public function getTermsAgree(): ?bool
{
return $this->terms_agree;
}
public function setTermsAgree(bool $terms_agree): self
{
$this->terms_agree = $terms_agree;
return $this;
}
public function getAdminQuickPurchase(): ?bool
{
return $this->admin_quick_purchase;
}
public function setAdminQuickPurchase(bool $admin_quick_purchase): self
{
$this->admin_quick_purchase = $admin_quick_purchase;
return $this;
}
public function getBilling(): ?string
{
return $this->getFirstName() . " " . $this->getLastName() . ($this->getFirstName() ? ", " : "") .
$this->getCompany() . ($this->getCompany() ? ", " : "") . $this->getAddressLine1() . " " .
$this->getAddressLine2() . ($this->getAddressLine1() ? ", " : "") . $this->getCity() . ($this->getCity() ? ", " : "") .
$this->getStateProvince() . ($this->getStateProvince() ? ", " : "") . $this->getPostalCode()
;
}
public function getShippingFirstName(): ?string
{
return $this->shipping_first_name;
}
public function setShippingFirstName(string $shipping_first_name = null): self
{
$this->shipping_first_name = $shipping_first_name ? $shipping_first_name : "";
return $this;
}
public function getShippingLastName(): ?string
{
return $this->shipping_last_name;
}
public function setShippingLastName(string $shipping_last_name = null): self
{
$this->shipping_last_name = $shipping_last_name ? $shipping_last_name : "";
return $this;
}
public function getShippingCompany(): ?string
{
return $this->shipping_company;
}
public function setShippingCompany(string $shipping_company = null): self
{
$this->shipping_company = $shipping_company ? $shipping_company : "";
return $this;
}
public function getShippingCountry(): ?string
{
return $this->shipping_country;
}
public function setShippingCountry(string $shipping_country = null): self
{
$this->shipping_country = $shipping_country ? $shipping_country : "";
return $this;
}
public function getShippingAddressLine1(): ?string
{
return $this->shipping_address_line_1;
}
public function setShippingAddressLine1(string $shipping_address_line_1 = null): self
{
$this->shipping_address_line_1 = $shipping_address_line_1 ? $shipping_address_line_1 : "";
return $this;
}
public function getShippingAddressLine2(): ?string
{
return $this->shipping_address_line_2;
}
public function setShippingAddressLine2(string $shipping_address_line_2 = null): self
{
$this->shipping_address_line_2 = $shipping_address_line_2 ? $shipping_address_line_2 : "";
return $this;
}
public function getShippingCity(): ?string
{
return $this->shipping_city;
}
public function setShippingCity(string $shipping_city = null): self
{
$this->shipping_city = $shipping_city ? $shipping_city : "";
return $this;
}
public function getShippingStateProvince(): ?string
{
return $this->shipping_state_province;
}
public function setShippingStateProvince(string $shipping_state_province = null): self
{
$this->shipping_state_province = $shipping_state_province ? $shipping_state_province : "";
return $this;
}
public function getShippingPostalCode(): ?string
{
return $this->shipping_postal_code;
}
public function setShippingPostalCode(string $shipping_postal_code = null): self
{
$this->shipping_postal_code = $shipping_postal_code ? $shipping_postal_code : "";
return $this;
}
}