diff --git a/.gitignore b/.gitignore index 346d3b2..e587688 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ composer.phar phpunit.phar # local phpunit config /phpunit.xml + +/node_modules diff --git a/backend/controllers/TicketController.php b/backend/controllers/TicketController.php index a036d8f..39b2f67 100644 --- a/backend/controllers/TicketController.php +++ b/backend/controllers/TicketController.php @@ -8,6 +8,9 @@ use backend\models\TicketSearch; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; +use common\models\Discount; +use common\models\TicketType; +use common\models\Account; /** * TicketController implements the CRUD actions for Ticket model. @@ -61,12 +64,20 @@ class TicketController extends Controller public function actionCreate() { $model = new Ticket(); + + $discounts = Discount::read(); + $ticketTypes = TicketType::read(); + $accounts = Account::readAccounts(); + if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id_ticket]); } else { return $this->render('create', [ 'model' => $model, + 'discounts' => $discounts, + 'ticketTypes' => $ticketTypes, + 'accounts' => $accounts, ]); } } diff --git a/common/assets/MomentAsset.php b/common/assets/MomentAsset.php new file mode 100644 index 0000000..f599a17 --- /dev/null +++ b/common/assets/MomentAsset.php @@ -0,0 +1,16 @@ +andWhere(['status' => self::STATUS_ACTIVE])->all(); + }else{ + $ticketTypes = TicketType::find()->andWhere( ['or', ['status' => self::STATUS_ACTIVE], ['id_ticket_type' => $forceIncludeObjectWithId ] ])->all(); + } + + return $ticketTypes; + } + + + public static function modelsToArray($models,$default = []){ + + if ( $models == null ){ + return $default; + } + + return ArrayHelper::toArray($models, [ + 'common\models\TicketType' => [ + 'name', + 'id_ticket_type', + 'max_usage_count', + 'time_unit_type', + 'time_unit_count', + 'id_account', + 'price_brutto', + ], + ]); + } + + } diff --git a/composer.json b/composer.json index 1bb2607..411126e 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "kartik-v/yii2-widgets": "^3.4", "kartik-v/yii2-widget-typeahead": "*", "bower-asset/remarkable-bootstrap-notify": "^3.1", - "yiisoft/yii2-jui": "^2.0" + "yiisoft/yii2-jui": "^2.0", + "bower-asset/moment": "^2.10" }, "require-dev": { "yiisoft/yii2-codeception": "*", diff --git a/composer.lock b/composer.lock index 4925c02..745d589 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7bff75eba2c88cda67ff49b95bda9644", + "hash": "ade53c29b13f5eaa8367e21defe51905", "packages": [ { "name": "bower-asset/bootstrap", @@ -176,6 +176,43 @@ "plugins" ] }, + { + "name": "bower-asset/moment", + "version": "2.10.6", + "source": { + "type": "git", + "url": "https://github.com/moment/moment.git", + "reference": "f3fbef9d9875bbff340b527dbe3f1c447a942f69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/moment/moment/zipball/f3fbef9d9875bbff340b527dbe3f1c447a942f69", + "reference": "f3fbef9d9875bbff340b527dbe3f1c447a942f69", + "shasum": "" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": "moment.js", + "bower-asset-ignore": [ + "**/.*", + "benchmarks", + "bower_components", + "meteor", + "node_modules", + "scripts", + "tasks", + "test", + "component.json", + "composer.json", + "CONTRIBUTING.md", + "ender.js", + "Gruntfile.js", + "Moment.js.nuspec", + "package.js", + "package.json" + ] + } + }, { "name": "bower-asset/punycode", "version": "v1.3.2", diff --git a/console/migrations/m151008_065256_alter__table__ticket__add_columns.php b/console/migrations/m151008_065256_alter__table__ticket__add_columns.php new file mode 100644 index 0000000..9e9c763 --- /dev/null +++ b/console/migrations/m151008_065256_alter__table__ticket__add_columns.php @@ -0,0 +1,30 @@ + + * @since 2.0 + */ +class TicketSellAsset extends AssetBundle +{ + public $basePath = '@webroot'; + public $baseUrl = '@web'; + public $css = [ + ]; + public $js = [ + 'js/transferlist.js', + 'js/ticket.sell.js', + ]; + public $depends = [ + 'frontend\assets\AppAsset', + 'common\assets\MomentAsset', + 'yii\jui\JuiAsset', + ]; +} diff --git a/frontend/components/HtmlHelper.php b/frontend/components/HtmlHelper.php new file mode 100644 index 0000000..095e528 --- /dev/null +++ b/frontend/components/HtmlHelper.php @@ -0,0 +1,43 @@ +number = $number; + + $receptionForm->readCard(); + + $model = new TicketCreate(); + $discounts = Discount::read(); + + $ticketTypes = TicketType::read(); + + $accounts = Account::readAccounts(); + + $user = User::findOne( [ 'id' => Yii::$app->user->id ] ); + + + $model->id_user = \Yii::$app->user->id; + $model->status = Ticket::STATUS_ACTIVE; + $model->usage_count = 0; + if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id_ticket]); } else { + + $userTransfers = Transfer::modelsToArray( Transfer::readUserSoldTransfers($user) ); + return $this->render('create', [ 'model' => $model, + 'discounts' => $discounts, + 'ticketTypes' => $ticketTypes, + 'accounts' => $accounts, + 'receptionForm' => $receptionForm, + 'userTransfers' => $userTransfers, ]); } } diff --git a/frontend/models/TicketCreate.php b/frontend/models/TicketCreate.php new file mode 100644 index 0000000..a10653d --- /dev/null +++ b/frontend/models/TicketCreate.php @@ -0,0 +1,76 @@ + 255] + ]; + } + + + public function validateTicketType($attribute,$params){ + $type = TicketType::findOne($this->id_ticket_type); + if ( !isset($type)) { + $this->addError($attribute,Yii::t('frontend/ticket' , 'Invalid ticket type' )); + } + } + public function validateAccount($attribute,$params){ + $acc = Account::findOne($this->id_account); + if ( !isset($acc)) { + $this->addError($attribute,Yii::t('frontend/ticket' , 'Invalid transfer' )); + } + } + public function validateDiscount($attribute,$params){ + $discount = Discount::findOne($this->id_discount); + if ( !isset($discount)) { + $this->addError($attribute,Yii::t('frontend/ticket' , 'Invalid discount' )); + } + } + + +} \ No newline at end of file diff --git a/frontend/views/common/_menu_reception.php b/frontend/views/common/_menu_reception.php index 40e1037..a52796e 100644 --- a/frontend/views/common/_menu_reception.php +++ b/frontend/views/common/_menu_reception.php @@ -66,7 +66,7 @@ function mkBtn($card, $label,$route = null ){
- 'glyphicon glyphicon-plus' ] ) , 'ticket/create' , ['class' => 'btn btn-primary btn-reception'] )?> + 'glyphicon glyphicon-plus' ] ) , Url::toRoute('ticket/create') , ['class' => 'btn btn-primary btn-reception'] ) ?>
diff --git a/frontend/views/common/_transfer_list.php b/frontend/views/common/_transfer_list.php new file mode 100644 index 0000000..98b4aea --- /dev/null +++ b/frontend/views/common/_transfer_list.php @@ -0,0 +1,9 @@ + +
+
+
+
+
+
diff --git a/frontend/views/customer/create.php b/frontend/views/customer/create.php index 9bc033f..360d9dc 100644 --- a/frontend/views/customer/create.php +++ b/frontend/views/customer/create.php @@ -8,6 +8,8 @@ use frontend\components\ReceptionCardNumberWidget; /* @var $this yii\web\View */ /* @var $model common\models\Customer */ + + $this->title = Yii::t('common/customer', 'Create Customer'); $this->params['breadcrumbs'][] = ['label' => Yii::t('common/customer', 'Customers'), 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; @@ -16,6 +18,9 @@ $this->params['breadcrumbs'][] = $this->title; $customer = $model; $card = $customer->card; + + + ?>
diff --git a/frontend/views/ticket/_form.php b/frontend/views/ticket/_form.php index d984294..f1aeabf 100644 --- a/frontend/views/ticket/_form.php +++ b/frontend/views/ticket/_form.php @@ -2,46 +2,68 @@ use yii\helpers\Html; use yii\widgets\ActiveForm; +use frontend\components\HtmlHelper; +use kartik\widgets\DatePicker; /* @var $this yii\web\View */ /* @var $model common\models\Ticket */ +/* @var $accounts common\models\Account[] */ +/* @var $ticketTypes common\models\TicketType[] */ +/* @var $discounts common\models\Discount[] */ /* @var $form yii\widgets\ActiveForm */ ?> -
+ + $accountOptions = HtmlHelper::mkAccountOptions($accounts); + $discountOptions = HtmlHelper::mkDiscountOptions($discounts); + $ticketTypeOptions = HtmlHelper::mkTicketTypeOptions($ticketTypes); + + + + +?> - field($model, 'id_user')->textInput() ?> - - field($model, 'id_ticket_type')->textInput() ?> - - field($model, 'id_account')->textInput() ?> - - field($model, 'id_discount')->textInput() ?> - - field($model, 'start')->textInput() ?> - - field($model, 'end')->textInput() ?> - - field($model, 'max_usage_count')->textInput() ?> - - field($model, 'usage_count')->textInput() ?> - - field($model, 'status')->textInput() ?> - - field($model, 'price_brutto')->textInput() ?> - - field($model, 'comment')->textInput(['maxlength' => true]) ?> - - field($model, 'created_at')->textInput() ?> - - field($model, 'updated_at')->textInput() ?> - -
- isNewRecord ? Yii::t('common/ticket', 'Create') : Yii::t('common/ticket', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> -
- - - -
+
+
+
+ + + + field($model, 'id_ticket_type')->dropDownList($ticketTypeOptions) ?> + + field($model, 'id_account')->dropDownList($accountOptions) ?> + + field($model, 'id_discount')->dropDownList($discountOptions) ?> + + + field($model, 'start')->widget(DatePicker::classname(), [ + 'pluginOptions' => [ + 'autoclose'=>true, + 'format' => 'yyyy.mm.dd' + ] + ]) ?> + + + field($model, 'end')->widget(DatePicker::classname(), [ + 'pluginOptions' => [ + 'autoclose'=>true, + 'format' => 'yyyy.mm.dd' + ] + ]) ?> + + field($model, 'max_usage_count')->input('number') ?> + + field($model, 'price_brutto')->input('number') ?> + + field($model, 'comment')->textarea(['maxlength' => true]) ?> + +
+ isNewRecord ? Yii::t('common/ticket', 'Create') : Yii::t('common/ticket', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> +
+ + + +
+
+
\ No newline at end of file diff --git a/frontend/views/ticket/create.php b/frontend/views/ticket/create.php index 67727e3..56d435d 100644 --- a/frontend/views/ticket/create.php +++ b/frontend/views/ticket/create.php @@ -1,21 +1,63 @@ title = Yii::t('common/ticket', 'Create Ticket'); $this->params['breadcrumbs'][] = ['label' => Yii::t('common/ticket', 'Tickets'), 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; + +$card = $receptionForm->card; +$customer = $receptionForm->customer; + +$options = []; + +// $options['lookup_product_url'] = Url::toRoute(['product/lookup']); +// $options['clear_list_url'] = Url::toRoute(['product/clear-list']); +$options['types'] = TicketType::modelsToArray($ticketTypes); +$options['transfer_list'] = $userTransfers; + +$this->registerJs ( 'new TicketSell( '. json_encode($options).');' ); + ?>
-

title) ?>

+
+
+ $customer, 'card' => $card] ) ?> +
+
+ $customer, 'card' =>$card, 'route' => ['customer/reception'] ] )?> +
+
+
+
- render('_form', [ - 'model' => $model, - ]) ?> + +
+
+

title) ?>

+ render('_form', [ + 'model' => $model, + 'discounts' => $discounts, + 'ticketTypes' => $ticketTypes, + 'accounts' => $accounts, + ]) ?> +
+
+

+ render( "//common/_transfer_list" ) ?> +
+
diff --git a/frontend/web/js/frontend.js b/frontend/web/js/frontend.js new file mode 100644 index 0000000..65ee634 --- /dev/null +++ b/frontend/web/js/frontend.js @@ -0,0 +1,17 @@ +(function() { + var KeypressListener; + + KeypressListener = (function() { + function KeypressListener(name) { + this.name = name; + } + + KeypressListener.prototype.listen = function() {}; + + return KeypressListener; + + })(); + +}).call(this); + +//# sourceMappingURL=frontend.js.map diff --git a/frontend/web/js/frontend.js.map b/frontend/web/js/frontend.js.map new file mode 100644 index 0000000..083bfa7 --- /dev/null +++ b/frontend/web/js/frontend.js.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "file": "frontend.js", + "sourceRoot": "../coffee/", + "sources": [ + "keypresslistener.coffee" + ], + "names": [], + "mappings": "AAAA;AAAA,MAAA;;EAAM;IAEQ,0BAAC,IAAD;MAAC,IAAC,CAAA,OAAD;IAAD;;+BAEb,MAAA,GAAQ,SAAA,GAAA;;;;;AAJT" +} \ No newline at end of file diff --git a/frontend/web/js/ticket.sell.js b/frontend/web/js/ticket.sell.js new file mode 100644 index 0000000..0bc6cfa --- /dev/null +++ b/frontend/web/js/ticket.sell.js @@ -0,0 +1,154 @@ +function TicketSell(o){ + + /**reference for the instance*/ + var app = this; + + this.defaults = { + default_type: 0, + selected_type: 1, + time_unit_day : 10, + time_unit_month : 20, + time_unit_month_reference : 30, + /**id of filter text*/ + types: [{ + name :'Bérlet', + id_ticket_type: 0, + max_usage_count:0, + time_unit_type:1, + time_unit_count:1, + id_account:0, + price_brutto:1000, + }, + ], + selector_type: '#ticketcreate-id_ticket_type', + selector_start: '#ticketcreate-start', + selector_end: '#ticketcreate-end', + selector_account: '#ticketcreate-id_account', + selector_price: '#ticketcreate-price_brutto', + selector_max_usage_count: '#ticketcreate-max_usage_count', + date_format_moment: 'YYYY.MM.DD', + ticket_type: null, + start_date: null, + end_date: null, + max_usage_count: null, + id_account: null, + price: null, + clear_list_url: '', + transfer_list: [] + }; + + init(); + + function init(){ + $.extend(app.defaults, o ); + addBehaviourTypeChangedListener(); + useDefaults(); + createUserSoldItemsTable(); + } + + function useDefaults(){ + if ( app.defaults.selected_type > 0){ + $(app.defaults.selector_type).val( app.defaults.selected_type ); + typeChanged(); + } + } + + function createUserSoldItemsTable(){ + $('.transfer-list-container').transferList({ + 'transfers' : app.defaults.transfer_list + }); + } + + function refreshSoldUseritems(){ + $('.transfer-list-container').transferList('option','transfers' , app.defaults.sold_items ); + } + + function addBehaviourTypeChangedListener(){ + $(app.defaults.selector_type).change(change); + } + + function change(event){ + if ( '#'+event.target.id == app.defaults.selector_type ){ + typeChanged(); + } + } + + function typeChanged(){ + validateTypeChanged(); + refresh(); + } + + function validateTypeChanged(){ + validateType(); + validateStartDate(); + validateEndDate(); + validateMaxUsageCount(); + validatePriceBrutto(); + validateAccount(); + } + + function validateType(){ + var type; + type = +$(app.defaults.selector_type).val(); + app.defaults.ticket_type = null; + for ( var i = 0; i < app.defaults.types.length; i++ ){ + if ( app.defaults.types[i].id_ticket_type == type){ + app.defaults.ticket_type = app.defaults.types[i]; + break; + } + + } + } + + function validateStartDate(){ + app.defaults.start_date = moment( $( app.defaults.selector_start ).val(), app.defaults.date_format_moment) ; + + if ( !app.defaults.start_date.isValid() ){ + app.defaults.start_date = moment(); + } + + } + + function validateEndDate(){ + var units; + units = app.defaults.ticket_type.time_unit_count; + app.defaults.end_date = moment(app.defaults.start_date); + switch(app.defaults.ticket_type.time_unit_type){ + case app.defaults.time_unit_day: + app.defaults.end_date.add( units, 'days'); + app.defaults.end_date.subtract( 1, 'days'); + break; + case app.defaults.time_unit_month: + app.defaults.end_date.add( units, 'month'); + app.defaults.end_date.subtract( 1, 'days'); + break; + case app.defaults.time_unit_month_reference: + if ( units > 1){ + app.defaults.end_date.add( units -1, 'month'); + } + app.defaults.end_date.endOf('month'); + break; + } + } + + function validateMaxUsageCount(){ + app.defaults.max_usage_count = app.defaults.ticket_type.max_usage_count; + } + + function validatePriceBrutto(){ + app.defaults.price = app.defaults.ticket_type.price_brutto; + } + function validateAccount(){ + app.defaults.id_account = app.defaults.ticket_type.id_account; + } + + function refresh(){ + console.info( app.defaults.start_date.toDate()); + $(app.defaults.selector_start ).val( app.defaults.start_date.format( app.defaults.date_format_moment ) ); + $(app.defaults.selector_end ).val( app.defaults.end_date.format( app.defaults.date_format_moment ) ); + $(app.defaults.selector_account ).val(app.defaults.id_account); + $(app.defaults.selector_price ).val(app.defaults.price); + $(app.defaults.selector_max_usage_count ).val(app.defaults.max_usage_count); + } + +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..4aa1294 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "author": "rocho", + "name": "coma", + "version": "0.0.1", + "private": true, + "dependencies": { + }, + "devDependencies": { + "grunt": "~0.4.1", + "matchdep": "*", + + "grunt-contrib-coffee": "*", + "grunt-contrib-compass": "*", + "grunt-contrib-watch": "*", + "grunt-contrib-imagemin": "*", + "grunt-contrib-clean": "*", + "grunt-concurrent": "*", + "grunt-jsmin-sourcemap": "*", + "grunt-notify": "*", + "grunt-newer": "*" + } +} \ No newline at end of file