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']);
}
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
177
}
/**
* @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'
]);
}
}
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
/**
* Check if the given Order can redeem this CouponCode
*
* @param OrderInterface|null $Order
* @throws CouponCodeException
*/
public function checkOrderRedemption($Order)
{
if ($Order === null) {
return;
}
$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->canUsedInOrder($Order)) {
$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'
]);
}
}
}
* @param QUI\Users\User $User - If omitted, use session user
public function isRedeemable($User = null, $Order = null)
try {
$this->checkRedemption($User);
} catch (CouponCodeException $Exception) {
return false;
}
if ($Order) {
try {
$this->checkOrderRedemption($Order);
} catch (CouponCodeException $Exception) {
$Order->addFrontendMessage($Exception->getMessage());
return false;
}
}
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(), $Order)) {
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\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\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);