Models and Repositories updated for cart rule usage

This commit is contained in:
Prashant Singh 2019-05-24 15:12:32 +05:30
parent 41c8793f64
commit b354b4ce15
22 changed files with 750 additions and 444 deletions

View File

@ -21,7 +21,7 @@ class CartRuleDataGrid extends DataGrid
{
$queryBuilder = DB::table('cart_rules')
->select('id')
->addSelect('id', 'name', 'description', 'status', 'end_other_rules', 'action_type');
->addSelect('id', 'name', 'starts_from', 'ends_till', 'usage_throttle', 'per_customer', 'status', 'end_other_rules', 'action_type');
$this->setQueryBuilder($queryBuilder);
}
@ -47,8 +47,17 @@ class CartRuleDataGrid extends DataGrid
]);
$this->addColumn([
'index' => 'description',
'label' => trans('admin::app.datagrid.desc'),
'index' => 'per_customer',
'label' => trans('admin::app.datagrid.per-cust'),
'type' => 'string',
'searchable' => false,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'usage_throttle',
'label' => trans('admin::app.datagrid.usage-throttle'),
'type' => 'string',
'searchable' => false,
'sortable' => true,
@ -61,7 +70,13 @@ class CartRuleDataGrid extends DataGrid
'type' => 'boolean',
'searchable' => false,
'sortable' => true,
'filterable' => true
'filterable' => true,
'wrapper' => function($value) {
if ($value->end_other_rules == 1)
return 'true';
else
return 'false';
}
]);
$this->addColumn([
@ -70,7 +85,13 @@ class CartRuleDataGrid extends DataGrid
'type' => 'boolean',
'searchable' => false,
'sortable' => true,
'filterable' => true
'filterable' => true,
'wrapper' => function($value) {
if ($value->end_other_rules == 1)
return 'true';
else
return 'false';
}
]);
$this->addColumn([
@ -85,28 +106,28 @@ class CartRuleDataGrid extends DataGrid
public function prepareActions()
{
// $this->addAction([
// 'type' => 'Edit',
// 'method' => 'GET', //use post only for redirects only
// 'route' => 'admin.catalog.attributes.edit',
// 'icon' => 'icon pencil-lg-icon'
// ]);
$this->addAction([
'type' => 'Edit',
'method' => 'GET', //use post only for redirects only
'route' => 'admin.cart-rule.edit',
'icon' => 'icon pencil-lg-icon'
]);
// $this->addAction([
// 'type' => 'Delete',
// 'method' => 'POST', //use post only for requests other than redirects
// 'route' => 'admin.catalog.attributes.delete',
// 'icon' => 'icon trash-icon'
// ]);
$this->addAction([
'type' => 'Delete',
'method' => 'POST', //use post only for requests other than redirects
'route' => 'admin.cart-rule.delete',
'icon' => 'icon trash-icon'
]);
}
public function prepareMassActions()
{
$this->addMassAction([
'type' => 'delete',
'action' => route('admin.catalog.attributes.massdelete'),
'label' => 'Delete',
'method' => 'DELETE'
]);
// $this->addMassAction([
// 'type' => 'delete',
// 'action' => route('admin.catalog.attributes.massdelete'),
// 'label' => 'Delete',
// 'method' => 'DELETE'
// ]);
}
}

View File

@ -643,7 +643,7 @@ Route::group(['middleware' => ['web']], function () {
// Route::post('/catalog-rule/delete/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@destroy')->name('admin.catalog-rule.delete');
Route::post('fetch/options', 'Webkul\Discount\Http\Controllers\CatalogRuleController@fetchAttributeOptions')->name('admin.catalog-rule.options');
// Route::post('fetch/options', 'Webkul\Discount\Http\Controllers\CatalogRuleController@fetchAttributeOptions')->name('admin.catalog-rule.options');
Route::get('/cart-rule', 'Webkul\Discount\Http\Controllers\CartRuleController@index')->defaults('_config', [
'view' => 'admin::promotions.cart-rule.index'
@ -654,8 +654,18 @@ Route::group(['middleware' => ['web']], function () {
])->name('admin.cart-rule.create');
Route::post('/cart-rule/store', 'Webkul\Discount\Http\Controllers\CartRuleController@store')->defaults('_config', [
'view' => 'admin.cart-rule.index'
'route' => 'admin.cart-rule.index'
])->name('admin.cart-rule.store');
Route::get('/cart-rule/edit/{$id}', 'Webkul\Discount\Http\Controllers\CartRuleController@edit')->defaults('_config', [
'view' => 'admin::promotions.cart-rule.edit'
])->name('admin.cart-rule.edit');
Route::post('/cart-rule/update/{$id}', 'Webkul\Discount\Http\Controllers\CartRuleController@update')->defaults('_config', [
'redirect' => 'admin.cart-rule.index'
])->name('admin.cart-rule.update');
Route::post('/cart-rule/delete/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@destroy')->name('admin.cart-rule.delete');
});
});
});

View File

@ -298,6 +298,17 @@ body {
}
}
.boolean-control-container {
display: flex;
flex-direction: row;
justify-content: flex-start;
width: 750px;
.control-group {
width: 200px;
}
}
.control-group {
label {
width: 70%;

View File

@ -156,6 +156,8 @@ return [
'attribute-family' => 'Attribute Family',
'starts-from' => 'Starts From',
'ends-till' => 'Ends Till',
'per-cust' => 'Per Customer',
'usage-throttle' => 'Usage Times'
],
'account' => [
@ -808,13 +810,18 @@ return [
'conditions' => 'Conditions',
'are' => 'are',
'true' => 'true',
'false' => 'false'
'false' => 'false',
'limit' => 'Usage Limit',
'specific-coupon' => 'Specific Coupon(Check) / Auto Generated(Unheck)',
'free-shipping' => 'Free Shipping'
],
'status' => [
'success' => 'Success! rule created',
'success-coupon' => 'Success! rule created along with coupon',
'failed' => 'Error! failed to create rule',
'update-success' => 'Success! rule updated',
'update-coupon-success' => 'Success! rule updated along with coupon',
'update-failed' => 'Error! cannot update',
'delete-success' => 'Sucess! rule deleted',
'delete-failed' => 'Error! cannot delete'

View File

@ -125,7 +125,7 @@
</div>
<div class="control-group" :class="[errors.has('auto_generation') ? 'has-error' : '']" v-if="use_coupon == 1">
<label for="auto_generation" class="required">Specific Coupon</label>
<label for="auto_generation" class="required">{{ __('admin::app.promotion.general-info.specific-coupon') }}</label>
<input type="checkbox" class="control" name="auto_generation" v-model="auto_generation" value="{{ old('auto_generation') }}" data-vv-as="&quot;Specific Coupon&quot;" v-on:change="checkAutogen">
@ -140,6 +140,14 @@
<span class="control-error" v-if="errors.has('per_customer')">@{{ errors.first('per_customer') }}</span>
</div>
<div class="control-group" :class="[errors.has('limit') ? 'has-error' : '']">
<label for="limit" class="required">{{ __('admin::app.promotion.general-info.limit') }}</label>
<input type="number" step="1" class="control" name="limit" v-model="limit" v-validate="'required|numeric|min_value:0'" value="{{ old('limit') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.uses-per-cust') }}&quot;">
<span class="control-error" v-if="errors.has('limit')">@{{ errors.first('limit') }}</span>
</div>
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
@ -232,10 +240,10 @@
<span class="control-error" v-if="errors.has('action_type')">@{{ errors.first('action_type') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']" v-if="apply_amt">
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']">
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="number" step="1.0000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<input type="number" step="0.5000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
</div>
@ -248,60 +256,63 @@
<span class="control-error" v-if="errors.has('disc_threshold')">@{{ errors.first('disc_threshold') }}</span>
</div>
<div class="control-group" :class="[errors.has('free_shipping') ? 'has-error' : '']" v-if="apply_prct">
<label for="free_shipping" class="required">{{ __('admin::app.promotion.general-info.free_shipping') }}</label>
<div class="boolean-control-container">
<div class="control-group" :class="[errors.has('free_shipping') ? 'has-error' : '']">
<label for="free_shipping" class="required">{{ __('admin::app.promotion.general-info.free-shipping') }}</label>
<input type="number" step="0.5000" class="control" name="free_shipping" v-model="free_shipping" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('free_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.free_shipping') }}&quot;">
<select type="text" class="control" name="free_shipping" v-model="free_shipping" v-validate="'required'" value="{{ old('free_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.free-shipping') }}&quot;">
<option value="0" :selected="free_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<span class="control-error" v-if="errors.has('free_shipping')">@{{ errors.first('free_shipping') }}</span>
</div>
<option value="1" :selected="free_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
<span class="control-error" v-if="errors.has('free_shipping')">@{{ errors.first('free_shipping') }}</span>
</div>
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.apply-to-shipping') }}&quot;">
<option value="0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
<option value="1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.apply-to-shipping') }}&quot;">
<option value="0" :selected="apply_to_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
<option value="1" :selected="apply_to_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
</div>
</div>
</div>
</accordian>
<accordian :active="false" title="Coupons" v-if="auto_generation != null">
<div slot="body">
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']" v-if="!auto_generation">
<label for="code" class="required">Code</label>
<input type="text" class="control" name="code" v-model="code" v-validate="'required'" value="{{ old('code') }}" data-vv-as="&quot;Code&quot;">
<div v-if="!auto_generation">
<div class="control-group" :class="[errors.has('prefix') ? 'has-error' : '']">
<label for="code" class="required">Prefix</label>
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
<input type="text" class="control" name="prefix" v-model="prefix" v-validate="'required'" value="{{ old('prefix') }}" data-vv-as="&quot;Prefix&quot;">
<span class="control-error" v-if="errors.has('prefix')">@{{ errors.first('prefix') }}</span>
</div>
<div class="control-group" :class="[errors.has('suffix') ? 'has-error' : '']"">
<label for="code" class="required">Suffix</label>
<input type="text" class="control" name="suffix" v-model="suffix" v-validate="'required'" value="{{ old('suffix') }}" data-vv-as="&quot;suffix&quot;">
<span class="control-error" v-if="errors.has('suffix')">@{{ errors.first('suffix') }}</span>
</div>
</div>
<div class="control-group" :class="[errors.has('prefix') ? 'has-error' : '']" v-if="!auto_generation">
<label for="code" class="required">Prefix</label>
<div v-if="auto_generation">
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code" class="required">Code</label>
<input type="text" class="control" name="prefix" v-model="prefix" v-validate="'required'" value="{{ old('prefix') }}" data-vv-as="&quot;Prefix&quot;">
<input type="text" class="control" name="code" v-model="code" v-validate="'required'" value="{{ old('code') }}" data-vv-as="&quot;Code&quot;">
<span class="control-error" v-if="errors.has('prefix')">@{{ errors.first('prefix') }}</span>
</div>
<div class="control-group" :class="[errors.has('suffix') ? 'has-error' : '']" v-if="!auto_generation">
<label for="code" class="required">Suffix</label>
<input type="text" class="control" name="suffix" v-model="suffix" v-validate="'required'" value="{{ old('suffix') }}" data-vv-as="&quot;suffix&quot;">
<span class="control-error" v-if="errors.has('suffix')">@{{ errors.first('suffix') }}</span>
</div>
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']" v-if="auto_generation">
<label for="code" class="required">Code</label>
<input type="text" class="control" name="code" v-model="code" v-validate="'required'" value="{{ old('code') }}" data-vv-as="&quot;Code&quot;">
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
</div>
</div>
</div>
</accordian>
@ -371,7 +382,7 @@
disc_quantity: 0,
end_other_rules: null,
coupon_type: null,
free_shipping: false,
free_shipping: null,
auto_generated: null,
all_conditions: null,
@ -380,6 +391,7 @@
suffix: null,
prefix: null,
dedicated_label: true,
limit: null,
global_label: null,
label: {
@ -435,7 +447,6 @@
},
checkAutogen() {
console.log(this.auto_generation);
},
detectApply() {
@ -461,7 +472,7 @@
useCoupon() {
if (this.use_coupon == 1) {
this.auto_generation = 0;
this.auto_generation = 1;
}
},
@ -474,7 +485,6 @@
},
onSubmit: function (e) {
debugger
this.$validator.validateAll().then(result => {
if (result) {
e.target.submit();

View File

@ -5,279 +5,349 @@
@stop
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.cart-rule.store') }}" @submit.prevent="onSubmit">
@csrf
<div class="page-header">
<div class="page-title">
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
{{ __('admin::app.promotion.add-cart-rule') }}
</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.promotion.save-btn-title') }}
</button>
</div>
</div>
<div class="page-content">
<div class="form-container">
<cart-rule></cart-rule>
</div>
</div>
</form>
<cart-rule></cart-rule>
</div>
@push('scripts')
<script type="text/x-template" id="cart-rule-form-template">
<div>
@csrf()
<form method="POST" action="{{ route('admin.cart-rule.store') }}" @submit.prevent="onSubmit">
@csrf
<accordian :active="true" title="Information">
<div slot="body">
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
<div class="page-header">
<div class="page-title">
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
<input type="text" class="control" name="name" v-model="name" v-validate="'required'" value="{{ old('name') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.name') }}&quot;">
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
<textarea class="control" name="description" v-model="description" v-validate="'required'" value="{{ old('description') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.description') }}&quot;"></textarea>
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
</div>
<div class="control-group" :class="[errors.has('customer_groups[]') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.cust-groups') }}</label>
<select type="text" class="control" name="customer_groups[]" v-model="customer_groups" v-validate="'required'" value="{{ old('customer_groups') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;" multiple="multiple">
<option disabled="disabled">Select Customer Groups</option>
@foreach(app('Webkul\Customer\Repositories\CustomerGroupRepository')->all() as $channel)
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('customer_groups[]')">@{{ errors.first('customer_groups[]') }}</span>
</div>
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.channels') }}&quot;" multiple="multiple">
<option disabled="disabled">Select Channels</option>
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channels[]')">@{{ errors.first('channels[]') }}</span>
</div>
<div class="control-group" :class="[errors.has('end_other_rules') ? 'has-error' : '']">
<label for="end_other_rules" class="required">{{ __('admin::app.promotion.general-info.end_other_rules') }}</label>
<select type="text" class="control" name="end_other_rules" v-model="end_other_rules" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.end_other_rules') }}&quot;">
<option disabled="disabled">Select option</option>
<option value="1">Yes</option>
<option value="0">No</option>
</select>
<span class="control-error" v-if="errors.has('end_other_rules')">@{{ errors.first('end_other_rules') }}</span>
</div>
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
<label for="status" class="required">{{ __('admin::app.promotion.general-info.status') }}</label>
<select type="text" class="control" name="status" v-model="status" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.status') }}&quot;">
<option disabled="disabled">Select status</option>
<option value="1">Yes</option>
<option value="0">No</option>
</select>
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
</div>
<div class="control-group" :class="[errors.has('is_coupon') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.is-coupon') }}</label>
<select type="text" class="control" name="is_coupon" v-model="is_coupon" v-validate="'required'" value="{{ old('is_coupon') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.is-coupon') }}&quot;">
<option value="0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('is_coupon')">@{{ errors.first('is_coupon') }}</span>
</div>
<div class="control-group" :class="[errors.has('uses_per_cust') ? 'has-error' : '']">
<label for="uses_per_cust" class="required">{{ __('admin::app.promotion.general-info.uses-per-cust') }}</label>
<input type="number" step="1" class="control" name="uses_per_cust" v-model="uses_per_cust" v-validate="'required|numeric|min_value:1'" value="{{ old('uses_per_cust') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.uses-per-cust') }}&quot;">
<span class="control-error" v-if="errors.has('uses_per_cust')">@{{ errors.first('uses_per_cust') }}</span>
</div>
<datetime :name="starts_from">
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
<label for="starts_from" class="required">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
<input type="text" class="control" v-model="starts_from" name="starts_from" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.starts-from') }}&quot;">
<span class="control-error" v-if="errors.has('starts_from')">@{{ errors.first('starts_from') }}</span>
</div>
</datetime>
<datetime :name="starts_from">
<div class="control-group" :class="[errors.has('ends_till') ? 'has-error' : '']">
<label for="ends_till" class="required">{{ __('admin::app.promotion.general-info.ends-till') }}</label>
<input type="text" class="control" v-model="ends_till" name="ends_till" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.ends-till') }}&quot;">
<span class="control-error" v-if="errors.has('ends_till')">@{{ errors.first('ends_till') }}</span>
</div>
</datetime>
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.priority') }}&quot;">
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
</div>
{{ __('admin::app.promotion.add-cart-rule') }}
</h1>
</div>
</accordian>
<accordian :active="true" title="Conditions">
<div slot="body">
<div class="add-condition">
<div class="control-group" :class="[errors.has('criteria') ? 'has-error' : '']">
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.promotion.save-btn-title') }}
</button>
</div>
</div>
<select type="text" class="control" name="criteria" v-model="criteria" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;">
<option value="cart">Cart Properties</option>
</select>
<div class="page-content">
<div class="form-container">
<div>
@csrf()
<span class="control-error" v-if="errors.has('criteria')">@{{ errors.first('criteria') }}</span>
</div>
<accordian :active="true" title="Information">
<div slot="body">
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
<span class="btn btn-primary btn-lg" v-on:click="addCondition">Add Condition</span>
</div>
<input type="text" class="control" name="name" v-model="name" v-validate="'required|alpha_spaces'" value="{{ old('name') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.name') }}&quot;">
<div class="condition-set">
<!-- Cart Attributes -->
<div v-for="(condition, index) in conditions_list" :key="index">
<div class="control-container mt-20">
<div class="title-bar">
<span>Cart Attribute is </span>
<span class="icon cross-icon" v-on:click="removeCartAttr(index)"></span>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
<div class="control-group mt-10" :key="index">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
<option disabled="disabled">Select Option</option>
<option v-for="(cart_ip, index1) in cart_input" :value="cart_ip.code" :key="index1">@{{ cart_ip.name }}</option>
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
<textarea class="control" name="description" v-model="description" v-validate="'alpha_spaces'" value="{{ old('description') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.description') }}&quot;"></textarea>
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
</div>
<datetime :name="starts_from">
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
<label for="starts_from">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
<input type="text" class="control" v-model="starts_from" name="starts_from" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.starts-from') }}&quot;">
<span class="control-error" v-if="errors.has('starts_from')">@{{ errors.first('starts_from') }}</span>
</div>
</datetime>
<datetime :name="starts_from">
<div class="control-group" :class="[errors.has('ends_till') ? 'has-error' : '']">
<label for="ends_till">{{ __('admin::app.promotion.general-info.ends-till') }}</label>
<input type="text" class="control" v-model="ends_till" name="ends_till" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.ends-till') }}&quot;">
<span class="control-error" v-if="errors.has('ends_till')">@{{ errors.first('ends_till') }}</span>
</div>
</datetime>
<div class="control-group" :class="[errors.has('customer_groups[]') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.cust-groups') }}</label>
<select type="text" class="control" name="customer_groups[]" v-model="customer_groups" v-validate="'required'" value="{{ old('customer_groups') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;" multiple="multiple">
<option disabled="disabled">Select Customer Groups</option>
@foreach(app('Webkul\Customer\Repositories\CustomerGroupRepository')->all() as $channel)
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
@endforeach
</select>
<div v-if='conditions_list[index].type == "string"'>
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
<span class="control-error" v-if="errors.has('customer_groups')">@{{ errors.first('customer_groups') }}</span>
</div>
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.channels') }}&quot;" multiple="multiple">
<option disabled="disabled">Select Channels</option>
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channels')">@{{ errors.first('channels') }}</span>
</div>
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
<label for="status" class="required">{{ __('admin::app.promotion.general-info.status') }}</label>
<select type="text" class="control" name="status" v-model="status" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.status') }}&quot;">
<option disabled="disabled">Select status</option>
<option value="1">Yes</option>
<option value="0">No</option>
</select>
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
</div>
<div class="control-group" :class="[errors.has('use_coupon') ? 'has-error' :
'']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.is-coupon') }}</label>
<select type="text" class="control" name="use_coupon" v-model="use_coupon" v-validate="'required'" value="{{ old('use_coupon')}}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.is-coupon') }}&quot;" v-on:change="useCoupon">
<option value="1" :selected="use_coupon == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="0" :selected="use_coupon == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('use_coupon')">@{{ errors.first('use_coupon') }}</span>
</div>
<div class="control-group" :class="[errors.has('auto_generation') ? 'has-error' : '']" v-if="use_coupon == 1">
<label for="auto_generation" class="required">{{ __('admin::app.promotion.general-info.specific-coupon') }}</label>
<input type="checkbox" class="control" name="auto_generation" v-model="auto_generation" value="{{ old('auto_generation') }}" data-vv-as="&quot;Specific Coupon&quot;" v-on:change="checkAutogen">
<span class="control-error" v-if="errors.has('auto_generation')">@{{ errors.first('auto_generation') }}</span>
</div>
<div class="control-group" :class="[errors.has('per_customer') ? 'has-error' : '']">
<label for="per_customer" class="required">{{ __('admin::app.promotion.general-info.uses-per-cust') }}</label>
<input type="number" step="1" class="control" name="per_customer" v-model="per_customer" v-validate="'required|numeric|min_value:0'" value="{{ old('per_customer') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.uses-per-cust') }}&quot;">
<span class="control-error" v-if="errors.has('per_customer')">@{{ errors.first('per_customer') }}</span>
</div>
<div class="control-group" :class="[errors.has('limit') ? 'has-error' : '']">
<label for="limit" class="required">{{ __('admin::app.promotion.general-info.limit') }}</label>
<input type="number" step="1" class="control" name="limit" v-model="limit" v-validate="'required|numeric|min_value:0'" value="{{ old('limit') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.uses-per-cust') }}&quot;">
<span class="control-error" v-if="errors.has('limit')">@{{ errors.first('limit') }}</span>
</div>
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.priority') }}&quot;">
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
</div>
</div>
</accordian>
<accordian :active="false" title="Conditions">
<div slot="body">
<div class="add-condition">
<div class="control-group" :class="[errors.has('criteria') ? 'has-error' : '']">
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
<select type="text" class="control" name="criteria" v-model="criteria" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;">
<option value="cart">Cart Properties</option>
</select>
<div v-if='conditions_list[index].attribute == "shipping_state"'>
<select class="control" v-validate="'required'" v-model="conditions_list[index].value">
<option disabled="disabled">Select State</option>
<optgroup v-for='(state, code) in country_and_states.states' :label="code">
<option v-for="(stateObj, index) in state" :value="stateObj.code">@{{ stateObj.default_name }}</option>
</optgroup>
</select>
</div>
<div v-if='conditions_list[index].attribute == "shipping_country"'>
<select class="control" v-validate="'required'" v-model="conditions_list[index].value">
<option disabled="disabled">Select Country</option>
<option v-for="(country, index) in country_and_states.countries" :value="country.code">@{{ country.name }}</option>
</select>
</div>
<input type="text" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value" v-if='conditions_list[index].attribute != "shipping_state" && conditions_list[index].attribute != "shipping_country"'>
<span class="control-error" v-if="errors.has('criteria')">@{{ errors.first('criteria') }}</span>
</div>
<div v-if='conditions_list[index].type == "numeric"'>
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
</select>
<span class="btn btn-primary btn-lg" v-on:click="addCondition">Add Condition</span>
</div>
<input type="number" step="0.1000" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
<div class="condition-set">
<!-- Cart Attributes -->
<div v-for="(condition, index) in conditions_list" :key="index">
<div class="control-container mt-20">
<div class="title-bar">
<span>Cart Attribute is </span>
<span class="icon cross-icon" v-on:click="removeCartAttr(index)"></span>
</div>
<div class="control-group mt-10" :key="index">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
<option disabled="disabled">Select Option</option>
<option v-for="(cart_ip, index1) in cart_input" :value="cart_ip.code" :key="index1">@{{ cart_ip.name }}</option>
</select>
<div v-if='conditions_list[index].type == "string"'>
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
</select>
<div v-if='conditions_list[index].attribute == "shipping_state"'>
<select class="control" v-validate="'required'" v-model="conditions_list[index].value">
<option disabled="disabled">Select State</option>
<optgroup v-for='(state, code) in country_and_states.states' :label="code">
<option v-for="(stateObj, index) in state" :value="stateObj.code">@{{ stateObj.default_name }}</option>
</optgroup>
</select>
</div>
<div v-if='conditions_list[index].attribute == "shipping_country"'>
<select class="control" v-validate="'required'" v-model="conditions_list[index].value">
<option disabled="disabled">Select Country</option>
<option v-for="(country, index) in country_and_states.countries" :value="country.code">@{{ country.name }}</option>
</select>
</div>
<input type="text" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value" v-if='conditions_list[index].attribute != "shipping_state" && conditions_list[index].attribute != "shipping_country"'>
</div>
<div v-if='conditions_list[index].type == "numeric"'>
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
</select>
<input type="number" step="0.1000" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</accordian>
<accordian :active="false" title="Actions">
<div slot="body">
<div class="control-group" :class="[errors.has('action_type') ? 'has-error' : '']">
<label for="action_type" class="required">Apply</label>
<select class="control" name="action_type" v-model="action_type" v-validate="'required'" value="{{ old('action_type') }}" data-vv-as="&quot;Apply As&quot;" v-on:change="detectApply">
<option v-for="(action, index) in actions" :value="index">@{{ action }}</option>
</select>
<span class="control-error" v-if="errors.has('action_type')">@{{ errors.first('action_type') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']">
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="number" step="0.5000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_threshold') ? 'has-error' : '']">
<label for="disc_threshold" class="required">{{ __('admin::app.promotion.cart.buy-atleast') }}</label>
<input type="number" step="1" class="control" name="disc_threshold" v-model="disc_threshold" v-validate="'required|numeric|min_value:1'" value="{{ old('disc_threshold') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.buy-atleast') }}&quot;">
<span class="control-error" v-if="errors.has('disc_threshold')">@{{ errors.first('disc_threshold') }}</span>
</div>
<div class="boolean-control-container">
<div class="control-group" :class="[errors.has('free_shipping') ? 'has-error' : '']">
<label for="free_shipping" class="required">{{ __('admin::app.promotion.general-info.free-shipping') }}</label>
<select type="text" class="control" name="free_shipping" v-model="free_shipping" v-validate="'required'" value="{{ old('free_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.free-shipping') }}&quot;">
<option value="0" :selected="free_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="1" :selected="free_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('free_shipping')">@{{ errors.first('free_shipping') }}</span>
</div>
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.apply-to-shipping') }}&quot;">
<option value="0" :selected="apply_to_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="1" :selected="apply_to_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
</div>
</div>
</div>
</accordian>
<accordian :active="false" title="Coupons" v-if="auto_generation != null">
<div slot="body">
<div v-if="!auto_generation">
<div class="control-group" :class="[errors.has('prefix') ? 'has-error' : '']">
<label for="code" class="required">Prefix</label>
<input type="text" class="control" name="prefix" v-model="prefix" v-validate="'required'" value="{{ old('prefix') }}" data-vv-as="&quot;Prefix&quot;">
<span class="control-error" v-if="errors.has('prefix')">@{{ errors.first('prefix') }}</span>
</div>
<div class="control-group" :class="[errors.has('suffix') ? 'has-error' : '']"">
<label for="code" class="required">Suffix</label>
<input type="text" class="control" name="suffix" v-model="suffix" v-validate="'required'" value="{{ old('suffix') }}" data-vv-as="&quot;suffix&quot;">
<span class="control-error" v-if="errors.has('suffix')">@{{ errors.first('suffix') }}</span>
</div>
</div>
<div v-if="auto_generation">
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code" class="required">Code</label>
<input type="text" class="control" name="code" v-model="code" v-validate="'required'" value="{{ old('code') }}" data-vv-as="&quot;Code&quot;">
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
</div>
</div>
</div>
</accordian>
<accordian :active="false" title="labels">
<div slot="body">
<input type="hidden" name="all_conditions[]" v-model="all_conditions">
<div class="control-group" :class="[errors.has('label') ? 'has-error' : '']" v-if="dedicated_label">
<label for="label" class="required">Global Label</label>
<input type="text" class="control" name="label[global]" v-model="label.global" v-validate="'required'" value="{{ old('label') }}" data-vv-as="&quot;label&quot;">
<span class="control-error" v-if="errors.has('label')">@{{ errors.first('label') }}</span>
</div>
<div v-if="label.global == null || label.global == ''">
@foreach(core()->getAllChannels() as $channel)
<span>[{{ $channel->code }}]</span>
@foreach($channel->locales as $locale)
<div class="control-group" :class="[errors.has('label') ? 'has-error' : '']">
<label for="code">{{ $locale->code }}</label>
<input type="text" class="control" name="label[{{ $channel->code }}][{{ $locale->code }}]" v-model="label.{{ $channel->code }}.{{ $locale->code }}" v-validate="'alpha'" value="{{ old('label') }}" data-vv-as="&quot;Label&quot;">
<span class="control-error" v-if="errors.has('label')">@{{ errors.first('label') }}</span>
</div>
@endforeach
@endforeach
</div>
</div>
</accordian>
</div>
</div>
</accordian>
<accordian :active="true" title="Actions">
<div slot="body">
<div class="control-group" :class="[errors.has('apply') ? 'has-error' : '']">
<label for="apply" class="required">Apply</label>
<select class="control" name="apply" v-model="apply" v-validate="'required'" value="{{ old('apply') }}" data-vv-as="&quot;Apply As&quot;" v-on:change="detectApply">
<option value="1">{{ __('admin::app.promotion.catalog.apply-percent') }}</option>
<option value="2">{{ __('admin::app.promotion.catalog.apply-fixed') }}</option>
<option value="3">{{ __('admin::app.promotion.catalog.adjust-to-percent') }}</option>
<option value="4">{{ __('admin::app.promotion.catalog.adjust-to-value') }}</option>
</select>
<span class="control-error" v-if="errors.has('apply')">@{{ errors.first('apply') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']" v-if="apply_amt">
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="number" step="1.0000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_percent') ? 'has-error' : '']" v-if="apply_prct">
<label for="disc_percent" class="required">{{ __('admin::app.promotion.general-info.disc_percent') }}</label>
<input type="number" step="0.5000" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_percent') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_percent') }}&quot;">
<span class="control-error" v-if="errors.has('disc_percent')">@{{ errors.first('disc_percent') }}</span>
</div>
<div class="control-group" :class="[errors.has('buy_atleast') ? 'has-error' : '']">
<label for="buy_atleast" class="required">{{ __('admin::app.promotion.cart.buy-atleast') }}</label>
<input type="number" step="1" class="control" name="buy_atleast" v-model="buy_atleast" v-validate="'required|numeric|min_value:1'" value="{{ old('buy_atleast') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.buy-atleast') }}&quot;">
<span class="control-error" v-if="errors.has('buy_atleast')">@{{ errors.first('buy_atleast') }}</span>
</div>
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.apply-to-shipping') }}&quot;">
<option value="0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
</div>
</div>
</accordian>
</div>
</div>
</form>
</script>
<script>
@ -288,30 +358,56 @@
data () {
return {
type: [],
name: @json($cart_rule->name),
description: @json($cart_rule->name),
conditions_list: [],
channels: [],
customer_groups: [],
ends_till: @json($cart_rule->ends_till),
starts_from: @json($cart_rule->starts_from),
priority: @json($cart_rule->priority),
per_customer: @json($cart_rule->per_customer),
status: @json($cart_rule->status),
use_coupon: @json($cart_rule->coupon_usage),
auto_generation: @json($cart_rule->auto_generation),
action_type: @json($cart_rule->action_type),
apply: null,
apply_amt: false,
apply_prct: false,
apply_to_shipping: null,
buy_atleast: null,
conditions_list: [],
channels: [],
criteria: null,
customer_groups: [],
description: null,
disc_amount: 0.0,
disc_percent: 0.0,
ends_till: null,
apply_to_shipping: @json($cart_rule->apply_to_shipping),
disc_amount: @json($cart_rule->disc_amount),
disc_threshold: @json($cart_rule->disc_threshold),
disc_quantity: @json($cart_rule->disc_quantity),
end_other_rules: null,
is_coupon: null,
name: null,
priority: 0,
starts_from: null,
uses_per_cust: 0,
status: null,
coupon_type: @json($cart_rule->coupon_type),
free_shipping: @json($cart_rule->free_shipping),
auto_generated: null,
all_conditions: null,
code: null,
suffix: null,
prefix: null,
dedicated_label: true,
limit: null,
global_label: null,
label: {
global: null,
@foreach(core()->getAllChannels() as $channel)
@foreach($channel->locales as $locale)
{{ trim($channel->code) }} : {
{{ trim($locale->code) }}: ''
},
@endforeach
@endforeach
},
criteria: null,
conditions: @json($cart_rule[0]).conditions,
cart_input: @json($cart_rule[0]).attributes,
actions: @json($cart_rule).actions,
actions: @json($cart_rule[0]).actions,
conditions_list:[],
cart_object: {
criteria: null,
@ -324,7 +420,7 @@
},
mounted () {
console.log(this.country_and_states.countries);
this.use_coupon = 0;
},
methods: {
@ -349,11 +445,14 @@
}
},
checkAutogen() {
},
detectApply() {
if (this.apply == 1 || this.apply == 3) {
if (this.apply == 'percent_of_product' || this.apply == 'buy_a_get_b') {
this.apply_prct = true;
this.apply_amt = false;
} else if (this.apply == 2 || this.apply == 4) {
} else if (this.apply == 'fixed_amount' || this.apply == 'fixed_amount_cart') {
this.apply_prct = false;
this.apply_amt = true;
}
@ -370,12 +469,64 @@
}
},
useCoupon() {
if (this.use_coupon == 1) {
this.auto_generation = 1;
}
},
removeCartAttr(index) {
this.conditions_list.splice(index, 1);
},
removeCat(index) {
this.cats.splice(index, 1);
},
onSubmit: function (e) {
this.$validator.validateAll().then(result => {
if (result) {
e.target.submit();
}
});
for (index in this.conditions_list) {
if (this.conditions_list[index].condition == null || this.conditions_list[index].condition == "" || this.conditions_list[index].condition == undefined) {
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
this.$root.addFlashMessages();
return false;
} else if (this.conditions_list[index].value == null || this.conditions_list[index].value == "" || this.conditions_list[index].value == undefined) {
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
this.$root.addFlashMessages();
return false;
}
}
if (this.conditions_list.length == 0) {
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
this.$root.addFlashMessages();
return false;
}
this.all_conditions = JSON.stringify(this.conditions_list);
},
// genericGroupCondition() {
// this.generic_condition = false;
// },
addFlashMessages() {
const flashes = this.$refs.flashes;
flashMessages.forEach(function(flash) {
flashes.addFlash(flash);
}, this);
}
}
});

View File

@ -20,8 +20,8 @@
</div>
<div class="page-content">
@inject('customerGrid','Webkul\Admin\DataGrids\CustomerDataGrid')
{!! $customerGrid->render() !!}
@inject('cartRuleGrid','Webkul\Admin\DataGrids\CartRuleDataGrid')
{!! $cartRuleGrid->render() !!}
</div>
</div>
@endsection

View File

@ -1,31 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBackorderChannelsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('backorder_channels', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('backorder_channels');
}
}

View File

@ -1,31 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBackorderInventoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('backorder_inventories', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('backorder_inventories');
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\Discount\Contracts;
interface CartRuleCouponsUsage
{
}

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\Discount\Contracts;
interface CartRuleCustomers
{
}

View File

@ -13,13 +13,13 @@ class CreateCartruleCustomersTable extends Migration
*/
public function up()
{
Schema::create('cartrule_customers', function (Blueprint $table) {
Schema::create('cart_rule_customers', function (Blueprint $table) {
$table->increments('id');
$table->integer('cart_rule_id')->unsigned();
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
$table->integer('customer_id')->unsigned();
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
$table->integer('usage_throttle')->unsigned()->default(0);
$table->bigInteger('usage_throttle')->unsigned()->default(0);
$table->timestamps();
});
}

View File

@ -13,7 +13,7 @@ class CreateCartruleCouponsTable extends Migration
*/
public function up()
{
Schema::create('cartrule_coupons', function (Blueprint $table) {
Schema::create('cart_rule_coupons', function (Blueprint $table) {
$table->increments('id');
$table->integer('cart_rule_id')->unsigned();
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');

View File

@ -1,36 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCartRuleCouponsUsageCustomersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cart_rule_coupons_usage_customers', function (Blueprint $table) {
$table->increments('id');
$table->integer('coupon_id')->unsigned();
$table->foreign('coupon_id')->references('id')->on('cart_rules')->onDelete('cascade');
$table->integer('customer_id')->unsigned();
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
$table->bigInteger('usage')->unsigned()->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cart_rule_coupons_usage_customers');
}
}

View File

@ -99,6 +99,107 @@ class CartRuleController extends Controller
{
$data = request()->all();
unset($data['_token']);
$channels = $data['channels'];
unset($data['channels']);
$customer_groups = $data['customer_groups'];
unset($data['customer_groups']);
unset($data['criteria']);
$labels = $data['label'];
unset($data['label']);
unset($data['cart_attributes']);
unset($data['attributes']);
$data['conditions'] = $data['all_conditions'];
unset($data['all_conditions']);
if (isset($data['disc_amount'])) {
$data['actions'] = [
'action_type' => $data['action_type'],
'disc_amount' => $data['disc_amount'],
'disc_thresold' => $data['disc_threshold']
];
}
$data['actions'] = json_encode($data['actions']);
$data['conditions'] = json_encode($data['conditions']);
$data['coupon_usage'] = $data['use_coupon'];
unset($data['use_coupon']);
$coupons['code'] = $data['code'];
unset($data['code']);
if (isset($data['prefix'])) {
$coupons['prefix'] = $data['prefix'];
unset($data['prefix']);
}
if(isset($data['suffix'])) {
$coupons['suffix'] = $data['suffix'];
unset($data['suffix']);
}
if(isset($data['limit'])) {
$coupons['limit'] = $data['limit'];
unset($data['limit']);
}
$ruleCreated = $this->cartRule->create($data);
$ruleGroupCreated = $this->cartRule->CustomerGroupSync($customer_groups, $ruleCreated);
$ruleChannelCreated = $this->cartRule->ChannelSync($channels, $ruleCreated);
if (isset($labels['global'])) {
foreach (core()->getAllChannels() as $channel) {
$label1['channel_id'] = $channel->id;
foreach($channel->locales as $locale) {
$label1['locale_id'] = $locale->id;
$label1['label'] = $labels['global'];
$ruleLabelCreated = $this->cartRuleLabel->create($label1);
}
}
} else {
$label2['label'] = $labels['global'];
$ruleLabelCreated = $this->cartRuleLabel->create($label2);
}
if(isset($coupons)) {
$coupons['cart_rule_id'] = $ruleCreated->id;
$coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
$couponCreated = $this->cartRuleCoupon->create($coupons);
}
if ($ruleCreated && $ruleGroupCreated && $ruleChannelCreated) {
if ($couponCreated) {
session()->flash('success', trans('admin::app.promotion.status.success-coupon'));
}
session()->flash('success', trans('admin::app.promotion.status.success'));
} else {
session()->flash('success', trans('admin::app.promotion.status.success'));
return redirect()->back();
}
return redirect()->route($this->_config['route']);
}
public function edit($id)
{
$cart_rule = $this->cartRule->find($id);
return view($this->_config['view'])->with('cart_rule', [$this->appliedConfig, $this->fetchOptionableAttributes(), $this->getStatesAndCountries(), $cart_rule]);
}
public function update()
{
$data = request()->all();
//assumed default
$data['limit'] = 10;
@ -181,13 +282,32 @@ class CartRuleController extends Controller
if ($ruleCreated && $ruleGroupCreated && $ruleChannelCreated) {
if ($couponCreated) {
dd('created with a coupon or coupons');
session()->flash('success', trans('admin::app.promotion.status.success-coupon'));
}
dd('created');
session()->flash('success', trans('admin::app.promotion.status.success'));
} else {
dd('error');
session()->flash('success', trans('admin::app.promotion.status.success'));
return redirect()->back();
}
return redirect()->route($this->_config['route']);
}
public function destroy($id)
{
$cartRule = $this->cartRule->findOrFail($id);
if ($cartRule->delete()) {
session()->flash('success', trans('admin::app.promotion.status.delete-success'));
return response()->json(['message' => true], 200);
} else {
session()->flash('success', trans('admin::app.promotion.status.delete-failed'));
return response()->json(['message' => false], 400);
}
}
public function getStatesAndCountries()

View File

@ -8,7 +8,7 @@ use Webkul\Discount\Models\CartRuleProxy as CartRule;
class CartRuleCoupons extends Model implements CartRuleCouponsContract
{
protected $table = 'cartrule_coupons';
protected $table = 'cart_rule_coupons';
protected $guarded = ['created_at', 'updated_at'];

View File

@ -0,0 +1,19 @@
<?php
namespace Webkul\Discount\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Discount\Contracts\CartRuleCouponsUsage as CartRuleCouponsUsageContract;
use Webkul\Discount\Models\CartRuleProxy as CartRule;
class CartRuleCouponsUsage extends Model implements CartRuleCouponsUsageContract
{
protected $table = 'cart_rule_coupons_usage';
protected $guarded = ['created_at', 'updated_at'];
public function cart_rule()
{
return $this->belongsTo(CartRule::modelClass(), 'cart_rule_id');
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Discount\Models;
use Konekt\Concord\Proxies\ModelProxy;
class CartRuleCouponsUsageProxy extends ModelProxy
{
}

View File

@ -0,0 +1,19 @@
<?php
namespace Webkul\Discount\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Discount\Contracts\CartRuleCustomers as CartRuleCustomersContract;
use Webkul\Discount\Models\CartRuleProxy as CartRule;
class CartRuleCustomers extends Model implements CartRuleCustomersContract
{
protected $table = 'cart_rule_customers';
protected $guarded = ['created_at', 'updated_at'];
public function cart_rule()
{
return $this->belongsTo(CartRule::modelClass(), 'cart_rule_id');
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Discount\Models;
use Konekt\Concord\Proxies\ModelProxy;
class CartRuleCustomersProxy extends ModelProxy
{
}

View File

@ -15,6 +15,8 @@ class ModuleServiceProvider extends BaseModuleServiceProvider
\Webkul\Discount\Models\CartRuleChannels::class,
\Webkul\Discount\Models\CartRuleCustomerGroups::class,
\Webkul\Discount\Models\CartRuleCoupons::class,
\Webkul\Discount\Models\CartRuleLabels::class
\Webkul\Discount\Models\CartRuleLabels::class,
\Webkul\Discount\Models\CartRuleCouponsUsage::class,
\Webkul\Discount\Models\CartRuleCustomers::class
];
}