use yii\data\ActiveDataProvider;
use yii\web\Controller;
use yii_app\records\Promocode;
+use yii_app\services\PromocodeService;
class PromocodeController extends Controller
{
public function actionIndex() {
- $dataProvider = new ActiveDataProvider(['query' => Promocode::find()->orderBy(['created_at' => SORT_DESC])]);
+ $dataProvider = new ActiveDataProvider(['query' => Promocode::find()->where(['parent_id' => null])->orderBy(['created_at' => SORT_DESC])]);
return $this->render('index', compact('dataProvider'));
}
public function actionEdit($id = null) {
+ $dataProvider = null;
if (!$id) {
$model = new Promocode;
$model->date_start = date("Y-m-d 00:00:00");
$model->date_end = date("Y-m-d 00:00:00", strtotime("+366 day", time()));
} else {
$model = Promocode::findOne($id);
+ $dataProvider = new ActiveDataProvider(['query' => Promocode::find()->where(['base' => Promocode::BASE_SINGLE_USE, 'parent_id' => $id])]);
}
+ /** @var $model Promocode */
if (Yii::$app->request->isPost && $model->load(Yii::$app->request->post())) {
if (!$model->created_by) {
$model->created_by = Yii::$app->user->id;
$model->updated_at = date("Y-m-d H:i:s");
}
if ($model->validate()) {
+ $model->code = mb_strtoupper($model->code, 'UTF-8');
$model->save();
+ if (!empty($model->generatePromocodeCount) && $model->active == Promocode::ACTIVE_ON) {
+ PromocodeService::generateSingleUsePromocodes($model);
+ $model->base = Promocode::BASE_BASE;
+ $model->save();
+ }
return $this->redirect('/promocode/index');
} else {
var_dump($model->getErrors());
}
}
- return $this->render('edit', compact('model'));
+ return $this->render('edit', compact('model', 'dataProvider'));
}
}
\ No newline at end of file
'id' => $this->primaryKey(),
'code' => $this->string(13)->notNull()->comment("Промокод"),
'bonus' => $this->integer()->notNull()->comment('Количество бонусов получаемых по промокоду'),
+ 'duration' => $this->integer()->notNull()->comment('Продолжительность действия бонуса'),
'active' => $this->tinyInteger()->notNull()->defaultValue(0)->comment('0 - не активный, 1 - активный'),
+ 'base' => $this->tinyInteger()->notNull()->defaultValue(0)->comment('0 - многоразовый промокод, 1 - база для одноразовых, 2 - одноразовый промокод'),
+ 'parent_id' => $this->integer()->null()->comment('ID промокода базы'),
'date_start' => $this->timestamp()->notNull()->comment('Дата начала действия промокода'),
'date_end' => $this->timestamp()->notNull()->comment('Дата окончания действия промокода'),
'created_by' => $this->integer()->notNull()->comment('ID создателя записи'),
* @property int $id
* @property string $code Промокод
* @property int $bonus Количество бонусов получаемых по промокоду
+ * @property int $duration Продолжительность действия бонуса
* @property int $active 0 - не активный, 1 - активный
+ * @property int $base 0 - многоразовый промокод, 1 - база для одноразовых, 2 - одноразовый промокод
+ * @property int|null $parent_id ID промокода базы
* @property string $date_start Дата начала действия промокода
* @property string $date_end Дата окончания действия промокода
* @property int $created_by ID создателя записи
*/
class Promocode extends \yii\db\ActiveRecord
{
+ const ACTIVE_ON = 1;
+ const ACTIVE_OFF = 0;
+ const BASE_SHARED = 0;
+ const BASE_BASE = 1;
+ const BASE_SINGLE_USE = 2;
+
+ public $generatePromocodeCount;
+
public static function tableName() { return 'promocode'; }
public function rules() {
return [
- [['code', 'bonus', 'active', 'date_start', 'date_end', 'created_by', 'created_at'], 'required'],
+ [['code', 'bonus', 'duration', 'active', 'date_start', 'date_end', 'created_by', 'created_at'], 'required'],
[['code'], 'string', 'max' => 13],
- [['bonus', 'active', 'created_by', 'updated_by'], 'integer'],
+ [['bonus', 'duration', 'active', 'base', 'parent_id', 'created_by', 'updated_by'], 'integer'],
[['date_start', 'date_end', 'created_at', 'updated_at'], 'datetime', 'format' => 'php:Y-m-d H:i:s'],
- [['updated_by', 'updated_at'], 'safe'],
+ [['updated_by', 'updated_at', 'generatePromocodeCount'], 'safe'],
];
}
'id' => 'ID',
'code' => 'Code',
'bonus' => 'Bonus',
+ 'duration' => 'Duration',
'active' => 'Active',
+ 'base' => 'Base',
+ 'parent_id' => 'Parent ID',
'date_start' => 'Date Start',
'date_end' => 'Date End',
'created_by' => 'Created By',
public function getUpdatedBy() {
return $this->hasOne(Admin::class, ['id' => 'updated_by']);
}
+
+ public function getParent() {
+ return $this->hasOne(Promocode::class, ['id' => 'parent_id']);
+ }
}
--- /dev/null
+<?php
+
+namespace yii_app\services;
+
+use Yii;
+use yii_app\records\Promocode;
+
+class PromocodeService
+{
+ private static function generateTwoChars() {
+ $chars = "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";
+ return mb_substr($chars, rand() % mb_strlen($chars), 1) .
+ mb_substr($chars, rand() % mb_strlen($chars), 1);
+ }
+
+ public static function generateSingleUsePromocodes(Promocode $basePromocode) {
+ foreach (range(1, $basePromocode->generatePromocodeCount) as $num) {
+ $word = self::generateTwoChars();
+ while (Promocode::find()->where(['code' => $basePromocode->code . $word])->one()) {
+ $word = self::generateTwoChars();
+ }
+ $singleUsePromocode = new Promocode;
+ $singleUsePromocode->code = mb_strtoupper($basePromocode->code . $word, 'UTF-8');
+ $singleUsePromocode->bonus = $basePromocode->bonus;
+ $singleUsePromocode->duration = $basePromocode->duration;
+ $singleUsePromocode->active = $basePromocode->active;
+ $singleUsePromocode->base = Promocode::BASE_SINGLE_USE;
+ $singleUsePromocode->parent_id = $basePromocode->id;
+ $singleUsePromocode->date_start = $basePromocode->date_start;
+ $singleUsePromocode->date_end = $basePromocode->date_end;
+ $singleUsePromocode->date_start = $basePromocode->date_start;
+ $singleUsePromocode->created_by = Yii::$app->user->id;
+ $singleUsePromocode->created_at = date("Y-m-d H:i:s");
+ $singleUsePromocode->save();
+ if ($singleUsePromocode->getErrors()) {
+ var_dump($singleUsePromocode->getErrors());
+ }
+ }
+ }
+}
\ No newline at end of file
use dosamigos\datetimepicker\DateTimePicker;
+use yii\data\ActiveDataProvider;
+use yii\grid\GridView;
use \yii\helpers\Html;
use \yii\widgets\ActiveForm;
use \yii_app\records\Promocode;
use \yii_app\helpers\PrintBlockHelper;
/** @var $model Promocode */
+/** @var $dataProvider ActiveDataProvider */
?>
<?php PrintBlockHelper::printBlock('Бонус', $form->field($model, 'bonus')->textInput(['type' => 'number'])->label(false)) ?>
+ <?php PrintBlockHelper::printBlock('Продолжительность действия бонуса в днях', $form->field($model, 'duration')->textInput(['type' => 'number'])->label(false)) ?>
+
<?php PrintBlockHelper::printBlock('Активность', $form->field($model, 'active')->dropDownList(['Не активен', 'Активен'])->label(false)) ?>
<?php PrintBlockHelper::printBlock('Дата начала действия промокода', $form->field($model, 'date_start')->widget(DateTimePicker::class, [
],
])->label(false)) ?>
+ <?php if ($model->base < 2): ?>
+ <?php PrintBlockHelper::printBlock('Количество дополнительных одноразовых промокодов', $form->field($model, 'generatePromocodeCount')->textInput(['type' => 'number'])->label(false)) ?>
+ <?php endif; ?>
+
<div class="form-group">
<?= Html::submitButton('Сохранить', ['class' => 'btn btn-success btn-lg'])?>
</div>
<?php ActiveForm::end() ?>
+ <?php if (isset($dataProvider) && $model->base == 1): ?>
+
+ <?= GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+ [
+ 'label' => 'Промокод',
+ 'format' => 'raw',
+ 'value' => function ($model) {
+ return Html::a($model->code, ['edit', 'id' => $model->id], ['class' => 'btn btn-link']);
+ }
+ ],
+ 'bonus',
+ [
+ 'label' => 'Время действия бонуса в днях',
+ 'value' => function ($model) {
+ return $model->duration;
+ }
+ ],
+ [
+ 'label' => 'Тип промокода',
+ 'value' => function ($model) {
+ return "Одноразовый";
+ }
+ ],
+ [
+ 'label' => 'Активен ли промокод',
+ 'value' => function ($model) {
+ return $model->active ? 'Да' : 'Нет';
+ }
+ ],
+ [
+ 'label' => 'Дата начала действия промокода',
+ 'value' => function ($model) {
+ return date("Y-m-d", strtotime($model->date_start));
+ }
+ ],
+ [
+ 'label' => 'Дата окончания действия промокода',
+ 'value' => function ($model) {
+ return date("Y-m-d", strtotime($model->date_end));
+ }
+ ],
+ [
+ 'label' => 'Создатель',
+ 'value' => function ($model) {
+ return $model->createdBy->name ?? '';
+ }
+ ],
+ [
+ 'label' => 'Обновил',
+ 'value' => function ($model) {
+ return $model->updatedBy->name ?? '';
+ }
+ ],
+ [
+ 'label' => 'Дата создания промокода',
+ 'value' => function ($model) {
+ return date("Y-m-d H:i:s", strtotime($model->created_at));
+ }
+ ],
+ [
+ 'label' => 'Дата обновления промокода',
+ 'value' => function ($model) {
+ return $model->updated_at ? date("Y-m-d H:i:s", strtotime($model->updated_at)) : '';
+ }
+ ],
+ ],
+ ]); ?>
+
+ <?php endif; ?>
+
</div>
\ No newline at end of file
}
],
'bonus',
+ [
+ 'label' => 'Время действия бонуса в днях',
+ 'value' => function ($model) {
+ return $model->duration;
+ }
+ ],
+ [
+ 'label' => 'Тип промокода',
+ 'value' => function ($model) {
+ return $model->base == 0 ? "Множественный" : "База для одноразовых";
+ }
+ ],
[
'label' => 'Активен ли промокод',
'value' => function ($model) {