<?php
namespace Whater\Domain\Product\Model;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Ramsey\Uuid\Uuid;
use Whater\Domain\Common\Exception\InvalidUUIDException;
use Whater\Domain\Product\Exception\InvalidCouponException;
use Whater\Domain\Whater\Model\WhaterOrganization;
/**
*
* @package Whater\Domain\Product\Model
*/
class WhatercoinCoupon
{
const COUPON_DEFAULT_DAYS = 180;
/**
* @var string
*/
protected $uuid;
/**
* @var string
*/
private $code;
/**
* @var WhaterOrganization
*/
private $whaterOrganization;
/**
* @var float
*/
private $whatercoinsPerUser;
/**
* @var float
*/
private $maxWhatercoins;
/**
* @var string
*/
private $message;
/**
* @var Collection
*/
private $users;
/**
* @var \DateTime
*/
private $createdAt;
/**
* @var \DateTime
*/
private $expiredAt;
public function __construct(
string $uuid = null,
WhaterOrganization $whaterOrganization,
string $code = null,
string $message = null,
float $maxWhatercoins,
float $whatercoinsPerUser,
\DateTime $expiredAt = null
) {
try {
$this->uuid = Uuid::fromString($uuid ?: Uuid::uuid4())->toString();
} catch (\InvalidArgumentException $e) {
throw new InvalidUUIDException();
}
$this->whaterOrganization = $whaterOrganization;
$this->createdAt = new \DateTime();
$this->users = new ArrayCollection();
$this->message = $message;
if (!is_null($code)) {
$this->code = strtoupper($code);
} else {
$this->code = strtoupper(substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10));
}
if ($maxWhatercoins > 0) {
$this->maxWhatercoins = $maxWhatercoins;
} else {
throw new InvalidCouponException();
}
if ($whatercoinsPerUser > 0) {
$this->whatercoinsPerUser = $whatercoinsPerUser;
} else if ($whatercoinsPerUser > $maxWhatercoins) {
throw new InvalidCouponException();
} else {
throw new InvalidCouponException();
}
if (!is_null($expiredAt)) {
$this->expiredAt = $expiredAt;
} else {
$this->expiredAt = clone $this->createdAt;
$this->expiredAt->modify('+' . WhatercoinCoupon::COUPON_DEFAULT_DAYS . ' days');
}
}
public function isValid(): bool
{
if (($this->users()->count() * $this->whatercoinsPerUser()) >= $this->maxWhatercoins()) {
//check max number of uses
return false;
}
$now = new \DateTime();
if ($this->expiredAt() < $now) {
//check expiration date
return false;
}
return true;
}
public function updateWhatercoinCoupon(
string $code = null,
string $message = null,
float $maxWhatercoins,
float $whatercoinsPerUser,
\DateTime $expiredAt = null
): WhatercoinCoupon {
$this->code = strtoupper($code);
if ($maxWhatercoins > 0) {
$this->maxWhatercoins = $maxWhatercoins;
} else {
throw new InvalidCouponException();
}
if ($whatercoinsPerUser > 0) {
$this->whatercoinsPerUser = $whatercoinsPerUser;
} else if ($whatercoinsPerUser > $maxWhatercoins) {
throw new InvalidCouponException();
} else {
throw new InvalidCouponException();
}
$this->message = $message;
$today = new \DateTime();
if ($expiredAt >= $today) {
$this->expiredAt = $expiredAt;
}
return $this;
}
/**
* @return string
*/
public function id(): string
{
return $this->uuid;
}
/**
* @return string
*/
public function code(): string
{
return $this->code;
}
/**
* @return string
*/
public function message(): ?string
{
return $this->message;
}
/**
* @return WhaterOrganization
*/
public function whaterOrganization(): WhaterOrganization
{
return $this->whaterOrganization;
}
/**
* @return float
*/
public function whatercoinsPerUser(): float
{
return $this->whatercoinsPerUser;
}
/**
* @return float
*/
public function maxWhatercoins(): float
{
return $this->maxWhatercoins;
}
/**
* @return Collection
*/
public function users(): Collection
{
return $this->users;
}
/**
* @return \DateTime
*/
public function expiredAt(): \DateTime
{
return $this->expiredAt;
}
/**
* @return \DateTime
*/
public function createdAt(): \DateTime
{
return $this->createdAt;
}
}