Newer
Older
use function GuzzleHttp\Promise\queue;
use QUI\ERP\Discount\Handler as DiscountHandler;
*
* @var int
*/
protected $id;
/**
* Actual code
*
* @var string
*/
protected $code;
/**
/**
* IDs of all linked discounts
*
* @var int[]
*/
protected $discountIds = [];
*
* @var \DateTime
*/
protected $ValidUntilDate = null;
/**
protected $maxUsages = Handler::MAX_USAGE_ONCE_PER_USER;
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.not_found',
[
$this->id = (int)$data['id'];
$this->code = $data['code'];
$this->title = $data['title'];
$this->usages = \json_decode($data['usages'], true);
$this->userIds = \json_decode($data['userIds'], true);
$this->groupIds = \json_decode($data['groupIds'], true);
if (!empty($data['maxUsages'])) {
$this->maxUsages = $data['maxUsages'];
$this->discountIds = \json_decode($data['discountIds'], true);
$this->CreateDate = new \DateTime($data['createDate']);
if (!empty($data['validUntilDate'])) {
$this->ValidUntilDate = new \DateTime($data['validUntilDate']);
}
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* @return \DateTime
*/
public function getCreateDate()
{
return $this->CreateDate;
}
/**
}
/**
* @return \DateTime|null
*/
public function getValidUntilDate()
{
return $this->ValidUntilDate;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @return int[]
*/
public function getDiscountIds()
{
return $this->discountIds;
}
/**
* Get all discounts associated with this CouponCode
*
* @return QUI\ERP\Discount\Discount[]
*/
public function getDiscounts()
{
$discounts = [];
$DiscountHandler = DiscountHandler::getInstance();
foreach ($this->discountIds as $discountId) {
try {
$discounts[] = $DiscountHandler->getChild($discountId);
} catch (\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
}
return $discounts;
}
* Redeems this CouponCode
*
* Hint: This may invalidate the code for future use
*
* @param QUI\Users\User $User - The user that redeems the CouponCode [if omitted use Session User]
* @param QUI\ERP\Order\Order $Order (optional) - Link redemption to a specific Order
public function redeem($User = null, $Order = null)
$User = QUI::getUserBySession();
}
$this->checkRedemption($User);
$Now = new \DateTime();
$usage = [
'userId' => $User->getId(),
'date' => $Now->format('Y-m-d H:i:s'),
'orderPrefixedId' => false
if (!\is_null($Order) && $Order instanceof QUI\ERP\Order\Order) {
$usage['orderPrefixedId'] = $Order->getPrefixedId();
}
$this->usages[] = $usage;
['usages' => \json_encode($this->usages)],
['id' => $this->id]
QUI::getEvents()->fireEvent(
'quiqqerCouponsRedeem',
[
'User' => $User,
'CouponCode' => $this
]
);
* @param QUI\Interfaces\Users\User $User - If omitted, use session user
* @throws CouponCodeException - Thrown if not redeemable by the given User
public function checkRedemption($User)
if (!$this->isValid()) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.no_longer_valid'
]);
}
$DiscountHandler = DiscountHandler::getInstance();
$discountsValid = false;
$discountError = false;
foreach ($this->discountIds as $discountId) {
try {
/** @var QUI\ERP\Discount\Discount $Discount */
$Discount = $DiscountHandler->getChild($discountId);
} catch (\Exception $Exception) {
$discountError = $Exception->getMessage();
continue;
}
if ($Discount->canUsedBy($User)) {
$discountsValid = true;
break;
}
}
if (!$discountsValid) {
if (\count($this->discountIds) === 1) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.discount_invalid',
[
'reason' => $discountError
]
]);
} else {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.discounts_invalid'
]);
}
}
// Max usage restrictions
switch ($this->maxUsages) {
case Handler::MAX_USAGE_ONCE_PER_USER:
if ($this->hasUserRedeemed($User)) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.already_used'
]);
}
break;
case Handler::MAX_USAGE_ONCE:
if (!empty($this->usages)) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.already_used'
]);
}
break;
}
// Restriction to QUIQQER user(s)
if (\in_array($User->getId(), $this->userIds)) {
if ($this->maxUsages !== Handler::MAX_USAGE_UNLIMITED
&& $this->hasUserRedeemed($User)) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.already_used'
]);
}
} else {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.user_not_allowed'
]);
}
// Restriction to QUIQQER group(s)
foreach ($this->groupIds as $groupId) {
if ($User->isInGroup($groupId)) {
$userInGroup = true;
break;
}
}
if ($this->maxUsages !== Handler::MAX_USAGE_UNLIMITED
&& $this->hasUserRedeemed($User)) {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.already_used'
]);
}
} else {
throw new CouponCodeException([
'quiqqer/coupons',
'exception.CouponCode.user_not_allowed_group'
]);
}
}
* @param QUI\Users\User $User - If omitted, use session user
try {
$this->checkRedemption($User);
} catch (CouponCodeException $Exception) {
return false;
}
return true;
foreach ($this->usages as $usage) {
if ($usage['userId'] === $userId) {
return true;
}
*/
public function delete()
{
Permission::checkPermission(Handler::PERMISSION_DELETE);
QUI::getDataBase()->delete(
Handler::getTable(),
*
* @return array
*/
public function toArray()
{
'userIds' => $this->userIds,
'groupIds' => $this->groupIds,
'createDate' => $this->getCreateDate()->format('Y-m-d H:i:s'),
'validUntilDate' => false,
'title' => $this->getTitle() ?: false,
$data['validUntilDate'] = $ValidUntilDate->format('Y-m-d');
/**
* Checks if this CouponCode is still valid
*
* @return void
*/
protected function checkValidity()
{
// Check if the expiration date has been reached
if (!empty($this->ValidUntilDate)) {
$Now = new \DateTime();
if ($Now > $this->ValidUntilDate) {
$this->valid = false;
if ($this->maxUsages === Handler::MAX_USAGE_UNLIMITED) {
return;
}
if ($this->maxUsages === Handler::MAX_USAGE_ONCE && !empty($this->usages)) {
$this->valid = false;
// If the CouponCode is restricted to certain users -> Check if all those
// users have already redeemed the code
if (!empty($this->userIds)) {
$usedByAllUsers = true;
foreach ($this->userIds as $userId) {
foreach ($this->usages as $usage) {
if ($userId == $usage['userId']) {
continue 2;
}
}
$usedByAllUsers = false;
break;
}
if ($usedByAllUsers) {
$this->valid = false;
}
}
/**
* @param QUI\ERP\Order\OrderInProcess $Order
* @throws QUI\Exception
*/
public function addToOrder(QUI\ERP\Order\OrderInProcess $Order)
{
$coupons = $Order->getDataEntry('quiqqer-coupons');
if (!$coupons) {
return;
}
$calculations = $Order->getArticles()->getCalculations();
$vatArray = $calculations['vatArray'];
$vat = false;
if (\count($vatArray) === 1) {
$vat = \array_key_first($vatArray);
}
foreach ($coupons as $coupon) {
/* @var $Coupon CouponCode */
try {
$Coupon = Handler::getCouponCodeByCode($coupon);
} catch (\Exception $Exception) {
continue;
}
// coupon check
if (!$Coupon->isRedeemable($Order->getCustomer())) {
continue;
}
/* @var $Discount QUI\ERP\Discount\Discount */
$discounts = $Coupon->getDiscounts();
foreach ($discounts as $Discount) {
$PriceFactor = $Discount->toPriceFactor(null, $Order->getCustomer());
if ($vat !== false) {
$PriceFactor->setVat($vat);
}
$PriceFactor->setTitle(
QUI::getLocale()->get('quiqqer/coupons', 'coupon.discount.title', [
'code' => $Coupon->getCode()
])
);
$priceFactors[] = $PriceFactor;
// @todo wenn fest preis (zb 10$), dann eigener produkt typ hinzufügen
$articles[] = new QUI\ERP\Accounting\Invoice\Articles\Text([
'id' => '-',
'articleNo' => $Coupon->getCode(),
'title' => $PriceFactor->getTitle(),
'description' => '',
'unitPrice' => 0,
'control' => '',
'quantity' => 1,
'customData' => [
'package' => 'quiqqer/coupon',
'code' => $Coupon->getCode()
]
]);
/**
* @param QUI\ERP\Accounting\Invoice\Articles\Text $Article
* @return boolean
*/
$isInArticles = function ($Article) use ($Order) {
$articles = $Order->getArticles();
$code = $Article->getCustomData()['code'];
foreach ($articles as $Entry) {
if (!\method_exists($Entry, 'getCustomData')) {
continue;
}
$customData = $Entry->getCustomData();
if (!$customData || !\is_array($customData)) {
continue;
}
if (!isset($customData['package']) || !isset($customData['code'])) {
continue;
}
return $customData['package'] === 'quiqqer/coupon'
&& $customData['code'] === $code;
}
return false;
};
foreach ($articles as $Article) {
/* @var $PriceFactor QUI\ERP\Accounting\Invoice\Articles\Text */
if ($isInArticles($Article) === false) {
$Order->addArticle($Article);
}
}
$Order->update();
$Order->addPriceFactors($priceFactors);