From e17b4a89c60c08ff7070873b350534b60bacead3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20M=C3=BCller?= <p.mueller@pcsg.de> Date: Fri, 2 Nov 2018 11:21:08 +0100 Subject: [PATCH] fix: Restrictions to group (label) #5 refactor: reusable status changed to maxUsages with 3 different options --- bin/backend/controls/Manager.Create.html | 14 ++++--- bin/backend/controls/Manager.css | 3 +- bin/backend/controls/Manager.js | 35 +++++++---------- database.xml | 2 +- locale.xml | 36 ++++++++++++++--- src/QUI/ERP/Coupons/CouponCode.php | 49 +++++++++++++++++++----- src/QUI/ERP/Coupons/Handler.php | 27 +++++++++++-- 7 files changed, 118 insertions(+), 48 deletions(-) diff --git a/bin/backend/controls/Manager.Create.html b/bin/backend/controls/Manager.Create.html index 23c82ac..54ba00f 100644 --- a/bin/backend/controls/Manager.Create.html +++ b/bin/backend/controls/Manager.Create.html @@ -15,16 +15,20 @@ <input type="text" name="code"/> </label> <label> - <span>{{labelUsers}}</span> - <input type="hidden" name="userIds" data-qui="controls/users/Select"/> + <span>{{labelReusable}}</span> + <select name="maxUsages"> + <option value="oncePerUser" selected>{{labelReusableOncePerUser}}</option> + <option value="once">{{labelReusableOnce}}</option> + <option value="unlimited">{{labelReusableUnlimited}}</option> + </select> </label> <label> <span>{{labelUsers}}</span> - <input type="hidden" name="groupIds" data-qui="controls/groups/Select"/> + <input type="hidden" name="userIds" data-qui="controls/users/Select"/> </label> <label> - <span>{{labelReusable}}</span> - <input type="checkbox" name="reusable"/> + <span>{{labelGroups}}</span> + <input type="hidden" name="groupIds" data-qui="controls/groups/Select"/> </label> <label> <span>{{labelDate}}</span> diff --git a/bin/backend/controls/Manager.css b/bin/backend/controls/Manager.css index e085853..7399dd2 100644 --- a/bin/backend/controls/Manager.css +++ b/bin/backend/controls/Manager.css @@ -36,7 +36,8 @@ .quiqqer-coupons-manager-create input[type="text"], .quiqqer-coupons-manager-create input[type="number"], -.quiqqer-coupons-manager-create input[type="date"] { +.quiqqer-coupons-manager-create input[type="date"], +.quiqqer-coupons-manager-create select { width: 100%; } diff --git a/bin/backend/controls/Manager.js b/bin/backend/controls/Manager.js index 0ffa025..13d3c8c 100644 --- a/bin/backend/controls/Manager.js +++ b/bin/backend/controls/Manager.js @@ -183,8 +183,8 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [ width : 150 }, { header : QUILocale.get(lg, 'controls.manager.tbl.header.reusable'), - dataIndex: 'reusableStatus', - dataType : 'node', + dataIndex: 'maxUsageLabel', + dataType : 'string', width : 150 }, { header : QUILocale.get(lg, 'controls.manager.tbl.header.createDate'), @@ -319,17 +319,7 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [ Row.title = '-'; } - var ReusableElm = new Element('span', { - 'class': 'fa' - }); - - if (!Row.reusable) { - ReusableElm.addClass('fa-close'); - } else { - ReusableElm.addClass('fa-check'); - } - - Row.reusableStatus = ReusableElm; + Row.maxUsageLabel = QUILocale.get(lg, 'controls.manager.tbl.maxUsageLabel.' + Row.maxUsages); } this.$Grid.setData(GridData); @@ -472,14 +462,17 @@ define('package/quiqqer/coupons/bin/backend/controls/Manager', [ }, closeButton: true, content : Mustache.render(templateCreate, { - labelTitle : QUILocale.get(lg, lgPrefix + 'labelTitle'), - labelCode : QUILocale.get(lg, lgPrefix + 'labelCode'), - labelUsers : QUILocale.get(lg, lgPrefix + 'labelUsers'), - labelGroups : QUILocale.get(lg, lgPrefix + 'labelGroups'), - labelDate : QUILocale.get(lg, lgPrefix + 'labelDate'), - labelAmount : QUILocale.get(lg, lgPrefix + 'labelAmount'), - labelReusable: QUILocale.get(lg, lgPrefix + 'labelReusable'), - labelDiscount: QUILocale.get(lg, lgPrefix + 'labelDiscount') + labelTitle : QUILocale.get(lg, lgPrefix + 'labelTitle'), + labelCode : QUILocale.get(lg, lgPrefix + 'labelCode'), + labelUsers : QUILocale.get(lg, lgPrefix + 'labelUsers'), + labelGroups : QUILocale.get(lg, lgPrefix + 'labelGroups'), + labelDate : QUILocale.get(lg, lgPrefix + 'labelDate'), + labelAmount : QUILocale.get(lg, lgPrefix + 'labelAmount'), + labelReusable : QUILocale.get(lg, lgPrefix + 'labelReusable'), + labelReusableOncePerUser: QUILocale.get(lg, lgPrefix + 'labelReusableOncePerUser'), + labelReusableOnce : QUILocale.get(lg, lgPrefix + 'labelReusableOnce'), + labelReusableUnlimited : QUILocale.get(lg, lgPrefix + 'labelReusableUnlimited'), + labelDiscount : QUILocale.get(lg, lgPrefix + 'labelDiscount') }) }); diff --git a/database.xml b/database.xml index c2ca7ec..7d721f3 100644 --- a/database.xml +++ b/database.xml @@ -12,7 +12,7 @@ <field type="DATETIME NOT NULL">createDate</field> <field type="DATETIME NULL">validUntilDate</field> <field type="MEDIUMTEXT NULL">usages</field> - <field type="TINYINT(1) NOT NULL DEFAULT 0">isReusable</field> + <field type="VARCHAR(255) NOT NULL">maxUsages</field> </table> </global> diff --git a/locale.xml b/locale.xml index f55c3de..0cf4f9d 100644 --- a/locale.xml +++ b/locale.xml @@ -178,8 +178,8 @@ <en><![CDATA[Usage (optional)]]></en> </locale> <locale name="controls.manager.create.template.labelAmount"> - <de><![CDATA[Anzahl]]></de> - <en><![CDATA[Amount]]></en> + <de><![CDATA[Anzahl generierte Gutschein-Codes]]></de> + <en><![CDATA[Amount of generated coupon codes]]></en> </locale> <locale name="controls.manager.create.template.labelUsers"> <de><![CDATA[Auf folgende Benutzer beschränken (optional)]]></de> @@ -194,8 +194,20 @@ <en><![CDATA[Coupon code (optional - is generated automatically if left empty)]]></en> </locale> <locale name="controls.manager.create.template.labelReusable"> - <de><![CDATA[Wiederverwendbar (Gutschein-Code kann mehrfach verwendet werden)]]></de> - <en><![CDATA[Reusable (Coupon code can be used multiple times)]]></en> + <de><![CDATA[Erlaubte Verwendung]]></de> + <en><![CDATA[Permitted usage]]></en> + </locale> + <locale name="controls.manager.create.template.labelReusableOncePerUser"> + <de><![CDATA[Einmal pro Benutzer einlösbar]]></de> + <en><![CDATA[Redeemable once per user]]></en> + </locale> + <locale name="controls.manager.create.template.labelReusableOnce"> + <de><![CDATA[Insgesamt nur einmal einlösbar]]></de> + <en><![CDATA[Only redeemable once in total]]></en> + </locale> + <locale name="controls.manager.create.template.labelReusableUnlimited"> + <de><![CDATA[Unbegrenzt einlösbar]]></de> + <en><![CDATA[Unlimited redeemable]]></en> </locale> <locale name="controls.manager.create.template.labelDiscount"> <de><![CDATA[Verknüpfter Rabatt]]></de> @@ -274,8 +286,8 @@ <en><![CDATA[Usage]]></en> </locale> <locale name="controls.manager.tbl.header.reusable"> - <de><![CDATA[Mehrfach verwendbar]]></de> - <en><![CDATA[Reusable]]></en> + <de><![CDATA[Erlaubte Verwendung]]></de> + <en><![CDATA[Permitted usage]]></en> </locale> <locale name="controls.manager.tbl.status.unused"> <de><![CDATA[nicht eingelöst]]></de> @@ -297,6 +309,18 @@ <de><![CDATA[Benutzer existiert nicht mehr]]></de> <en><![CDATA[User does not exist anymore]]></en> </locale> + <locale name="controls.manager.tbl.maxUsageLabel.oncePerUser"> + <de><![CDATA[Einmal pro Benutzer]]></de> + <en><![CDATA[Once per user]]></en> + </locale> + <locale name="controls.manager.tbl.maxUsageLabel.once"> + <de><![CDATA[Einmal einlösbar]]></de> + <en><![CDATA[Redeemable once]]></en> + </locale> + <locale name="controls.manager.tbl.maxUsageLabel.unlimited"> + <de><![CDATA[Unbegrenzt]]></de> + <en><![CDATA[Unlimited]]></en> + </locale> <locale name="controls.manager.delete.popup.info"> <de> <![CDATA[Sind Sie sicher, dass Sie die folgenden Gutschein-Codes unwiderruflich löschen wollen?<br><br>[codes]]]></de> diff --git a/src/QUI/ERP/Coupons/CouponCode.php b/src/QUI/ERP/Coupons/CouponCode.php index aec25c2..2cd5030 100644 --- a/src/QUI/ERP/Coupons/CouponCode.php +++ b/src/QUI/ERP/Coupons/CouponCode.php @@ -82,11 +82,11 @@ class CouponCode protected $valid = true; /** - * Flag - Is the CouponCode reusable? + * Max usages * - * @var bool + * @var string */ - protected $reusable; + protected $maxUsages = Handler::MAX_USAGE_ONCE_PER_USER; /** * CouponCode constructor. @@ -131,8 +131,8 @@ public function __construct($id) $this->groupIds = json_decode($data['groupIds'], true); } - if (!empty($data['isReusable'])) { - $this->reusable = true; + if (!empty($data['maxUsages'])) { + $this->maxUsages = $data['maxUsages']; } if (!empty($data['discountIds'])) { @@ -333,9 +333,32 @@ public function checkRedemption($User) } } + // 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 (!empty($this->userIds)) { if (in_array($User->getId(), $this->userIds)) { - if (!$this->reusable && $this->hasUserRedeemed($User)) { + if ($this->maxUsages !== Handler::MAX_USAGE_UNLIMITED + && $this->hasUserRedeemed($User)) { throw new CouponCodeException([ 'quiqqer/coupons', 'exception.CouponCode.already_used' @@ -349,6 +372,7 @@ public function checkRedemption($User) } } + // Restriction to QUIQQER group(s) if (!empty($this->groupIds)) { $userInGroup = false; @@ -360,7 +384,8 @@ public function checkRedemption($User) } if ($userInGroup) { - if (!$this->reusable && $this->hasUserRedeemed($User)) { + if ($this->maxUsages !== Handler::MAX_USAGE_UNLIMITED + && $this->hasUserRedeemed($User)) { throw new CouponCodeException([ 'quiqqer/coupons', 'exception.CouponCode.already_used' @@ -456,7 +481,7 @@ public function toArray() 'validUntilDate' => false, 'title' => $this->getTitle() ?: false, 'isValid' => $this->isValid(), - 'reusable' => $this->reusable, + 'maxUsages' => $this->maxUsages, 'discountIds' => $this->discountIds ]; @@ -482,12 +507,16 @@ protected function checkValidity() if ($Now > $this->ValidUntilDate) { $this->valid = false; - return; } } - if ($this->reusable) { + if ($this->maxUsages === Handler::MAX_USAGE_UNLIMITED) { + return; + } + + if ($this->maxUsages === Handler::MAX_USAGE_ONCE && !empty($this->usages)) { + $this->valid = false; return; } diff --git a/src/QUI/ERP/Coupons/Handler.php b/src/QUI/ERP/Coupons/Handler.php index 621dfc4..b8ab7a4 100644 --- a/src/QUI/ERP/Coupons/Handler.php +++ b/src/QUI/ERP/Coupons/Handler.php @@ -17,11 +17,18 @@ class Handler /** * Permissions */ - const PERMISSION_VIEW = 'quiqqer.couponcode.view'; + const PERMISSION_VIEW = 'quiqqer.couponcode.view'; const PERMISSION_CREATE = 'quiqqer.couponcode.create'; - const PERMISSION_EDIT = 'quiqqer.couponcode.edit'; + const PERMISSION_EDIT = 'quiqqer.couponcode.edit'; const PERMISSION_DELETE = 'quiqqer.couponcode.delete'; + /** + * Valur for `maxUsage` + */ + const MAX_USAGE_ONCE_PER_USER = 'oncePerUser'; + const MAX_USAGE_ONCE = 'once'; + const MAX_USAGE_UNLIMITED = 'unlimited'; + /** * CouponCode runtime cache * @@ -135,11 +142,17 @@ public static function createCouponCode($discountIds, $settings = []) $code = CodeGenerator::generate(); } + if (empty($settings['maxUsages'])) { + $maxUsages = self::MAX_USAGE_ONCE_PER_USER; + } else { + $maxUsages = $settings['maxUsages']; + } + $couponCode = [ 'title' => empty($settings['title']) ? null : $settings['title'], 'createDate' => $Now->format('Y-m-d H:i:s'), 'code' => $code, - 'isReusable' => empty($settings['reusable']) ? 0 : 1, + 'maxUsages' => $maxUsages, 'discountIds' => json_encode($discountIds) ]; @@ -226,11 +239,17 @@ public static function editCouponCode($id, $discountIds, $settings = []) $code = CodeGenerator::generate(); } + if (empty($settings['maxUsages'])) { + $maxUsages = self::MAX_USAGE_ONCE_PER_USER; + } else { + $maxUsages = $settings['maxUsages']; + } + $couponCode = [ 'title' => empty($settings['title']) ? null : $settings['title'], 'createDate' => $Now->format('Y-m-d H:i:s'), 'code' => $code, - 'isReusable' => !empty($settings['reusable']) ? 1 : 0, + 'maxUsages' => $maxUsages, 'discountIds' => json_encode($discountIds) ]; -- GitLab