Added downloadable and virtual products

This commit is contained in:
jitendra 2019-06-29 15:23:34 +05:30
parent 55b71e1e66
commit ad6e422fdb
75 changed files with 1658 additions and 992 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/admin.js": "/js/admin.js?id=301713f31cb0ba5260b5",
"/css/admin.css": "/css/admin.css?id=226f12bd8a9461ca69f8"
"/js/admin.js": "/js/admin.js?id=2bab17ad3ee2b7f905ac",
"/css/admin.css": "/css/admin.css?id=01764b9f81357d7a4c3a"
}

View File

@ -391,7 +391,32 @@ return [
'name' => 'admin::app.acl.delete',
'route' => 'admin.tax-rates.delete',
'sort' => 3
]
], [
'key' => 'promotions',
'name' => 'admin::app.acl.promotions',
'route' => 'admin.cart-rule.index',
'sort' => 7
], [
'key' => 'promotions.cart-rule',
'name' => 'admin::app.acl.cart-rules',
'route' => 'admin.cart-rule.index',
'sort' => 1
], [
'key' => 'promotions.cart-rule.create',
'name' => 'admin::app.acl.create',
'route' => 'admin.cart-rule.create',
'sort' => 1
], [
'key' => 'promotions.cart-rule.edit',
'name' => 'admin::app.acl.edit',
'route' => 'admin.cart-rule.edit',
'sort' => 2
], [
'key' => 'promotions.cart-rule.delete',
'name' => 'admin::app.acl.delete',
'route' => 'admin.cart-rule.delete',
'sort' => 3
],
];
?>

View File

@ -21,7 +21,7 @@ class CartRuleDataGrid extends DataGrid
{
$queryBuilder = DB::table('cart_rules')
->select('id')
->addSelect('id', 'name', 'starts_from', 'ends_till', 'priority', 'usage_limit', 'per_customer', 'status', 'end_other_rules', 'is_guest', 'action_type');
->addSelect('id', 'name', 'starts_from', 'ends_till', 'priority', 'status', 'end_other_rules', 'action_type', 'disc_quantity', 'disc_threshold', 'use_coupon');
$this->setQueryBuilder($queryBuilder);
}
@ -41,7 +41,7 @@ class CartRuleDataGrid extends DataGrid
'index' => 'name',
'label' => trans('admin::app.datagrid.name'),
'type' => 'string',
'searchable' => false,
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
@ -59,29 +59,14 @@ class CartRuleDataGrid extends DataGrid
'index' => 'status',
'label' => trans('admin::app.datagrid.status'),
'type' => 'boolean',
'searchable' => false,
'searchable' => true,
'sortable' => true,
'filterable' => true,
'wrapper' => function($value) {
if ($value->status == 1)
return 'True';
return 'Active';
else
return 'False';
}
]);
$this->addColumn([
'index' => 'is_guest',
'label' => trans('admin::app.datagrid.for-guest'),
'type' => 'boolean',
'searchable' => false,
'sortable' => true,
'filterable' => true,
'wrapper' => function($value) {
if ($value->is_guest == 1)
return 'True';
else
return 'False';
return 'In Active';
}
]);
@ -104,10 +89,47 @@ class CartRuleDataGrid extends DataGrid
'index' => 'action_type',
'label' => 'Action Type',
'type' => 'string',
'searchable' => true,
'sortable' => true,
'filterable' => true,
'wrapper' => function($value) {
return config('pricerules.cart.actions')[$value->action_type];
}
]);
$this->addColumn([
'index' => 'disc_quantity',
'label' => 'Quantity',
'type' => 'number',
'searchable' => false,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'disc_threshold',
'label' => 'Threshold',
'type' => 'number',
'searchable' => false,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'use_coupon',
'label' => 'Use Coupon',
'type' => 'boolean',
'searchable' => true,
'sortable' => true,
'filterable' => true,
'wrapper' => function($value) {
if ($value->use_coupon == 1) {
return 'True';
} else {
return 'False';
}
}
]);
}
public function prepareActions()

View File

@ -152,7 +152,6 @@ class CustomerController extends Controller
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
'phone' => 'nullable|numeric|unique:customers,phone,'. $id,
'email' => 'required|unique:customers,email,'. $id,
'date_of_birth' => 'date|before:today'
]);
@ -190,7 +189,7 @@ class CustomerController extends Controller
/**
* To load the note taking screen for the customers
*
* @return View
* @return view
*/
public function createNote($id)
{
@ -202,12 +201,12 @@ class CustomerController extends Controller
/**
* To store the response of the note in storage
*
* @return Redirect
* @return redirect
*/
public function storeNote()
{
$this->validate(request(), [
'notes' => 'required|string'
'notes' => 'string|nullable'
]);
$customer = $this->customer->find(request()->input('_customer'));
@ -227,6 +226,8 @@ class CustomerController extends Controller
/**
* To mass update the customer
*
* @return redirect
*/
public function massUpdate()
{
@ -241,13 +242,15 @@ class CustomerController extends Controller
]);
}
session()->flash('info', trans('admin::app.customers.customers.mass-update-success'));
session()->flash('success', trans('admin::app.customers.customers.mass-update-success'));
return redirect()->back();
}
/**
* To mass delete the customer
*
* @return redirect
*/
public function massDestroy()
{
@ -259,7 +262,7 @@ class CustomerController extends Controller
]);
}
session()->flash('info', trans('admin::app.customers.customers.mass-destroy-success'));
session()->flash('success', trans('admin::app.customers.customers.mass-destroy-success'));
return redirect()->back();
}

View File

@ -17,7 +17,7 @@ use Excel;
class ExportController extends Controller
{
protected $exportableGrids = [
'OrderDataGrid', 'OrderInvoicesDataGrid', 'OrderShipmentsDataGrid', 'CustomerDataGrid', 'TaxRateDataGrid'
'OrderDataGrid', 'OrderInvoicesDataGrid', 'OrderShipmentsDataGrid', 'CustomerDataGrid', 'TaxRateDataGrid', 'ProductDataGrid'
];
/**

View File

@ -226,7 +226,7 @@ Route::group(['middleware' => ['web']], function () {
Route::post('/products/upload-file/{id}', 'Webkul\Product\Http\Controllers\ProductController@uploadLink')->name('admin.catalog.products.upload_link');
Route::post('/products/upload-sample/{id}', 'Webkul\Product\Http\Controllers\ProductController@uploadSample')->name('admin.catalog.products.upload_sample');
//product delete
Route::post('/products/delete/{id}', 'Webkul\Product\Http\Controllers\ProductController@destroy')->name('admin.catalog.products.delete');
@ -248,6 +248,10 @@ Route::group(['middleware' => ['web']], function () {
'view' => 'admin::catalog.products.edit'
])->name('admin.catalog.products.productlinksearch');
Route::get('/products/{id}/{attribute_id}', 'Webkul\Product\Http\Controllers\ProductController@download')->defaults('_config', [
'view' => 'admin.catalog.products.edit'
])->name('admin.catalog.products.file.download');
// Catalog Category Routes
Route::get('/categories', 'Webkul\Category\Http\Controllers\CategoryController@index')->defaults('_config', [
'view' => 'admin::catalog.categories.index'

View File

@ -3,7 +3,6 @@
namespace Webkul\Admin\Listeners;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductGridRepository;
use Webkul\Product\Repositories\ProductFlatRepository;
use Webkul\Product\Helpers\Price;
@ -40,15 +39,12 @@ class Product {
public function __construct(
ProductRepository $product,
ProductGridRepository $productGrid,
ProductFlatRepository $productFlat,
Price $price
)
{
$this->product = $product;
$this->productGrid = $productGrid;
$this->productFlat = $productFlat;
$this->price = $price;

View File

@ -121,8 +121,7 @@ $(document).ready(function () {
}
},
addServerErrors() {
var scope = null;
addServerErrors(scope = null) {
for (var key in serverErrors) {
var inputNames = [];
key.split('.').forEach(function(chunk, index) {

View File

@ -123,6 +123,11 @@ body {
color: #0041ff;
}
}
span {
display: block;
margin: auto;
}
}
}
@ -262,35 +267,30 @@ body {
}
.control-container {
border: 1px solid #c7c7c7;
padding: 10px;
width: 63%;
display: flex;
flex-direction: row;
align-items: center;
width: 750px;
.title-bar {
display: inline-flex;
justify-content: space-between;
width: 100%;
.control {
background: #fff;
border: 2px solid #C7C7C7;
@include border-radius(3px);
width: 150px;
height: 36px;
display: inline-block;
vertical-align: middle;
transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
padding: 0px 10px;
font-size: 15px;
.icon {
cursor: pointer;
}
.icon.cross-icon {
height: 24px;
width: 24px;
&:focus {
border-color: #0041FF;
}
}
.control-group {
display: flex;
flex-direction: row;
align-content: center;
justify-content: flex-start;
padding: 10px;
border: 1px solid #c7c7c7;
border-radius: 2px;
margin-right: 15px;
margin-bottom: 0px;
.icon:hover {
cursor: pointer;
}
.control-group::last-child {
@ -346,6 +346,7 @@ body {
box-shadow: 0 5px 10px 2px rgba(0,0,0,0.08);
border-radius: 2px;
padding: 20px 0px 0px 20px;
overflow: auto;
.card-title {
font-size: 14px;
@ -455,7 +456,7 @@ body {
font-size: 14px;
color: #8E8E8E;
float: right;
margin-top: 9px;
margin-top: -2px;
.icon {
vertical-align: middle;

View File

@ -75,6 +75,8 @@ return [
'edit' => 'Edit',
'create' => 'Add',
'delete' => 'Delete',
'promotions' => 'Promotions',
'cart-rules' => 'Cart Rules'
],
'dashboard' => [
@ -783,7 +785,10 @@ return [
'edit-help-title' => 'Edit Customer',
'delete-help-title' => 'Delete Customer',
'mass-destroy-success' => 'Customers deleted successfully',
'mass-update-success' => 'Customers updated successfully'
'mass-update-success' => 'Customers updated successfully',
'status' => 'Status',
'active' => 'Active',
'in-active' => 'Inactive'
],
'reviews' => [
@ -821,6 +826,7 @@ return [
'create-cart-rule' => 'Create Cart Rule',
'save-btn-title' => 'Create',
'edit-btn-title' => 'Edit',
'save' => 'Save',
'select-attr' => 'Select Attribute',
'select-attr-fam' => 'Select Attribute Family',
'select-cart-attr' => 'Select Cart Attribute',
@ -834,7 +840,7 @@ return [
'cust-groups' => 'Customer Groups',
'priority' => 'Priority',
'add-condition' => 'Add Conditions',
'disc_amt' => 'Discount Amount(B)',
'disc_amt' => 'Discount Amount',
'disc_percent' => 'Discount Percentage',
'is-coupon' => 'Use Coupon',
'is-coupon-yes' => 'Yes',
@ -849,6 +855,7 @@ return [
'any' => 'Any',
'all' => 'All',
'conditions' => 'Conditions',
'apply' => 'Apply',
'are' => 'are',
'true' => 'true',
'false' => 'false',
@ -857,7 +864,8 @@ return [
'free-shipping' => 'Free Shipping',
'is-guest' => 'For Guests',
'disc_qty' => 'Max. Quantity Allowed To Be Discounted',
'test-mode' => 'Choose how to test conditions'
'test-mode' => 'Choose how to test conditions',
'labels' => 'Labels'
],
'status' => [
@ -873,7 +881,8 @@ return [
'coupon-failed' => 'Coupon failed to apply',
'no-coupon' => '* Coupon not applicable',
'coupon-removed' => 'Coupon removed successfully',
'coupon-remove-failed' => 'Coupon removal failed'
'coupon-remove-failed' => 'Coupon removal failed',
'duplicate-coupon' => 'Coupon already exists, please try again with a different coupon'
],
'catalog' => [
@ -885,8 +894,9 @@ return [
'adjust-to-value' => 'Adjust to discount value',
'condition-missing' => 'Please check conditons, some values might be missing'
],
'cart' => [
'buy-atleast' => 'Buy Atleast (N)',
'buy-atleast' => 'Buy Atleast',
'apply-to-shipping' => 'Apply to shipping'
]
],
@ -1009,7 +1019,7 @@ return [
'footer' => 'Footer',
'content' => 'Content',
'footer-content' => 'Footer Text',
'locale-options' => 'Locale Options',
'locale-options' => 'Unit Options',
'weight-unit' => 'Weight Unit',
'design' => 'Design',
'admin-logo' => 'Admin Logo',

View File

@ -78,7 +78,7 @@
<span class="control-error" v-if="errors.has('admin_name')">@{{ errors.first('admin_name') }}</span>
</div>
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
<div class="control-group">
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
@ -251,7 +251,7 @@
<th>{{ __('admin::app.catalog.attributes.admin_name') }}</th>
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
<th>{{ $locale->name . ' (' . $locale->code . ')' }}</th>
@ -280,7 +280,7 @@
</div>
</td>
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
<td>
<div class="control-group" :class="[errors.has(localeInputName(row, '{{ $locale->code }}')) ? 'has-error' : '']">
<input type="text" v-validate="'{{ app()->getLocale() }}' == '{{ $locale->code }}' ? 'required': ''" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control" data-vv-as="&quot;{{ $locale->name . ' (' . $locale->code . ')' }}&quot;"/>
@ -356,7 +356,7 @@
var rowCount = this.optionRowCount++;
var row = {'id': 'option_' + rowCount};
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
row['{{ $locale->code }}'] = '';
@endforeach

View File

@ -101,7 +101,7 @@
<span class="control-error" v-if="errors.has('admin_name')">@{{ errors.first('admin_name') }}</span>
</div>
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
<div class="control-group">
<label for="locale-{{ $locale->code }}">{{ $locale->name . ' (' . $locale->code . ')' }}</label>
@ -309,7 +309,7 @@
<th>{{ __('admin::app.catalog.attributes.admin_name') }}</th>
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
<th>{{ $locale->name . ' (' . $locale->code . ')' }}</th>
@ -339,7 +339,7 @@
</div>
</td>
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
<td>
<div class="control-group" :class="[errors.has(localeInputName(row, '{{ $locale->code }}')) ? 'has-error' : '']">
<input type="text" v-validate="'{{ app()->getLocale() }}' == '{{ $locale->code }}' ? 'required': ''" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control" data-vv-as="&quot;{{ $locale->name . ' (' . $locale->code . ')' }}&quot;"/>
@ -397,7 +397,7 @@
'swatch_value_url': '{{ $option->swatch_value_url }}'
};
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] }}";
@endforeach
@ -420,7 +420,7 @@
var rowCount = this.optionRowCount++;
var row = {'id': 'option_' + rowCount};
@foreach (Webkul\Core\Models\Locale::all() as $locale)
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
row['{{ $locale->code }}'] = '';
@endforeach

View File

@ -142,7 +142,7 @@
@include ($view)
@endforeach
</div>
</form>

View File

@ -1,5 +1,5 @@
@if ($product[$attribute->code])
<a href="{{ Storage::url($product[$attribute->code]) }}" target="_blank">
<a href="{{ route('admin.catalog.products.file.download', [$product->product_id, $attribute->id] )}}" target="_blank">
<i class="icon sort-down-icon download"></i>
</a>
@endif

View File

@ -1,5 +1,5 @@
@if ($product[$attribute->code])
<a href="{{ Storage::url($product[$attribute->code]) }}" target="_blank">
<a href="{{ route('admin.catalog.products.file.download', [$product->product_id, $attribute->id] )}}">
<img src="{{ Storage::url($product[$attribute->code]) }}" class="configuration-image"/>
</a>
@endif

View File

@ -12,6 +12,13 @@
</div>
<div class="page-action">
<div class="export-import" @click="showModal('downloadDataGrid')">
<i class="export-icon"></i>
<span >
{{ __('admin::app.export.export') }}
</span>
</div>
<a href="{{ route('admin.catalog.products.create') }}" class="btn btn-lg btn-primary">
{{ __('admin::app.catalog.products.add-product-btn-title') }}
</a>
@ -28,4 +35,15 @@
{!! view_render_event('bagisto.admin.catalog.products.list.after') !!}
</div>
@stop
<modal id="downloadDataGrid" :is-open="modalIds.downloadDataGrid">
<h3 slot="header">{{ __('admin::app.export.download') }}</h3>
<div slot="body">
<export-form></export-form>
</div>
</modal>
@stop
@push('scripts')
@include('admin::export.export', ['gridName' => $products])
@endpush

View File

@ -35,209 +35,263 @@
}
?>
<div class="control-group {{ $field['type'] }}" @if ($field['type'] == 'multiselect') :class="[errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][]') ? 'has-error' : '']" @else :class="[errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]') ? 'has-error' : '']" @endif>
@if ($field['type'] == 'depands')
<label for="{{ $name }}" {{ !isset($field['validation']) || strpos('required', $field['validation']) === false ? '' : 'class=required' }}>
<?php
{{ trans($field['title']) }}
$depands = explode(":", $field['depand']);
$depandField = current($depands);
$depandValue = end($depands);
@if (count($channel_locale))
<span class="locale">[{{ implode(' - ', $channel_locale) }}]</span>
@endif
if (count($channel_locale)) {
$channel_locale = implode(' - ', $channel_locale);
} else {
$channel_locale = '';
}
</label>
if (isset($value) && $value) {
$i = 0;
foreach ($value as $key => $result) {
$data['title'] = $result;
$data['value'] = $key;
$options[$i] = $data;
$i++;
}
$field['options'] = $options;
}
@if ($field['type'] == 'text')
if (! isset($field['options'])) {
$field['options'] = [['title' => 'No', 'value' => 0],['title' => 'Yes', 'value' => 1]];
}
<input type="text" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;">
$selectedOption = core()->getConfigData($name) ?? '';
?>
@elseif ($field['type'] == 'password')
<depands
:options = '@json($field['options'])'
:name = "'{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]'"
:validations = "'{{ $validations }}'"
:depand = "'{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $depandField }}]'"
:value = "'{{ $depandValue }}'"
:field_name = "'{{ $field['title'] }}'"
:channel_loacle = "'{{ $channel_locale }}'"
:result = "'{{ $selectedOption }}'"
></depands>
<input type="password" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;">
@else
@elseif ($field['type'] == 'textarea')
<div class="control-group {{ $field['type'] }}" @if ($field['type'] == 'multiselect') :class="[errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][]') ? 'has-error' : '']" @else :class="[errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]') ? 'has-error' : '']" @endif>
<textarea v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ $field['name'] }}&quot;">{{ old($name) ?: core()->getConfigData($name) }}</textarea>
<label for="{{ $name }}" {{ !isset($field['validation']) || strpos('required', $field['validation']) === false ? '' : 'class=required' }}>
@elseif ($field['type'] == 'select')
{{ trans($field['title']) }}
<select v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ $field['name'] }}&quot;" >
<?php
$selectedOption = core()->getConfigData($name) ?? '';
?>
@if (isset($field['repository']))
@foreach ($value as $key => $option)
<option value="{{ $key }}" {{ $key == $selectedOption ? 'selected' : ''}}>
{{ trans($option) }}
</option>
@endforeach
@else
@foreach ($field['options'] as $option)
<?php
if ($option['value'] == false) {
$value = 0;
} else {
$value = $option['value'];
}
?>
<option value="{{ $value }}" {{ $value == $selectedOption ? 'selected' : ''}}>
{{ trans($option['title']) }}
</option>
@endforeach
@if (count($channel_locale))
<span class="locale">[{{ implode(' - ', $channel_locale) }}]</span>
@endif
</select>
</label>
@elseif ($field['type'] == 'multiselect')
@if ($field['type'] == 'text')
<select v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][]" data-vv-as="&quot;{{ $field['name'] }}&quot;" multiple>
<input type="text" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;">
@elseif ($field['type'] == 'password')
<input type="password" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;">
@elseif ($field['type'] == 'textarea')
<textarea v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ $field['name'] }}&quot;">{{ old($name) ?: core()->getConfigData($name) }}</textarea>
@elseif ($field['type'] == 'select')
<select v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ $field['name'] }}&quot;" >
<?php
$selectedOption = core()->getConfigData($name) ?? '';
?>
@if (isset($field['repository']))
@foreach ($value as $key => $option)
<option value="{{ $key }}" {{ $key == $selectedOption ? 'selected' : ''}}>
{{ trans($option) }}
</option>
@endforeach
@else
@foreach ($field['options'] as $option)
<?php
if ($option['value'] == false) {
$value = 0;
} else {
$value = $option['value'];
}
?>
<option value="{{ $value }}" {{ $value == $selectedOption ? 'selected' : ''}}>
{{ trans($option['title']) }}
</option>
@endforeach
@endif
</select>
@elseif ($field['type'] == 'multiselect')
<select v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][]" data-vv-as="&quot;{{ $field['name'] }}&quot;" multiple>
<?php
$selectedOption = core()->getConfigData($name) ?? '';
?>
@if (isset($field['repository']))
@foreach ($value as $key => $option)
<option value="{{ $key }}" {{ in_array($key, explode(',', $selectedOption)) ? 'selected' : ''}}>
{{ trans($value[$key]) }}
</option>
@endforeach
@else
@foreach ($field['options'] as $option)
<?php
if ($option['value'] == false) {
$value = 0;
} else {
$value = $option['value'];
}
?>
<option value="{{ $value }}" {{ in_array($option['value'], explode(',', $selectedOption)) ? 'selected' : ''}}>
{{ $option['title'] }}
</option>
@endforeach
@endif
</select>
@elseif ($field['type'] == 'country')
<?php
$selectedOption = core()->getConfigData($name) ?? '';
$countryCode = core()->getConfigData($name) ?? '';
?>
@if (isset($field['repository']))
@foreach ($value as $key => $option)
<country
:country_code = "'{{ $countryCode }}'"
:validations = "'{{ $validations }}'"
:name = "'{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]'"
></country>
<option value="{{ $key }}" {{ in_array($key, explode(',', $selectedOption)) ? 'selected' : ''}}>
{{ trans($value[$key]) }}
</option>
@elseif ($field['type'] == 'state')
@endforeach
@else
@foreach ($field['options'] as $option)
<?php
if ($option['value'] == false) {
$value = 0;
} else {
$value = $option['value'];
}
?>
<?php
$stateCode = core()->getConfigData($name) ?? '';
?>
<option value="{{ $value }}" {{ in_array($option['value'], explode(',', $selectedOption)) ? 'selected' : ''}}>
{{ $option['title'] }}
</option>
@endforeach
<state
:state_code = "'{{ $stateCode }}'"
:validations = "'{{ $validations }}'"
:name = "'{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]'"
></state>
@elseif ($field['type'] == 'boolean')
<select v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ $field['name'] }}&quot;">
<?php
$selectedOption = core()->getConfigData($name) ?? '';
?>
<option value="0" {{ $selectedOption ? '' : 'selected'}}>
{{ __('admin::app.configuration.no') }}
</option>
<option value="1" {{ $selectedOption ? 'selected' : ''}}>
{{ __('admin::app.configuration.yes') }}
</option>
</select>
@elseif ($field['type'] == 'image')
<?php
$src = Storage::url(core()->getConfigData($name));
$result = core()->getConfigData($name);
?>
@if ($result)
<a href="{{ $src }}" target="_blank">
<img src="{{ $src }}" class="configuration-image"/>
</a>
@endif
</select>
<input type="file" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;" style="padding-top: 5px;">
@elseif ($field['type'] == 'country')
@if ($result)
<div class="control-group" style="margin-top: 5px;">
<span class="checkbox">
<input type="checkbox" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" value="1">
<?php
$countryCode = core()->getConfigData($name) ?? '';
?>
<label class="checkbox-view" for="delete"></label>
{{ __('admin::app.configuration.delete') }}
</span>
</div>
@endif
<country code = {{ $countryCode }}></country>
@elseif ($field['type'] == 'state')
<?php
$stateCode = core()->getConfigData($name) ?? '';
?>
<state code = {{ $stateCode }}></state>
@elseif ($field['type'] == 'boolean')
<select v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ $field['name'] }}&quot;">
@elseif ($field['type'] == 'file')
<?php
$selectedOption = core()->getConfigData($name) ?? '';
$result = core()->getConfigData($name);
$src = explode("/", $result);
$path = end($src);
?>
<option value="0" {{ $selectedOption ? '' : 'selected'}}>
{{ __('admin::app.configuration.no') }}
</option>
@if ($result)
<a href="{{ route('admin.configuration.download', [request()->route('slug'), request()->route('slug2'), $path]) }}">
<i class="icon sort-down-icon download"></i>
</a>
@endif
<option value="1" {{ $selectedOption ? 'selected' : ''}}>
{{ __('admin::app.configuration.yes') }}
</option>
<input type="file" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;" style="padding-top: 5px;">
</select>
@if ($result)
<div class="control-group" style="margin-top: 5px;">
<span class="checkbox">
<input type="checkbox" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" value="1">
@elseif ($field['type'] == 'image')
<label class="checkbox-view" for="delete"></label>
{{ __('admin::app.configuration.delete') }}
</span>
</div>
@endif
<?php
$src = Storage::url(core()->getConfigData($name));
$result = core()->getConfigData($name);
?>
@if ($result)
<a href="{{ $src }}" target="_blank">
<img src="{{ $src }}" class="configuration-image"/>
</a>
@endif
<input type="file" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;" style="padding-top: 5px;">
@if ($result)
<div class="control-group" style="margin-top: 5px;">
<span class="checkbox">
<input type="checkbox" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" value="1">
<label class="checkbox-view" for="delete"></label>
{{ __('admin::app.configuration.delete') }}
</span>
</div>
@if (isset($field['info']))
<span class="control-info">{{ trans($field['info']) }}</span>
@endif
@elseif ($field['type'] == 'file')
<?php
$result = core()->getConfigData($name);
$src = explode("/", $result);
$path = end($src);
?>
@if ($result)
<a href="{{ route('admin.configuration.download', [request()->route('slug'), request()->route('slug2'), $path]) }}">
<i class="icon sort-down-icon download"></i>
</a>
<span class="control-error" @if ($field['type'] == 'multiselect') v-if="errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][]')" @else v-if="errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]')" @endif
>
@if ($field['type'] == 'multiselect')
@{{ errors.first('{!! $firstField !!}[{!! $secondField !!}][{!! $thirdField !!}][{!! $field['name'] !!}][]') }}
@else
@{{ errors.first('{!! $firstField !!}[{!! $secondField !!}][{!! $thirdField !!}][{!! $field['name'] !!}]') }}
@endif
</span>
<input type="file" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ $field['name'] }}&quot;" style="padding-top: 5px;">
@if ($result)
<div class="control-group" style="margin-top: 5px;">
<span class="checkbox">
<input type="checkbox" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][delete]" value="1">
<label class="checkbox-view" for="delete"></label>
{{ __('admin::app.configuration.delete') }}
</span>
</div>
@endif
@endif
@if (isset($field['info']))
<span class="control-info">{{ trans($field['info']) }}</span>
@endif
<span class="control-error" @if ($field['type'] == 'multiselect') v-if="errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}][]')" @else v-if="errors.has('{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]')" @endif
>
@if ($field['type'] == 'multiselect')
@{{ errors.first('{!! $firstField !!}[{!! $secondField !!}][{!! $thirdField !!}][{!! $field['name'] !!}][]') }}
@else
@{{ errors.first('{!! $firstField !!}[{!! $secondField !!}][{!! $thirdField !!}][{!! $field['name'] !!}]') }}
@endif
</span>
</div>
</div>
@endif
@push('scripts')
<script type="text/x-template" id="country-template">
<div>
<select type="text" v-validate="'required'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][country]" v-model="country" data-vv-as="&quot;{{ __('admin::app.customers.customers.country') }}&quot;" @change="someHandler">
<select type="text" v-validate="validations" class="control" :id="name" :name="name" v-model="country" data-vv-as="&quot;{{ __('admin::app.customers.customers.country') }}&quot;" @change="sendCountryCode">
<option value=""></option>
@foreach (core()->countries() as $country)
@ -257,7 +311,7 @@
inject: ['$validator'],
props: ['code'],
props: ['country_code', 'name', 'validations'],
data: function () {
return {
@ -266,13 +320,13 @@
},
mounted: function () {
this.country = this.code;
this.someHandler()
this.country = this.country_code;
this.sendCountryCode()
},
methods: {
someHandler: function () {
this.$root.$emit('sendCountryCode', this.country)
sendCountryCode: function () {
this.$root.$emit('countryCode', this.country)
},
}
});
@ -281,9 +335,9 @@
<script type="text/x-template" id="state-template">
<div>
<input type="text" v-validate="'required'" v-if="!haveStates()" class="control" v-model="state" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][state]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][state]" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;"/>
<input type="text" v-validate="'required'" v-if="!haveStates()" class="control" v-model="state" :id="name" :name="name" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;"/>
<select v-validate="'required'" v-if="haveStates()" class="control" v-model="state" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][state]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][state]" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;" >
<select v-validate="'required'" v-if="haveStates()" class="control" v-model="state" :id="name" :name="name" data-vv-as="&quot;{{ __('admin::app.customers.customers.state') }}&quot;" >
<option value="">{{ __('admin::app.customers.customers.select-state') }}</option>
@ -304,7 +358,7 @@
inject: ['$validator'],
props: ['code'],
props: ['state_code', 'name', 'validations'],
data: function () {
return {
@ -317,14 +371,14 @@
},
mounted: function () {
this.state = this.code
this.state = this.state_code
},
methods: {
haveStates: function () {
var this_this = this;
this_this.$root.$on('sendCountryCode', function (country) {
this_this.$root.$on('countryCode', function (country) {
this_this.country = country;
});
@ -337,4 +391,75 @@
});
</script>
<script type="text/x-template" id="depands-template">
<div class="control-group" :class="[errors.has(name) ? 'has-error' : '']" v-if="this.isVisible">
<label :for="name" :class="[ isRequire ? 'required' : '']">
@{{ field_name }}
<span class="locale"> [@{{ channel_loacle }}] </span>
</label>
<select v-validate= "validations" class="control" :id = "name" :name = "name" v-model="this.result"
:data-vv-as="field_name">
<option v-for='(option, index) in this.options' :value="option.value"> @{{ option.title }} </option>
</select>
<span class="control-error" v-if="errors.has(name)">
@{{ errors.first(name) }}
</span>
</div>
</script>
<script>
Vue.component('depands', {
template: '#depands-template',
inject: ['$validator'],
props: ['options', 'name', 'validations', 'depand', 'value', 'field_name', 'channel_loacle', 'repository', 'result'],
data: function() {
return {
isVisible: false,
isRequire: false,
}
},
created: function () {
var this_this = this;
if (this_this.validations || (this_this.validations.indexOf("required") != -1)) {
this_this.isRequire = true;
}
$(document).ready(function () {
var dependentElement = document.getElementById(this_this.depand);
var depandValue = this_this.value;
if (depandValue == 'true') {
depandValue = 1;
} else if (depandValue == 'false') {
depandValue = 0;
}
dependentElement.onchange = function() {
if (dependentElement.value == depandValue) {
this_this.isVisible = true;
} else {
this_this.isVisible = false;
}
}
if (dependentElement.value == depandValue) {
this_this.isVisible = true;
} else {
this_this.isVisible = false;
}
});
}
});
</script>
@endpush

View File

@ -66,7 +66,7 @@
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone">{{ __('admin::app.customers.customers.phone') }}</label>
<input type="text" class="control" name="phone" v-validate="'numeric|max:10'" value="{{ old('phone') }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.phone') }}&quot;">
<input type="text" class="control" name="phone" value="{{ old('phone') }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>

View File

@ -58,12 +58,21 @@
<div class="control-group">
<label for="gender" class="required">{{ __('admin::app.customers.customers.gender') }}</label>
<select name="gender" class="control" value="{{ $customer->gender }}" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customers.customers.gender') }}&quot;">
<option value="Male" {{ $customer->gender == "Male" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.male') }}</option>
<option value="Female" {{ $customer->gender == "Female" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.female') }}</option>
<option value="Male" {{ $customer->gender == "Male" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.male') }}</option>
<option value="Female" {{ $customer->gender == "Female" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.female') }}</option>
</select>
<span class="control-error" v-if="errors.has('gender')">@{{ errors.first('gender') }}</span>
</div>
<div class="control-group">
<label for="status" class="required">{{ __('admin::app.customers.customers.status') }}</label>
<select name="status" class="control" value="{{ $customer->status }}" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.customers.customers.status') }}&quot;">
<option value="1" {{ $customer->status == "1" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.active') }}</option>
<option value="0" {{ $customer->status == "0" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.in-active') }}</option>
</select>
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
</div>
<div class="control-group" :class="[errors.has('date_of_birth') ? 'has-error' : '']">
<label for="dob">{{ __('admin::app.customers.customers.date_of_birth') }}</label>
<input type="date" class="control" name="date_of_birth" value="{{ $customer->date_of_birth }}" v-validate="" data-vv-as="&quot;{{ __('admin::app.customers.customers.date_of_birth') }}&quot;">
@ -72,7 +81,7 @@
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone">{{ __('admin::app.customers.customers.phone') }}</label>
<input type="text" class="control" name="phone" v-validate="'numeric|max:10'" value="{{ $customer->phone }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.phone') }}&quot;">
<input type="text" class="control" name="phone" value="{{ $customer->phone }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>

View File

@ -34,7 +34,7 @@
<div class="control-group" :class="[errors.has('channel_id') ? 'has-error' : '']">
<label for="notes">{{ __('admin::app.customers.note.enter-note') }} for {{ $customer->name }}</label>
<textarea class="control" name="notes" v-validate="'required'">{{ $customer->notes }}</textarea>
<textarea class="control" name="notes">{{ $customer->notes }}</textarea>
<span class="control-error" v-if="errors.has('notes')">@{{ errors.first('notes') }}</span>
</div>

View File

@ -3,9 +3,9 @@
@foreach ($menu->items as $menuItem)
<li class="menu-item {{ $menu->getActive($menuItem) }}">
<a href="{{ count($menuItem['children']) ? current($menuItem['children'])['url'] : $menuItem['url'] }}">
<span class="icon {{ $menuItem['icon-class'] }}">
</span>
{{ trans($menuItem['name']) }}
<span class="icon {{ $menuItem['icon-class'] }}"></span>
<span>{{ trans($menuItem['name']) }}</span>
</a>
</li>
@endforeach

View File

@ -12,7 +12,7 @@
@push('scripts')
<script type="text/x-template" id="cart-rule-form-template">
<form method="POST" action="{{ route('admin.cart-rule.store') }}" @submit.prevent="onSubmit">
<form method="POST" action="{{ route('admin.cart-rule.store') }}" @submit.prevent="onSubmit" autocomplete="off">
@csrf
<div class="page-header">
@ -84,7 +84,7 @@
@endforeach
</select>
<span class="control-error" v-if="errors.has('customer_groups')">@{{ errors.first('customer_groups') }}</span>
<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' : '']">
@ -142,17 +142,6 @@
<span class="control-error" v-if="errors.has('per_customer')">@{{ errors.first('per_customer') }}</span>
</div> --}}
<div class="control-group" :class="[errors.has('is_guest') ? 'has-error' : '']">
<label for="is_guest" class="required">{{ __('admin::app.promotion.general-info.is-guest') }}</label>
<select type="text" class="control" name="is_guest" v-model="is_guest" v-validate="'required'" value="{{ old('is_guest')}}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.is-guest') }}&quot;">
<option value="1" :selected="is_guest == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="0" :selected="is_guest == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('is_guest')">@{{ errors.first('is_guest') }}</span>
</div>
{{-- <div class="control-group" :class="[errors.has('usage_limit') ? 'has-error' : '']">
<label for="usage_limit" class="required">{{ __('admin::app.promotion.general-info.limit') }}</label>
@ -175,7 +164,7 @@
<div slot="body">
<input type="hidden" name="all_conditions" v-model="all_conditions">
<div class="add-condition">
{{-- <div class="add-condition">
<div class="control-group">
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
@ -183,7 +172,7 @@
<option value="cart">Cart Properties</option>
</select>
</div>
</div>
</div> --}}
<div class="control-group">
{{ __('admin::app.promotion.general-info.test-mode') }}
@ -198,52 +187,45 @@
<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-container mt-20" v-for="(condition, index) in conditions_list" :key="index">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" title="You Can Make Multiple Selections Here" style="margin-right: 15px; width: 30%;" 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 class="control-group mt-10" :key="index">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" 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 v-if='conditions_list[index].type == "string"' style="display: flex">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.string" :value="index" :key="index">@{{ condition }}</option>
</select>
<div v-if='conditions_list[index].attribute == "shipping_state"'>
<select class="control" 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 v-if='conditions_list[index].type == "string"'>
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.string" :value="index" :key="index">@{{ condition }}</option>
</select>
<div v-if='conditions_list[index].attribute == "shipping_state"'>
<select class="control" 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-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" 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 v-if='conditions_list[index].attribute == "shipping_country"'>
<select class="control" 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 class="control" type="text" 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"' style="display: flex">
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
</select>
<input class="control" type="number" step="0.1000" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
</div>
<span class="icon trash-icon" v-on:click="removeCartAttr(index)"></span>
</div>
</div>
@ -254,9 +236,9 @@
<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>
<label for="action_type" class="required">{{ __('admin::app.promotion.general-info.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">
<select class="control" name="action_type" v-model="action_type" v-validate="'required'" value="{{ old('action_type') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.apply') }}&quot;" v-on:change="detectApply">
<option v-for="(action, index) in actions" :value="index">@{{ action }}</option>
</select>
@ -292,9 +274,9 @@
<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">{{ __('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>
<option value="0">{{ __('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>
@ -304,9 +286,9 @@
<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 == 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>
<option value="0" :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>
@ -359,7 +341,7 @@
</div>
</accordian>
<accordian :active="false" title="labels">
<accordian :active="false" :title="'{{ __('admin::app.promotion.general-info.labels') }}'">
<div slot="body">
<div class="control-group" :class="[errors.has('label') ? 'has-error' : '']" v-if="dedicated_label">
<label for="label">Global Label</label>
@ -371,10 +353,9 @@
<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>
<label for="code"><span class="locale">[{{ $channel->code }} - {{ $locale->code }}]</span></label>
<input type="text" class="control" name="label[{{ $channel->code }}][{{ $locale->code }}]" v-model="label.{{ $channel->code }}.{{ $locale->code }}" data-vv-as="&quot;Label&quot;">
@ -412,19 +393,18 @@
use_coupon: null,
auto_generation: false,
usage_limit: 0,
is_guest: 0,
action_type: null,
apply: null,
apply_amt: false,
apply_prct: false,
apply_to_shipping: null,
apply_to_shipping: 0,
disc_amount: null,
disc_threshold: null,
disc_quantity: null,
end_other_rules: null,
end_other_rules: 0,
coupon_type: null,
free_shipping: null,
free_shipping: 0,
all_conditions: [],
match_criteria: 'all_are_true',
@ -445,7 +425,7 @@
@endforeach
},
criteria: null,
criteria: 'cart',
conditions: @json($cart_rule[0]).conditions,
cart_input: @json($cart_rule[0]).attributes,
actions: @json($cart_rule[0]).actions,

View File

@ -26,7 +26,7 @@
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.promotion.edit-btn-title') }}
{{ __('admin::app.promotion.save') }}
</button>
</div>
</div>
@ -144,7 +144,7 @@
<span class="control-error" v-if="errors.has('per_customer')">@{{ errors.first('per_customer') }}</span>
</div> --}}
<div class="control-group" :class="[errors.has('is_guest') ? 'has-error' : '']">
{{-- <div class="control-group" :class="[errors.has('is_guest') ? 'has-error' : '']">
<label for="is_guest" class="required">{{ __('admin::app.promotion.general-info.is-guest') }}</label>
<select type="text" class="control" name="is_guest" v-model="is_guest" v-validate="'required'" value="{{ old('is_guest')}}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.is-guest') }}&quot;">
@ -153,7 +153,7 @@
</select>
<span class="control-error" v-if="errors.has('is_guest')">@{{ errors.first('is_guest') }}</span>
</div>
</div> --}}
{{-- <div class="control-group" :class="[errors.has('usage_limit') ? 'has-error' : '']">
<label for="usage_limit" class="required">{{ __('admin::app.promotion.general-info.limit') }}</label>
@ -175,7 +175,9 @@
<accordian :active="false" title="Conditions">
<div slot="body">
<div class="add-condition">
<input type="hidden" name="all_conditions" v-model="all_conditions">
{{-- <div class="add-condition">
<div class="control-group">
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
@ -183,11 +185,11 @@
<option value="cart">Cart Properties</option>
</select>
</div>
</div>
</div> --}}
<div class="control-group">
{{ __('admin::app.promotion.general-info.test-mode') }}
<select class="control" v-model="match_criteria" name="match_criteria" style="margin-right: 15px;">
<select class="control" v-model="match_criteria" style="margin-right: 15px;">
{{ $i = 0 }}
@foreach(config('pricerules.test_mode') as $key => $value)
<option value="{{ $key }}">{{ $value }}</option>
@ -198,52 +200,45 @@
<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-container mt-20" v-for="(condition, index) in conditions_list" :key="index">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" title="You Can Make Multiple Selections Here" style="margin-right: 15px; width: 30%;" 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 class="control-group mt-10" :key="index">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" 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 v-if='conditions_list[index].type == "string"' style="display: flex">
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.string" :value="index" :key="index">@{{ condition }}</option>
</select>
<div v-if='conditions_list[index].attribute == "shipping_state"'>
<select class="control" 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 v-if='conditions_list[index].type == "string"'>
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.string" :value="index" :key="index">@{{ condition }}</option>
</select>
<div v-if='conditions_list[index].attribute == "shipping_state"'>
<select class="control" 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-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" 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 v-if='conditions_list[index].attribute == "shipping_country"'>
<select class="control" 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 class="control" type="text" 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"' style="display: flex">
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
</select>
<input class="control" type="number" step="0.1000" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
</div>
<span class="icon trash-icon" v-on:click="removeCartAttr(index)"></span>
</div>
</div>
@ -292,21 +287,21 @@
<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">{{ __('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>
<option value="0">{{ __('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>
<label for="apply_to_shipping" 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">{{ __('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>
<option value="0">{{ __('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>
@ -358,7 +353,7 @@
</div>
</accordian>
<accordian :active="false" title="labels">
<accordian :active="false" :title="'{{ __('admin::app.promotion.general-info.labels') }}'">
<div slot="body">
@foreach($cart_rule[3]->labels as $label)
<span>[{{ $label->channel->code }}]</span>
@ -398,7 +393,6 @@
use_coupon: null,
// auto_generation: 0,
usage_limit: 0,
is_guest: 0,
action_type: null,
apply: null,
@ -431,7 +425,7 @@
// @endforeach
// },
criteria: null,
criteria: 'cart',
conditions: @json($cart_rule[0]).conditions,
cart_input: @json($cart_rule[0]).attributes,
actions: @json($cart_rule[0]).actions,

View File

@ -147,7 +147,7 @@
<td>
{{ core()->getConfigData('sales.paymentmethods.' . $invoice->order->payment->method . '.title') }}
</td>
<td>
{{ $invoice->order->shipping_title }}
</td>

View File

@ -252,7 +252,7 @@
<td>
{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}
</td>
<td>
{{ $item->name }}
@ -305,7 +305,7 @@
<td>-</td>
<td>{{ core()->formatBasePrice($order->base_sub_total) }}</td>
</tr>
@if ($order->haveStockableItems())
<tr>
<td>{{ __('admin::app.sales.orders.shipping-handling') }}</td>

View File

@ -648,12 +648,12 @@ class Cart {
$option = $attribute->options()->where('id', $product->{$attribute->code})->first();
$data['attributes'][$attribute->code] = [
'attribute_name' => $attribute->name,
'attribute_name' => $attribute->name ? $attribute->name : $attribute->admin_name,
'option_id' => $option->id,
'option_label' => $option->label,
];
$labels[] = $attribute->name . ' : ' . $option->label;
$labels[] = ($attribute->name ? $attribute->name : $attribute->admin_name) . ' : ' . $option->label;
}
$data['html'] = implode(', ', $labels);
@ -1102,7 +1102,9 @@ class Cart {
'base_sub_total' => $data['base_sub_total'],
'tax_amount' => $data['tax_total'],
'base_tax_amount' => $data['base_tax_total'],
'discount_amount' => $data['discount_amount'],
'base_discount_amount' => $data['base_discount_amount'],
'billing_address' => array_except($data['billing_address'], ['id', 'cart_id']),
'payment' => array_except($data['payment'], ['id', 'cart_id']),
@ -1167,7 +1169,8 @@ class Cart {
*
* Move a wishlist item to cart
*/
public function moveToCart($wishlistItem) {
public function moveToCart($wishlistItem)
{
$product = $wishlistItem->product;
if ($product->type == 'simple') {

View File

@ -7,6 +7,8 @@ use Webkul\Checkout\Contracts\CartShippingRate as CartShippingRateContract;
class CartShippingRate extends Model implements CartShippingRateContract
{
protected $fillable = ['carrier', 'carrier_title', 'method', 'method_title', 'method_description', 'price', 'base_price'];
/**
* Get the post that owns the comment.
*/

View File

@ -14,7 +14,9 @@ class AddPhoneColumnInCustomersTable extends Migration
public function up()
{
Schema::table('customers', function (Blueprint $table) {
$table->string('phone')->unique()->nullable();
if (! Schema::hasColumn('customers', 'phone')) {
$table->string('phone')->unique()->nullable();
}
});
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveUniqueInPhoneColumnInCustomersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('customers', function (Blueprint $table) {
if ( Schema::hasColumn('customers', 'phone')) {
$table->dropUnique('customers_phone_unique');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customers', function (Blueprint $table) {
//
});
}
}

View File

@ -19,6 +19,13 @@ class RedirectIfNotCustomer
{
if (! Auth::guard($guard)->check()) {
return redirect()->route('customer.session.index');
} else {
if (Auth::guard($guard)->user()->status == 0) {
Auth::guard($guard)->logout();
session()->flash('warning', trans('shop::app.customer.login-form.not-activated'));
return redirect()->route('customer.session.index');
}
}
return $next($request);

View File

@ -5,4 +5,6 @@ namespace Webkul\Discount\Actions;
abstract class Action
{
abstract public function calculate($rule, $item, $cart);
abstract public function calculateOnShipping($cart);
}

View File

@ -23,16 +23,30 @@ class BuyAGetB extends Action
if ($realQty > $disc_quantity) {
$amountDiscounted = $amountDiscounted * $disc_quantity;
} else {
$amountDiscounted = $amountDiscounted * $realQty;
}
if ($amountDiscounted > $item['price']) {
$amountDiscounted = $item['price'];
if ($amountDiscounted > $item['base_price'] && $realQty == 1) {
$amountDiscounted = $item['base_price'];
}
}
$report['discount'] = $amountDiscounted;
$report['formatted_discount'] = core()->formatPrice($amountDiscounted, $cart->cart_currency_code);
$report['formatted_discount'] = core()->currency($amountDiscounted);
return $report;
}
/**
* Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled
*/
public function calculateOnShipping($cart)
{
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
$discountOnShipping = ($percentOfDiscount / 100) * $cart->selected_shipping_rate->base_price;
return $discountOnShipping;
}
}

View File

@ -8,7 +8,7 @@ class FixedAmount extends Action
{
public function calculate($rule, $item, $cart)
{
//calculate discount amount
// calculate discount amount
$action_type = $rule->action_type; // action type used
$disc_threshold = $rule->disc_threshold; // atleast quantity by default 1 --> may be omitted in near future
$disc_amount = $rule->disc_amount; // value of discount
@ -18,21 +18,35 @@ class FixedAmount extends Action
$realQty = $item['quantity'];
if ($cart >= $disc_threshold) {
if ($cart->items_qty >= $disc_threshold) {
$amountDiscounted = $disc_amount;
if ($realQty > $disc_quantity) {
$amountDiscounted = $amountDiscounted * $disc_quantity;
} else {
$amountDiscounted = $amountDiscounted * $realQty;
}
if ($amountDiscounted > $item['price']) {
$amountDiscounted = $item['price'];
if ($amountDiscounted > $item['base_price'] && $realQty == 1) {
$amountDiscounted = $item['base_price'];
}
}
$report['discount'] = $amountDiscounted;
$report['formatted_discount'] = core()->formatPrice($amountDiscounted, $cart->cart_currency_code);
$report['formatted_discount'] = core()->currency($amountDiscounted);
return $report;
}
/**
* Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled
*/
public function calculateOnShipping($cart)
{
$cart = \Cart::getCart();
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
return $percentOfDiscount;
}
}

View File

@ -15,21 +15,35 @@ class PercentOfProduct extends Action
$realQty = $item['quantity'];
if ($cart >= $disc_threshold) {
$amountDiscounted = $item['price'] * ($disc_amount / 100);
if ($cart->items_qty >= $disc_threshold) {
$amountDiscounted = $item['base_price'] * ($disc_amount / 100);
if ($realQty > $disc_quantity) {
$amountDiscounted = $amountDiscounted * $disc_quantity;
} else {
$amountDiscounted = $amountDiscounted * $realQty;
}
if ($amountDiscounted > $item['price']) {
$amountDiscounted = $item['price'];
if ($amountDiscounted > $item['base_price'] && $realQty == 1) {
$amountDiscounted = $item['base_price'];
}
}
$report['discount'] = $amountDiscounted;
$report['formatted_discount'] = core()->formatPrice($amountDiscounted, $cart->cart_currency_code);
$report['formatted_discount'] = core()->currency($amountDiscounted);
return $report;
}
/**
* Calculates the impact on the shipping amount if the rule is apply_to_shipping enabled
*/
public function calculateOnShipping($cart)
{
$cart = \Cart::getCart();
$percentOfDiscount = ($cart->base_discount_amount * 100) / $cart->base_grand_total;
return $percentOfDiscount;
}
}

View File

@ -34,8 +34,7 @@ return [
'actions' => [
'percent_of_product' => 'Percentage of product',
'fixed_amount' => 'Apply as fixed amount',
'buy_a_get_b' => 'Get B amount back',
'fixed_amount_cart' => 'Whole cart gets discounted'
// 'buy_a_get_b' => 'Buy A get B'
],
'validation' => [

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveIsGuestFromCartRulesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('cart_rules', function (Blueprint $table) {
$table->dropColumn('is_guest');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('cart_rules', function (Blueprint $table) {
$table->boolean('is_guest')->default(0);
});
}
}

View File

@ -18,18 +18,10 @@ class CouponAbleRule extends Discount
{
$cart = Cart::getCart();
if (auth()->guard('customer')->check()) {
$rules = $this->cartRule->findWhere([
'use_coupon' => 1,
'status' => 1
]);
} else {
$rules = $this->cartRule->findWhere([
'use_coupon' => 1,
'is_guest' => 1,
'status' => 1
]);
}
$rules = $this->cartRule->findWhere([
'use_coupon' => 1,
'status' => 1
]);
$applicableRule = null;
@ -41,6 +33,10 @@ class CouponAbleRule extends Discount
}
}
if (! isset($applicableRule)) {
return false;
}
$applicability = $this->checkApplicability($applicableRule);
if ($applicability) {
@ -50,15 +46,22 @@ class CouponAbleRule extends Discount
$impact = $actionInstance->calculate($applicableRule, $item, $cart);
if ($impact['discount'] == 0) {
return false;
}
// avoid applying the same rule
$ifAlreadyApplied = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id,
'cart_rule_id' => $applicableRule->id
]);
if ($ifAlreadyApplied->count() == 1) {
// can give a message that coupon is already applied
return false;
}
// if the rule ain't same
$ifAlreadyApplied = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id,
]);
@ -69,35 +72,43 @@ class CouponAbleRule extends Discount
return $impact;
}
$alreadyAppliedRule = $ifAlreadyApplied->first()->cart_rule;
if ($alreadyAppliedRule->priority < $rule->priority) {
// the only case where a non couponable rule defeats couponable rule
if ($ifAlreadyApplied->first()->cart_rule->use_coupon == 0 && $ifAlreadyApplied->first()->cart_rule->end_other_rules == 1) {
return false;
} else if ($alreadyAppliedRule->priority == $applicableRule->priority) {
// tie breaker case
}
// end other rules
if ($alreadyAppliedRule->end_other_rules) {
if ($ifAlreadyApplied->first()->cart_rule->use_coupon == 1 && $ifAlreadyApplied->first()->cart_rule->end_other_rules == 1) {
return false;
}
if ($ifAlreadyApplied->first()->cart_rule->use_coupon == 1) {
$alreadyAppliedRule = $ifAlreadyApplied->first()->cart_rule;
if ($alreadyAppliedRule->priority < $applicableRule->priority) {
return false;
}
} else if ($alreadyAppliedRule->priority == $applicableRule->priority) {
$actionInstance = new $this->rules[$alreadyAppliedRule->action_type];
$actionInstance = new $this->rules[$alreadyAppliedRule->action_type];
$alreadyAppliedRuleImpact = $actionInstance->calculate($alreadyAppliedRule, $item, $cart);
$alreadyAppliedRuleImpact = $actionInstance->calculate($alreadyAppliedRule, $item, $cart);
if ($alreadyAppliedRule['discount'] > $impact['discount']) {
return false;
} else if ($alreadyAppliedRule['discount'] < $impact['discount']) {
$this->save($applicableRule);
return $impact;
} else {
// least id case
if ($applicableRule->id < $alreadyAppliedRule->id) {
if ($alreadyAppliedRule['discount'] > $impact['discount']) {
return false;
} else if ($alreadyAppliedRule['discount'] < $impact['discount']) {
$this->save($applicableRule);
return $impact;
} else {
// least id case
if ($applicableRule->id < $alreadyAppliedRule->id) {
$this->save($applicableRule);
return $impact;
}
}
} else {
$this->save($applicableRule);
return $impact;
}
} else {
$this->save($applicableRule);
@ -123,32 +134,30 @@ class CouponAbleRule extends Discount
]);
if ($existingRule->count()) {
if ($existingRule->first()->cart_rule->use_coupon) {
$existingRule->first()->delete();
$existingRule->first()->delete();
foreach ($cart->items as $item) {
if ($item->discount_amount > 0) {
$item->update([
'discount_amount' => 0,
'base_discount_amount' => 0,
'discount_percent' => 0,
'coupon_code' => NULL
]);
}
$this->resetShipping($cart);
foreach ($cart->items as $item) {
if ($item->discount_amount > 0) {
$item->update([
'discount_amount' => 0,
'base_discount_amount' => 0,
'discount_percent' => 0,
'coupon_code' => NULL
]);
}
$cart->update([
'coupon_code' => NULL,
'discount_amount' => 0,
'base_discount_amount' => 0
]);
Cart::collectTotals();
return true;
} else {
return false;
}
$cart->update([
'coupon_code' => NULL,
'discount_amount' => 0,
'base_discount_amount' => 0
]);
Cart::collectTotals();
return true;
} else {
return false;
}

View File

@ -29,11 +29,6 @@ abstract class Discount
*/
protected $rules;
/**
* disable coupon
*/
protected $disableCoupon = false;
public function __construct(CartRule $cartRule, CartRuleCart $cartRuleCart)
{
$this->cartRule = $cartRule;
@ -90,13 +85,17 @@ abstract class Discount
// customer groups based constraints
if (auth()->guard('customer')->check()) {
foreach ($rule->customer_groups as $customer_group) {
if ($customer_group->customer_group_id == auth()->guard('customer')->user()->group->id) {
$customerGroupBased = true;
if (auth()->guard('customer')->user()->group->exists()) {
if ($customer_group->customer_group_id == auth()->guard('customer')->user()->group->id) {
$customerGroupBased = true;
}
}
}
} else {
if ($rule->is_guest) {
$customerGroupBased = true;
foreach ($rule->customer_groups as $customer_group) {
if ($customer_group->customer_group->code == 'guest') {
$customerGroupBased = true;
}
}
}
@ -133,39 +132,153 @@ abstract class Discount
{
$cart = \Cart::getCart();
// create or update
// Create or update
$existingRule = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id
]);
if (count($existingRule)) {
// $this->clearDiscount();
if ($rule->use_coupon) {
$this->resetShipping($cart);
}
if (count($existingRule)) {
if ($existingRule->first()->cart_rule_id != $rule->id) {
$existingRule->first()->update([
'cart_rule_id' => $rule->id
]);
$this->clearDiscount();
$this->updateCartItemAndCart($rule);
if ($rule->use_coupon) {
$this->checkOnShipping($cart);
}
return true;
} else {
// $this->checkOnShipping($cart);
}
} else {
// $this->clearDiscount();
$this->cartRuleCart->create([
'cart_id' => $cart->id,
'cart_rule_id' => $rule->id
]);
$this->clearDiscount();
$this->updateCartItemAndCart($rule);
if ($rule->use_coupon) {
$this->checkOnShipping($cart);
}
return true;
}
return false;
}
/**
* Checks whether rule is getting applied on shipping or not
*/
public function checkOnShipping($cart)
{
if (! isset($cart->selected_shipping_rate)) {
return false;
}
$shippingRate = config('carriers')[$cart->selected_shipping_rate->carrier]['class'];
$actualShippingRate = new $shippingRate;
$actualShippingRate = $actualShippingRate->calculate();
$actualShippingPrice = $actualShippingRate->price;
$actualShippingBasePrice = $actualShippingRate->base_price;
$alreadyAppliedCartRuleCart = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id
]);
if (count($alreadyAppliedCartRuleCart)) {
$this->resetShipping($cart);
$alreadyAppliedRule = $alreadyAppliedCartRuleCart->first()->cart_rule;
$cartShippingRate = $cart->selected_shipping_rate;
if (isset($cartShippingRate)) {
if ($cartShippingRate->base_price < $actualShippingBasePrice) {
return false;
} else {
$this->applyOnShipping($alreadyAppliedRule, $cart);
}
} else {
$this->applyOnShipping($alreadyAppliedRule, $cart);
}
} else {
$this->resetShipping($cart);
}
}
/**
* Apply on shipping
*
* @return void
*/
public function applyOnShipping($appliedRule, $cart)
{
$cart = \Cart::getCart();
if (isset($cart->selected_shipping_rate)) {
if ($appliedRule->free_shipping && $cart->selected_shipping_rate->base_price > 0) {
$cart->selected_shipping_rate->update([
'price' => 0,
'base_price' => 0
]);
} else if ($appliedRule->free_shipping == 0 && $appliedRule->apply_to_shipping && $cart->selected_shipping_rate->base_price > 0) {
$actionType = config('discount-rules')[$appliedRule->action_type];
if ($appliedRule->apply_to_shipping) {
$actionInstance = new $actionType;
$discountOnShipping = $actionInstance->calculateOnShipping($cart);
$discountOnShipping = ($discountOnShipping / 100) * $cart->selected_shipping_rate->base_price;
$cart->selected_shipping_rate->update([
'price' => $cart->selected_shipping_rate->price - core()->convertPrice($discountOnShipping, $cart->cart_currency_code),
'base_price' => $cart->selected_shipping_rate->base_price - $discountOnShipping
]);
}
}
}
}
/**
* Resets the shipping for the current items in the cart
*
* @return void
*/
public function resetShipping($cart)
{
$cart = \Cart::getCart();
if (isset($cart->selected_shipping_rate->carrier)) {
$shippingRate = config('carriers')[$cart->selected_shipping_rate->carrier]['class'];
$actualShippingRate = new $shippingRate;
$actualShippingRate = $actualShippingRate->calculate();
$actualShippingPrice = $actualShippingRate->price;
$actualShippingBasePrice = $actualShippingRate->base_price;
$cartShippingRate = $cart->selected_shipping_rate;
$cartShippingRate->update([
'price' => $actualShippingPrice,
'base_price' => $actualShippingBasePrice
]);
}
}
/**
* Removes any cart rule from the current cart instance
*
@ -195,6 +308,56 @@ abstract class Discount
return true;
}
/**
* Update discount for least worth item
*/
public function updateCartItemAndCart($rule)
{
$cart = Cart::getCart();
$leastWorthItem = $this->leastWorthItem();
$actionInstance = new $this->rules[$rule->action_type];
$impact = $actionInstance->calculate($rule, $leastWorthItem, $cart);
foreach ($cart->items as $item) {
if ($item->id == $leastWorthItem['id']) {
if ($rule->action_type == 'percent_of_product') {
$item->update([
'discount_percent' => $rule->discount_amount,
'discount_amount' => core()->convertPrice($impact['discount'], $cart->cart_currency_code),
'base_discount_amount' => $impact['discount']
]);
} else {
$item->update([
'discount_amount' => core()->convertPrice($impact['discount'], $cart->cart_currency_code),
'base_discount_amount' => $impact['discount']
]);
}
// save coupon if rule use it
if ($rule->use_coupon) {
$coupon = $rule->coupons->code;
$item->update([
'coupon_code' => $coupon
]);
$cart->update([
'coupon_code' => $coupon
]);
}
break;
}
}
Cart::collectTotals();
return true;
}
/**
* To find the least worth item in current cart instance
*
@ -222,60 +385,10 @@ abstract class Discount
return $leastWorthItem;
}
/**
* Update discount for least worth item
*/
public function updateCartItemAndCart($rule)
{
$cart = Cart::getCart();
$leastWorthItem = $this->leastWorthItem();
$actionInstance = new $this->rules[$rule->action_type];
$impact = $actionInstance->calculate($rule, $leastWorthItem, $cart);
foreach ($cart->items as $item) {
if ($item->id == $leastWorthItem['id']) {
if ($rule->action_type == 'percent_of_product') {
$item->update([
'discount_percent' => $rule->discount_amount,
'discount_amount' => $impact['discount'],
'base_discount_amount' => $impact['discount']
]);
} else {
$item->update([
'discount_amount' => $impact['discount'],
'base_discount_amount' => $impact['discount']
]);
}
// save coupon if rule has it
if ($rule->use_coupon) {
$coupon = $rule->coupons->code;
$item->update([
'coupon_code' => $coupon
]);
$cart->update([
'coupon_code' => $coupon
]);
}
break;
}
}
Cart::collectTotals();
return true;
}
/**
* To find the max worth item in current cart instance
*
* @return Array
* @return array
*/
public function maxWorthItem()
{
@ -287,6 +400,7 @@ abstract class Discount
foreach ($cart->items as $item) {
if ($item->base_total > $maxValue) {
$maxValue = $item->total;
$maxWorthItem = [
'id' => $item->id,
'price' => $item->price,
@ -299,6 +413,50 @@ abstract class Discount
return $maxWorthItem;
}
/**
* Validate the currently applied cart rule
*
* @return boolean
*/
public function validateRule($rule)
{
$applicability = $this->checkApplicability($rule);
if ($applicability) {
if ($rule->status) {
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* Retreives all the payment methods from application config
*
* @return array
*/
public function getPaymentMethods()
{
$paymentMethods = config('paymentmethods');
return $paymentMethods;
}
/**
* Retreives all the shippin methods from the application config
*
* @return array
*/
public function getShippingMethods()
{
$shippingMethods = config('carriers');
return $shippingMethods;
}
/**
* Checks the rule against the current cart instance whether rule conditions are applicable
* or not
@ -307,34 +465,71 @@ abstract class Discount
*/
protected function testIfAllConditionAreTrue($conditions, $cart)
{
$paymentMethods = $this->getPaymentMethods();
$shippingMethods = $this->getShippingMethods();
array_pop($conditions);
$shipping_address = $cart->getShippingAddressAttribute() ?? '';
$shipping_address = $cart->getShippingAddressAttribute() ?? null;
$shipping_method = $cart->shipping_method ?? '';
$shipping_country = $shipping_address->country ?? '';
$shipping_state = $shipping_address->state ?? '';
$shipping_postcode = $shipping_address->postcode ?? '';
$shipping_city = $shipping_address->city ?? '';
$shipping_method = $cart->selected_shipping_rate->method_title ?? null;
$shipping_country = $shipping_address->country ?? null;
$shipping_state = $shipping_address->state ?? null;
$shipping_postcode = $shipping_address->postcode ?? null;
$shipping_city = $shipping_address->city ?? null;
if (isset($cart->payment)) {
$payment_method = $paymentMethods[$cart->payment->method]['title'];
} else {
$payment_method = null;
}
$payment_method = $cart->payment->method ?? '';
$sub_total = $cart->base_sub_total;
$total_items = $cart->items_qty;
$total_weight = 0;
foreach($cart->items as $item) {
foreach ($cart->items as $item) {
$total_weight = $total_weight + $item->base_total_weight;
}
$result = true;
foreach ($conditions as $condition) {
$actual_value = ${$condition->attribute};
$test_value = $condition->value;
$test_condition = $condition->condition;
if (isset($condition->attribute)) {
$actual_value = ${$condition->attribute};
} else {
$result = false;
}
if (isset($condition->value)) {
$test_value = $condition->value;
} else {
$result = false;
}
if (isset($condition->condition)) {
$test_condition = $condition->condition;
}
else {
$result = false;
}
if (isset($condition->type) && ($condition->type == 'numeric' || $condition->type == 'string' || $condition->type == 'text')) {
if ($condition->type == 'string') {
$actual_value = strtolower($actual_value);
$test_value = strtolower($test_value);
}
if ($condition->type == 'numeric' || $condition->type == 'string' || $condition->type == 'text') {
if ($test_condition == '=') {
if ($actual_value != $test_value) {
$result = false;
@ -390,23 +585,38 @@ abstract class Discount
*
* @return boolean
*/
protected function testIfAnyConditionIsTrue($conditions, $cart) {
protected function testIfAnyConditionIsTrue($conditions, $cart)
{
$paymentMethods = $this->getPaymentMethods();
$shippingMethods = $this->getShippingMethods();
array_pop($conditions);
$result = false;
$shipping_address = $cart->getShippingAddressAttribute() ?? '';
$shipping_address = $cart->getShippingAddressAttribute() ?? null;
$shipping_method = $cart->shipping_method ?? '';
$shipping_country = $shipping_address->country ?? '';
$shipping_state = $shipping_address->state ?? '';
$shipping_postcode = $shipping_address->postcode ?? '';
$shipping_city = $shipping_address->city ?? '';
$shipping_method = $cart->selected_shipping_rate->method_title ?? null;
$shipping_country = $shipping_address->country ?? null;
$shipping_state = $shipping_address->state ?? null;
$shipping_postcode = $shipping_address->postcode ?? null;
$shipping_city = $shipping_address->city ?? null;
if (isset($cart->payment)) {
$payment_method = $paymentMethods[$cart->payment->method]['title'];
} else {
$payment_method = null;
}
$payment_method = $cart->payment->method ?? '';
$sub_total = $cart->base_sub_total;
$total_items = $cart->items_qty;
$total_weight = 0;
foreach($cart->items as $item) {
@ -414,11 +624,34 @@ abstract class Discount
}
foreach ($conditions as $condition) {
$actual_value = ${$condition->attribute};
$test_value = $condition->value;
$test_condition = $condition->condition;
if (isset($condition->attribute)) {
$actual_value = ${$condition->attribute};
} else {
$result = false;
}
if (isset($condition->value)) {
$test_value = $condition->value;
} else {
$result = false;
}
if (isset($condition->condition)) {
$test_condition = $condition->condition;
}
else {
$result = false;
}
if ($condition->type == 'numeric' || $condition->type == 'string' || $condition->type == 'text') {
if ($condition->type == 'string') {
$actual_value = strtolower($actual_value);
$test_value = strtolower($test_value);
}
if ($test_condition == '=') {
if ($actual_value == $test_value) {
$result = true;
@ -450,7 +683,7 @@ abstract class Discount
break;
}
} else if ($test_condition == '{}') {
if (str_contains($actual_value, $test_value)) {
if (! str_contains($actual_value, $test_value)) {
$result = true;
break;

View File

@ -19,29 +19,34 @@ class NonCouponAbleRule extends Discount
$applicableRules = array();
if (auth()->guard('customer')->check()) {
$rules = $this->cartRule->findWhere([
'use_coupon' => 0,
'status' => 1
]);
} else {
$rules = $this->cartRule->findWhere([
'use_coupon' => 0,
'is_guest' => 1,
'status' => 1
]);
}
$rules = $this->cartRule->findWhere([
'use_coupon' => 0,
'status' => 1
]);
$alreadyAppliedRule = $this->cartRuleCart->findWhere([
$alreadyAppliedCartRuleCart = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id,
]);
if (count($alreadyAppliedCartRuleCart)) {
$alreadyAppliedRule = $alreadyAppliedCartRuleCart->first()->cart_rule;
if (count($alreadyAppliedRule)) {
$alreadyAppliedRule = $alreadyAppliedRule->first()->cart_rule;
$validated = $this->validateRule($alreadyAppliedRule);
if (! $validated) {
// if the validation fails then the cart rule gets deleted from cart rule cart
$alreadyAppliedCartRuleCart->first()->delete();
$this->resetShipping($cart);
// all discount is cleared fro mthe cart and cart items table
$this->clearDiscount();
return false;
}
if ($alreadyAppliedRule->use_coupon) {
return null;
return false;
}
}
@ -56,10 +61,25 @@ class NonCouponAbleRule extends Discount
$impact = $actionInstance->calculate($rule, $item, $cart);
array_push($applicableRules, [
'rule' => $rule,
'impact' => $impact
]);
if ($impact['discount'] > 0) {
array_push($applicableRules, [
'rule' => $rule,
'impact' => $impact
]);
}
if (count($alreadyAppliedCartRuleCart)) {
$alreadyAppliedRule = $alreadyAppliedCartRuleCart->first()->cart_rule;
if ($alreadyAppliedRule->id == $rule->id) {
if ($impact['discount'] == 0) {
$alreadyAppliedCartRuleCart->first()->delete();
// all discount is cleared from cart and cart items table
$this->clearDiscount();
}
}
}
}
}
@ -99,7 +119,7 @@ class NonCouponAbleRule extends Discount
if (count($endRules) == 1) {
$this->save(array_first($endRules)['rule']);
return $endRules;
return array_first($endRules)['impact'];
}
$maxImpact = 0;
@ -165,7 +185,7 @@ class NonCouponAbleRule extends Discount
} else {
$this->save(array_first($maxImpacts)['rule']);
return $maxImpacts;
return array_first($applicableRules)['impact'];
}
} else {
$this->save(array_first($prioritySorted)['rule']);
@ -173,13 +193,11 @@ class NonCouponAbleRule extends Discount
return $prioritySorted;
}
} else if (count($applicableRules) == 1) {
$rule = array_first($applicableRules)['rule'];
$this->save($applicableRules);
$this->save(array_first($applicableRules)['rule']);
return array_first($applicableRules)['impact'];
} else {
return null;
return false;
}
}
}

View File

@ -0,0 +1,100 @@
<?php
namespace Webkul\Discount\Helpers;
use Webkul\Discount\Helpers\Discount;
use Webkul\Discount\Repositories\CartRuleCartRepository as CartRuleCart;
class ValidatesDiscount extends Discount
{
/**
* CartRuleCartRepository instance
*/
protected $cartRuleCart;
/**
* Initializes type hinted dependencies
*
* @param CartRuleCart $cartRuleCart
*/
public function __construct(CartRuleCart $cartRuleCart)
{
$this->cartRuleCart = $cartRuleCart;
}
public function apply($code)
{
return ;
}
/**
* Validates the currently applied cart rule on the current cart
*
* @param $cart instance
*
* @return mixed
*/
public function validate($cart)
{
$appliedRule = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id
]);
if ($appliedRule->count()) {
$appliedRule = $appliedRule->first()->cart_rule;
if ($appliedRule->status == 1) {
$applicability = $this->checkApplicability($appliedRule);
if (! $applicability) {
return $this->remove();
}
} else {
return $this->remove();
}
}
return false;
}
/**
* Removes the already applied coupon on the current cart instance
*
* @return boolean
*/
public function remove()
{
$cart = Cart::getCart();
$existingRule = $this->cartRuleCart->findWhere([
'cart_id' => $cart->id
]);
if ($existingRule->count()) {
$existingRule->first()->delete();
foreach ($cart->items as $item) {
if ($item->discount_amount > 0) {
$item->update([
'discount_amount' => 0,
'base_discount_amount' => 0,
'discount_percent' => 0,
'coupon_code' => NULL
]);
}
}
$cart->update([
'coupon_code' => NULL,
'discount_amount' => 0,
'base_discount_amount' => 0
]);
Cart::collectTotals();
return true;
} else {
return false;
}
}
}

View File

@ -190,6 +190,16 @@ class CartRuleController extends Controller
// save the coupon used in coupon section
$coupons['code'] = $data['code'];
$couponExists = $this->cartRuleCoupon->findWhere([
'code' => $coupons['code']
]);
if ($couponExists->count()) {
session()->flash('warning', trans('admin::app.promotion.status.duplicate-coupon'));
return redirect()->back();
}
// set coupon usage per customer same as per_customer limit which is disabled for now
$coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
// unset coupon code from coupon section
@ -390,6 +400,18 @@ class CartRuleController extends Controller
$coupons['code'] = $data['code'];
$couponExists = $this->cartRuleCoupon->findWhere([
'code' => $coupons['code']
]);
if ($couponExists->count()) {
if ($couponExists->first()->cart_rule_id != $id) {
session()->flash('warning', trans('admin::app.promotion.status.duplicate-coupon'));
return redirect()->back();
}
}
unset($data['code']);
// } else {
// $data['auto_generation'] = 1;
@ -425,20 +447,28 @@ class CartRuleController extends Controller
// check coupons set conditions
if (isset($coupons)) {
$coupons['cart_rule_id'] = $ruleUpdated->id;
// $coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
$coupons['cart_rule_id'] = $ruleUpdated->id;
$couponUpdated = $ruleUpdated->coupons->update($coupons);
if ($ruleUpdated->coupons == null) {
$couponCreatedOrUpdated = $this->cartRuleCoupon->create($coupons);
} else {
$couponCreatedOrUpdated = $ruleUpdated->coupons->update($coupons);
}
} else {
if ($ruleUpdated->coupons != null) {
$ruleUpdated->coupons->delete();
}
}
if ($ruleUpdated && $ruleGroupUpdated && $ruleChannelUpdated) {
if (isset($couponUpdated) && $couponUpdated) {
session()->flash('info', trans('admin::app.promotion.status.success-coupon'));
if (isset($couponCreatedOrUpdated) && $couponCreatedOrUpdated) {
session()->flash('success', trans('admin::app.promotion.status.success-coupon'));
}
session()->flash('info', trans('admin::app.promotion.status.update-success'));
session()->flash('success', trans('admin::app.promotion.status.update-success'));
} else {
session()->flash('info', trans('admin::app.promotion.status.update-success'));
session()->flash('success', trans('admin::app.promotion.status.update-success'));
return redirect()->back();
}

View File

@ -255,7 +255,7 @@ class CatalogRuleController extends Controller
$catalogRuleCustomerGroups = $this->catalogRule->CustomerGroupSync($catalog_rule_customer_groups, $catalogRule);
if($catalogRule && $catalogRuleChannels && $catalogRuleCustomerGroups) {
session()->flash('info', trans('admin::app.promotion.status.update-success'));
session()->flash('success', trans('admin::app.promotion.status.update-success'));
return redirect()->route($this->_config['redirect']);
} else {

View File

@ -3,6 +3,7 @@
namespace Webkul\Discount\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\CustomerGroupProxy;
use Webkul\Discount\Contracts\CartRuleCustomerGroups as CartRuleCustomerGroupContract;
class CartRuleCustomerGroups extends Model implements CartRuleCustomerGroupContract
@ -10,4 +11,9 @@ class CartRuleCustomerGroups extends Model implements CartRuleCustomerGroupContr
protected $table = 'cart_rule_customer_groups';
protected $guarded = ['created_at', 'updated_at'];
public function customer_group()
{
return $this->hasOne(CustomerGroupProxy::modelClass(), 'id', 'customer_group_id');
}
}

View File

@ -186,12 +186,4 @@ class CartRuleRepository extends Repository
return true;
}
/**
* To sync the coupons associated with the cart rule
*/
public function CouponSync($coupon, $cartRule)
{
}
}

View File

@ -32,7 +32,7 @@ class ProductImage extends AbstractProduct
];
}
if (! count($images)) {
if (! $product->parent_id && ! count($images)) {
$images[] = [
'small_image_url' => asset('vendor/webkul/ui/assets/images/product/small-product-placeholder.png'),
'medium_image_url' => asset('vendor/webkul/ui/assets/images/product/meduim-product-placeholder.png'),

View File

@ -26,6 +26,7 @@ class View extends AbstractProduct
}
$data[] = [
'id' => $attribute->id,
'code' => $attribute->code,
'label' => $attribute->name,
'value' => $value,

View File

@ -12,6 +12,7 @@ use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
use Webkul\Product\Repositories\ProductDownloadableSampleRepository;
use Webkul\Attribute\Repositories\AttributeFamilyRepository;
use Webkul\Inventory\Repositories\InventorySourceRepository;
use Illuminate\Support\Facades\Storage;
/**
* Product controller
@ -338,4 +339,20 @@ class ProductController extends Controller
return view($this->_config['view']);
}
}
/**
* Download image or file
*
* @param int $productId, $attributeId
* @return \Illuminate\Http\Response
*/
public function download($productId, $attributeId)
{
$productAttribute = $this->productAttributeValue->findOneWhere([
'product_id' => $productId,
'attribute_id' => $attributeId
]);
return Storage::download($productAttribute['text_value']);
}
}

View File

@ -1,114 +0,0 @@
<?php
namespace Webkul\Product\Repositories;
use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Helpers\Price;
/**
* Product Repository
*
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ProductGridRepository extends Repository
{
protected $product;
/**
* Price Object
*
* @var array
*/
Protected $price;
public function __construct(
Product $product,
Price $price,
App $app
)
{
$this->product = $product;
$this->price = $price;
parent::__construct($app);
}
public function model() {
return 'Webkul\Product\Contracts\ProductGrid';
}
public function updateWhere($product) {
if ($product->type == "simple") {
$gridObject = [
'sku' => $product->sku,
'name' => $product->name,
'attribute_family_name' => $product->toArray()['attribute_family']['name'],
'price' => $this->price->getMinimalPrice($product),
'status' => $product->status
];
$qty = 0;
if ($product->parent_id == 'null') {
$gridObject['type'] = $product->type;
}
foreach ($product->toArray()['inventories'] as $inventorySource) {
$qty = $qty + $inventorySource['qty'];
}
$gridObject['quantity'] = $qty;
return $this->getModel()->where('product_id', $product->id)->update($gridObject);
} else if ($product->type == "configurable") {
$gridObject = [
'sku' => $product->sku,
'type' => $product->type,
'name' => $product->name,
'attribute_family_name' => $product->toArray()['attribute_family']['name'],
'price' => $this->price->getMinimalPrice($product),
'status' => $product->status
];
$qty = 0;
$gridObject['quantity'] = $qty;
$this->getModel()->where('product_id', $product->id)->update($gridObject);
$variants = $product->variants;
foreach ($variants as $variant) {
$gridObject = [];
$gridObject = [
'sku' => $variant->sku,
'name' => $variant->name,
'attribute_family_name' => $variant->toArray()['attribute_family']['name'],
'price' => $this->price->getMinimalPrice($variant),
'status' => $variant->status
];
if ($variant->type == 'configurable') {
$gridObject['quantity'] = 0;
} else {
$qty = 0;
foreach ($variant->toArray()['inventories'] as $inventorySource) {
$qty = $qty + $inventorySource['qty'];
}
$gridObject['quantity'] = $qty;
}
return $this->getModel()->where('product_id', $variant->id)->update($gridObject);
}
}
return false;
}
}

View File

@ -45,7 +45,7 @@ class ProductRepository extends Repository
*
* @var array
*/
protected $productImage;
protected $productImageRepository;
/**
* ProductDownloadableLinkRepository object
@ -79,7 +79,8 @@ class ProductRepository extends Repository
ProductImageRepository $productImageRepository,
ProductDownloadableLinkRepository $productDownloadableLinkRepository,
ProductDownloadableSampleRepository $productDownloadableSampleRepository,
App $app)
App $app
)
{
$this->attributeRepository = $attributeRepository;

View File

@ -5,9 +5,9 @@ namespace Webkul\Sales\Repositories;
use Illuminate\Container\Container as App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;
use Webkul\Core\Eloquent\Repository;
use Webkul\Sales\Contracts\Order;
use Webkul\Sales\Repositories\OrderItemRepository;
/**
* Order Reposotory
@ -15,7 +15,6 @@ use Webkul\Sales\Contracts\Order;
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class OrderRepository extends Repository
{
/**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/shop.js": "/js/shop.js?id=71f03d05d9690fe24784",
"/css/shop.css": "/css/shop.css?id=0e57754dbdaba7c6eb76"
"/js/shop.js": "/js/shop.js?id=ca072e0f28ed18cc8517",
"/css/shop.css": "/css/shop.css?id=b1e887800b394edeea8e"
}

View File

@ -4,7 +4,6 @@ namespace Webkul\Shop\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Checkout\Repositories\CartRepository;
use Webkul\Checkout\Repositories\CartItemRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Customer\Repositories\WishlistRepository;
@ -27,13 +26,6 @@ class CartController extends Controller
*/
protected $_config;
/**
* CartRepository object
*
* @var Object
*/
protected $cartRepository;
/**
* CartItemRepository object
*
@ -63,22 +55,19 @@ class CartController extends Controller
/**
* Create a new controller instance.
*
* @param \Webkul\Checkout\Repositories\CartRepository $cartRepository
* @param \Webkul\Checkout\Repositories\CartItemRepository $cartItemRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Customer\Repositories\CartItemRepository $wishlistRepository
* @return void
*/
public function __construct(
CartRepository $cartRepository,
CartItemRepository $cartItemRepository,
ProductRepository $productRepository,
WishlistRepository $wishlistRepository
)
{
$this->middleware('customer')->only(['moveToWishlist']);
$this->cartRepository = $cartRepository;
$this->middleware('customer')->only(['moveToWishlist']);
$this->cartItemRepository = $cartItemRepository;
@ -232,18 +221,24 @@ class CartController extends Controller
public function buyNow($id, $quantity = 1)
{
Event::fire('checkout.cart.add.before', $id);
try {
Event::fire('checkout.cart.add.before', $id);
$result = Cart::proceedToBuyNow($id, $quantity);
$result = Cart::proceedToBuyNow($id, $quantity);
Event::fire('checkout.cart.add.after', $result);
Event::fire('checkout.cart.add.after', $result);
Cart::collectTotals();
Cart::collectTotals();
if (! $result) {
return redirect()->back();
} else {
return redirect()->route('shop.checkout.onepage.index');
}
} catch(\Exception $e) {
session()->flash('error', trans($e->getMessage()));
if (! $result) {
return redirect()->back();
} else {
return redirect()->route('shop.checkout.onepage.index');
}
}

View File

@ -2,7 +2,6 @@
namespace Webkul\Shop\Http\Controllers;
use Webkul\Shop\Http\Controllers\Controller;
use Webkul\Category\Repositories\CategoryRepository;
/**
@ -36,7 +35,7 @@ class CategoryController extends Controller
public function __construct(CategoryRepository $categoryRepository)
{
$this->categoryRepository = $categoryRepository;
$this->_config = request('_config');
}

View File

@ -10,6 +10,7 @@ use Webkul\Checkout\Http\Requests\CustomerAddressForm;
use Webkul\Sales\Repositories\OrderRepository;
use Webkul\Discount\Helpers\CouponAbleRule as Coupon;
use Webkul\Discount\Helpers\NonCouponAbleRule as NonCoupon;
use Webkul\Discount\Helpers\ValidatesDiscount;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Auth;
@ -38,17 +39,22 @@ class OnepageController extends Controller
protected $_config;
/**
* CouponAbleRule instance object
*
* CouponAbleRule instance
*/
protected $coupon;
/**
* NoncouponAbleRule instance object
*
* NoncouponAbleRule instance
*/
protected $nonCoupon;
/**
* ValidatesDiscount instance object
*/
protected $validatesDiscount;
/**
* Create a new controller instance.
*
@ -58,7 +64,8 @@ class OnepageController extends Controller
public function __construct(
OrderRepository $orderRepository,
Coupon $coupon,
NonCoupon $nonCoupon
NonCoupon $nonCoupon,
ValidatesDiscount $validatesDiscount
)
{
$this->coupon = $coupon;
@ -67,6 +74,8 @@ class OnepageController extends Controller
$this->orderRepository = $orderRepository;
$this->validatesDiscount = $validatesDiscount;
$this->_config = request('_config');
}
@ -119,15 +128,15 @@ class OnepageController extends Controller
$data['billing']['address1'] = implode(PHP_EOL, array_filter($data['billing']['address1']));
$data['shipping']['address1'] = implode(PHP_EOL, array_filter($data['shipping']['address1']));
$this->nonCoupon->apply();
Cart::collectTotals();
if (Cart::hasError() || ! Cart::saveCustomerAddress($data)) {
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
} else {
$cart = Cart::getCart();
$this->nonCoupon->apply();
Cart::collectTotals();
if ($cart->haveStockableItems()) {
if (! $rates = Shipping::collectRates())
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
@ -148,13 +157,13 @@ class OnepageController extends Controller
{
$shippingMethod = request()->get('shipping_method');
if (Cart::hasError() || !$shippingMethod || !Cart::saveShippingMethod($shippingMethod))
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
$this->nonCoupon->apply();
Cart::collectTotals();
if (Cart::hasError() || ! $shippingMethod || ! Cart::saveShippingMethod($shippingMethod))
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
return response()->json(Payment::getSupportedPaymentMethods());
}
@ -167,12 +176,14 @@ class OnepageController extends Controller
{
$payment = request()->get('payment');
if (Cart::hasError() || ! $payment || ! Cart::savePaymentMethod($payment))
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
$this->nonCoupon->apply();
Cart::collectTotals();
$this->nonCoupon->checkOnShipping(Cart::getCart());
if (Cart::hasError() || !$payment || ! Cart::savePaymentMethod($payment))
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
Cart::collectTotals();
$cart = Cart::getCart();
@ -238,20 +249,23 @@ class OnepageController extends Controller
{
$cart = Cart::getCart();
// extra validation check if some the conditions is changed for the coupons but not using it now
// $this->nonCoupon->apply();
$this->validatesDiscount->validate($cart);
if ($cart->haveStockableItems() && ! $cart->shipping_address)
if ($cart->haveStockableItems() && ! $cart->shipping_address) {
throw new \Exception(trans('Please check shipping address.'));
}
if (! $cart->billing_address)
if (! $cart->billing_address) {
throw new \Exception(trans('Please check billing address.'));
}
if ($cart->haveStockableItems() && ! $cart->selected_shipping_rate)
if ($cart->haveStockableItems() && ! $cart->selected_shipping_rate) {
throw new \Exception(trans('Please specify shipping method.'));
}
if (! $cart->payment)
if (! $cart->payment) {
throw new \Exception(trans('Please specify payment method.'));
}
}
/**
@ -274,13 +288,13 @@ class OnepageController extends Controller
return response()->json([
'success' => true,
'message' => trans('shop::app.checkout.onepage.total.coupon-applied'),
'message' => trans('shop::app.checkout.total.coupon-applied'),
'result' => $result
], 200);
} else {
return response()->json([
'success' => false,
'message' => trans('shop::app.checkout.onepage.total.cannot-apply-coupon'),
'message' => trans('shop::app.checkout.total.cannot-apply-coupon'),
'result' => null
], 422);
}
@ -288,19 +302,6 @@ class OnepageController extends Controller
return $result;
}
/**
* Applies non couponable rule if present
*
* @return Void
*/
public function applyNonCouponAbleRule()
{
$cart = Cart::getCart();
$nonCouponAbleRules = Cart::applyNonCoupon();
return $nonCouponAbleRules;
}
/**
* Initiates the removal of couponable cart rule
*

View File

@ -4,6 +4,7 @@ namespace Webkul\Shop\Http\Controllers;
use Illuminate\Support\Facades\Storage;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductDownloadableSampleRepository;
use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
@ -30,6 +31,13 @@ class ProductController extends Controller
*/
protected $productRepository;
/**
* ProductAttributeValueRepository object
*
* @var array
*/
protected $productAttributeValueRepository;
/**
* ProductDownloadableSampleRepository object
*
@ -48,18 +56,22 @@ class ProductController extends Controller
* Create a new controller instance.
*
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Product\Repositories\productAttributeValueRepository $productAttributeValueRepository
* @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository
* @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository
* @return void
*/
public function __construct(
ProductRepository $productRepository,
ProductAttributeValueRepository $productAttributeValueRepository,
ProductDownloadableSampleRepository $productDownloadableSampleRepository,
ProductDownloadableLinkRepository $productDownloadableLinkRepository
)
{
$this->productRepository = $productRepository;
$this->productAttributeValueRepository = $productAttributeValueRepository;
$this->productDownloadableSampleRepository = $productDownloadableSampleRepository;
$this->productDownloadableLinkRepository = $productDownloadableLinkRepository;
@ -79,7 +91,23 @@ class ProductController extends Controller
$customer = auth()->guard('customer')->user();
return view($this->_config['view'], compact('product','customer'));
return view($this->_config['view'], compact('product', 'customer'));
}
/**
* Download image or file
*
* @param int $productId, $attributeId
* @return \Illuminate\Http\Response
*/
public function download($productId, $attributeId)
{
$productAttribute = $this->productAttributeValueRepository->findOneWhere([
'product_id' => $productId,
'attribute_id' => $attributeId
]);
return Storage::download($productAttribute['text_value']);
}
/**

View File

@ -114,6 +114,11 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
'redirect' => 'shop.home.index'
])->name('shop.reviews.store');
// Download file or image
Route::get('/product/{id}/{attribute_id}', 'Webkul\Shop\Http\Controllers\ProductController@download')->defaults('_config', [
'view' => 'shop.products.index'
])->name('shop.product.file.download');
//customer routes starts here
Route::prefix('customer')->group(function () {
// forgot Password Routes

View File

@ -46,6 +46,22 @@ input {
justify-content: center;
}
@media only screen and (max-width: 770px) {
.pagination.shop {
justify-content: space-between;
.page-item {
display: none;
&.previous,
&.next {
display: block;
}
}
}
}
//components
.bold {
font-weight: bold;
@ -1095,6 +1111,7 @@ section.slider-block {
.search-box {
display: inline-block;
margin-right: 10px;
cursor: pointer;
}
.right-content-menu {
@ -3443,6 +3460,7 @@ section.review {
.table {
.grid-container {
margin-top: 10px;
overflow-x: hidden;
.filter-row-one {
display: block;

View File

@ -299,7 +299,7 @@ return [
'unlimited' => 'Unlimited',
'download-error' => 'Download link has been expired.'
],
'review' => [
'index' => [
'title' => 'Reviews',
@ -359,18 +359,18 @@ return [
'deleteall' => 'Delete All',
'moveall' => 'Move All Products To Cart',
'move-to-cart' => 'Move To Cart',
'error' => 'Cannot Add The Product To Wishlist Due To Unknown Problems, Please Checkback Later',
'add' => 'Item Successfully Added To Wishlist',
'remove' => 'Item Successfully Removed From Wishlist',
'moved' => 'Item Successfully Moved To Wishlist',
'move-error' => 'Item Cannot Be Moved To Wishlist, Please Try Again Later',
'success' => 'Item Successfully Added To Wishlist',
'failure' => 'Item Cannot Be Added To Wishlist, Please Try Again Later',
'already' => 'Item Already Present In Your Wishlist',
'removed' => 'Item Successfully Removed From Wishlist',
'remove-fail' => 'Item Cannot Be Removed From Wishlist, Please Try Again Later',
'empty' => 'You do not have any items in your Wishlist',
'remove-all-success' => 'All The Items From Your Wishlist Have Been Removed',
'error' => 'Cannot add product to wishlist due to unknown problems, please checkback later',
'add' => 'Item successfully added to wishlist',
'remove' => 'Item successfully removed from wishlist',
'moved' => 'Item successfully moved To cart',
'move-error' => 'Item cannot be moved to wishlist, Please try again later',
'success' => 'Item successfully added to wishlist',
'failure' => 'Item cannot be added to wishlist, Please try again later',
'already' => 'Item already present in your wishlist',
'removed' => 'Item successfully removed from wishlist',
'remove-fail' => 'Item cannot Be removed from wishlist, Please try again later',
'empty' => 'You do not have any items in your wishlist',
'remove-all-success' => 'All the items from your wishlist have been removed',
],
// 'reviews' => [

View File

@ -153,7 +153,7 @@
new_shipping_address: false,
new_billing_address: false,
allAddress: {},
countryStates: @json(core()->groupedStatesByCountries()),
@ -290,20 +290,20 @@
this.disable_button = true;
this.$http.post("{{ route('shop.checkout.save-payment') }}", {'payment': this.selected_payment_method})
.then(function(response) {
this_this.disable_button = false;
.then(function(response) {
this_this.disable_button = false;
reviewHtml = Vue.compile(response.data.html)
this_this.completed_step = this_this.step_numbers[response.data.jump_to_section] + 1;
this_this.current_step = this_this.step_numbers[response.data.jump_to_section];
reviewHtml = Vue.compile(response.data.html)
this_this.completed_step = this_this.step_numbers[response.data.jump_to_section] + 1;
this_this.current_step = this_this.step_numbers[response.data.jump_to_section];
this_this.getOrderSummary();
})
.catch(function (error) {
this_this.disable_button = false;
this_this.getOrderSummary();
})
.catch(function (error) {
this_this.disable_button = false;
this_this.handleErrorResponse(error.response, 'payment-form')
});
this_this.handleErrorResponse(error.response, 'payment-form')
});
},
placeOrder: function() {
@ -312,22 +312,22 @@
this.disable_button = true;
this.$http.post("{{ route('shop.checkout.save-order') }}", {'_token': "{{ csrf_token() }}"})
.then(function(response) {
if (response.data.success) {
if (response.data.redirect_url) {
window.location.href = response.data.redirect_url;
} else {
window.location.href = "{{ route('shop.checkout.success') }}";
}
.then(function(response) {
if (response.data.success) {
if (response.data.redirect_url) {
window.location.href = response.data.redirect_url;
} else {
window.location.href = "{{ route('shop.checkout.success') }}";
}
})
.catch(function (error) {
this_this.disable_button = true;
}
})
.catch(function (error) {
this_this.disable_button = true;
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('shop::app.common.error') }}" }];
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('shop::app.common.error') }}" }];
this_this.$root.addFlashMessages()
})
this_this.$root.addFlashMessages()
})
},
handleErrorResponse: function(response, scope) {
@ -505,7 +505,11 @@
coupon_code: null,
error_message: ''
error_message: null,
couponChanged: false,
changeCount: 0
}
},
@ -536,9 +540,28 @@
axios.post('{{ route('shop.checkout.check.coupons') }}', {code: this_this.coupon_code})
.then(function(response) {
this_this.$emit('onApplyCoupon')
this_this.$emit('onApplyCoupon');
this_this.couponChanged = true;
})
.catch(function(error) {});
.catch(function(error) {
this_this.couponChanged = true;
this_this.error_message = error.response.data.message;
});
},
changeCoupon: function() {
console.log('called');
if (this.couponChanged == true && this.changeCount == 0) {
this.changeCount++;
this.error_message = null;
this.couponChanged = false;
} else {
this.changeCount = 0;
}
},
removeCoupon: function () {
@ -548,7 +571,11 @@
.then(function(response) {
this_this.$emit('onRemoveCoupon')
})
.catch(function(error) {});
.catch(function(error) {
window.flashMessages = [{'type' : 'alert-error', 'message' : error.response.data.message}];
this_this.$root.addFlashMessages();
});
}
}
})

View File

@ -221,7 +221,6 @@
<label class="checkbox-view" for="billing[use_for_shipping]"></label>
{{ __('shop::app.checkout.onepage.use_for_shipping') }}
</span>
</div>
@endif

View File

@ -50,13 +50,13 @@
<div class="discount">
<div class="discount-group">
<form class="coupon-form" method="post" @submit.prevent="onSubmit">
<div class="control-group mt-20" :class="[errors.has('code') ? 'has-error' : '']">
<input type="text" class="control" value="" v-model="coupon_code" name="code" placeholder="Enter Coupon Code" v-validate="'required'" style="width: 100%">
<div class="control-group mt-20" :class="[errors.has('code') ? 'has-error' : '']" style="margin-bottom: 10px">
<input type="text" class="control" value="" v-model="coupon_code" name="code" placeholder="Enter Coupon Code" v-validate="'required'" style="width: 100%" @change="changeCoupon">
</div>
<span class="control-error" v-if="error_message.length > 0">@{{ error_message }}</span>
<div class="control-error mb-10" v-if="error_message != null" style="color: #FF6472">* @{{ error_message }}</div>
<button class="btn btn-lg btn-black">{{ __('shop::app.checkout.onepage.apply-coupon') }}</button>
<button class="btn btn-lg btn-black" :disabled="couponChanged">{{ __('shop::app.checkout.onepage.apply-coupon') }}</button>
</form>
</div>
</div>

View File

@ -123,6 +123,14 @@
</tr>
@endif
@if ($order->base_discount_amount > 0)
<tr>
<td>{{ __('shop::app.customer.account.order.view.discount') }}</td>
<td>-</td>
<td>{{ core()->formatPrice($order->discount_amount, $order->order_currency_code) }}</td>
</tr>
@endif
<tr class="border">
<td>{{ __('shop::app.customer.account.order.view.tax') }}</td>
<td>-</td>

View File

@ -29,39 +29,37 @@
</div>
<div style="display: flex;flex-direction: row;margin-top: 20px;justify-content: space-between;margin-bottom: 40px;">
@if ($order->shipping_address)
<div style="line-height: 25px;">
<div style="font-weight: bold;font-size: 16px;color: #242424;">
{{ __('shop::app.mail.order.shipping-address') }}
</div>
<div>
{{ $order->shipping_address->name }}
</div>
<div>
{{ $order->shipping_address->address1 }}, {{ $order->shipping_address->state }}
</div>
<div>
{{ core()->country_name($order->shipping_address->country) }} {{ $order->shipping_address->postcode }}
</div>
<div>---</div>
<div style="margin-bottom: 40px;">
{{ __('shop::app.mail.order.contact') }} : {{ $order->shipping_address->phone }}
</div>
<div style="font-size: 16px;color: #242424;">
{{ __('shop::app.mail.order.shipping') }}
</div>
<div style="font-weight: bold;font-size: 16px;color: #242424;">
{{ $order->shipping_title }}
</div>
<div style="line-height: 25px;">
<div style="font-weight: bold;font-size: 16px;color: #242424;">
{{ __('shop::app.mail.order.shipping-address') }}
</div>
@endif
<div>
{{ $order->shipping_address->name }}
</div>
<div>
{{ $order->shipping_address->address1 }}, {{ $order->shipping_address->state }}
</div>
<div>
{{ core()->country_name($order->shipping_address->country) }} {{ $order->shipping_address->postcode }}
</div>
<div>---</div>
<div style="margin-bottom: 40px;">
{{ __('shop::app.mail.order.contact') }} : {{ $order->shipping_address->phone }}
</div>
<div style="font-size: 16px;color: #242424; font-weight: bold">
{{ __('shop::app.mail.order.shipping') }}
</div>
<div style="font-size: 16px;color: #242424;">
{{ $order->shipping_title }}
</div>
</div>
<div style="line-height: 25px;">
<div style="font-weight: bold;font-size: 16px;color: #242424;">
@ -86,51 +84,54 @@
{{ __('shop::app.mail.order.contact') }} : {{ $order->billing_address->phone }}
</div>
<div style="font-size: 16px; color: #242424;">
<div style="font-size: 16px; color: #242424; font-weight: bold">
{{ __('shop::app.mail.order.payment') }}
</div>
<div style="font-weight: bold;font-size: 16px; color: #242424;">
<div style="font-size: 16px; color: #242424;">
{{ core()->getConfigData('sales.paymentmethods.' . $order->payment->method . '.title') }}
</div>
</div>
</div>
@foreach ($order->items as $item)
<div style="background: #FFFFFF;border: 1px solid #E8E8E8;border-radius: 3px;padding: 20px;margin-bottom: 10px">
<p style="font-size: 18px;color: #242424;line-height: 24px;margin-top: 0;margin-bottom: 10px;font-weight: bold;">
{{ $item->name }}
</p>
<div class="section-content">
<div class="table mb-20">
<table style="overflow-x: auto; border-collapse: collapse;
border-spacing: 0;width: 100%">
<thead>
<tr style="background-color: #f2f2f2">
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.SKU') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.product-name') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.price') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.qty') }}</th>
</tr>
</thead>
<div style="margin-bottom: 10px;">
<label style="font-size: 16px;color: #5E5E5E;">
{{ __('shop::app.mail.order.price') }}
</label>
<span style="font-size: 18px;color: #242424;margin-left: 40px;font-weight: bold;">
{{ core()->formatBasePrice($item->base_price) }}
</span>
</div>
<tbody>
@foreach ($order->items as $item)
<tr>
<td data-value="{{ __('shop::app.customer.account.order.view.SKU') }}" style="text-align: left;padding: 8px">{{ $item->child ? $item->child->sku : $item->sku }}</td>
<div style="margin-bottom: 10px;">
<label style="font-size: 16px;color: #5E5E5E;">
{{ __('shop::app.mail.order.quantity') }}
</label>
<span style="font-size: 18px;color: #242424;margin-left: 40px;font-weight: bold;">
{{ $item->qty_ordered }}
</span>
</div>
<td data-value="{{ __('shop::app.customer.account.order.view.product-name') }}" style="text-align: left;padding: 8px">{{ $item->name }}</td>
@if ($html = $item->getOptionDetailHtml())
<div style="">
<label style="margin-top: 10px; font-size: 16px;color: #5E5E5E; display: block;">
{{ $html }}
</label>
</div>
@elseif ($item->type == 'downloadable')
<p><b>Downloads : </b>{{ $item->getDownloadableDetailHtml() }}</p>
@endif
<td data-value="{{ __('shop::app.customer.account.order.view.price') }}" style="text-align: left;padding: 8px">{{ core()->formatPrice($item->price, $order->order_currency_code) }}
</td>
<td data-value="{{ __('shop::app.customer.account.order.view.qty') }}" style="text-align: left;padding: 8px">{{ $item->qty_ordered }}</td>
@if ($html = $item->getOptionDetailHtml())
<div style="">
<label style="margin-top: 10px; font-size: 16px;color: #5E5E5E; display: block;">
{{ $html }}
</label>
</div>
@endif
</tr>
@endforeach
</tbody>
</table>
</div>
@endforeach
</div>
<div style="font-size: 16px;color: #242424;line-height: 30px;float: right;width: 40%;margin-top: 20px;">
<div>
@ -140,14 +141,12 @@
</span>
</div>
@if ($order->shipping_address)
<div>
<span>{{ __('shop::app.mail.order.shipping-handling') }}</span>
<span style="float: right;">
{{ core()->formatBasePrice($order->base_shipping_amount) }}
</span>
</div>
@endif
<div>
<span>{{ __('shop::app.mail.order.shipping-handling') }}</span>
<span style="float: right;">
{{ core()->formatBasePrice($order->base_shipping_amount) }}
</span>
</div>
<div>
<span>{{ __('shop::app.mail.order.tax') }}</span>

View File

@ -21,7 +21,7 @@
{!! __('shop::app.mail.order.greeting', [
'order_id' => '<a href="' . route('customer.orders.view', $order->id) . '" style="color: #0041FF; font-weight: bold;">#' . $order->id . '</a>',
'created_at' => $order->created_at
])
])
!!}
</p>
</div>
@ -52,7 +52,7 @@
<div>---</div>
<div style="margin-bottom: 40px;">
{{ __('shop::app.mail.order.contact') }} : {{ $order->shipping_address->phone }}
{{ __('shop::app.mail.order.contact') }} : {{ $order->shipping_address->phone }}
</div>
<div style="font-size: 16px;color: #242424;">
@ -85,7 +85,7 @@
<div>---</div>
<div style="margin-bottom: 40px;">
{{ __('shop::app.mail.order.contact') }} : {{ $order->billing_address->phone }}
{{ __('shop::app.mail.order.contact') }} : {{ $order->billing_address->phone }}
</div>
<div style="font-size: 16px; color: #242424;">
@ -98,41 +98,44 @@
</div>
</div>
@foreach ($invoice->items as $item)
<div style="background: #FFFFFF;border: 1px solid #E8E8E8;border-radius: 3px;padding: 20px;margin-bottom: 10px">
<p style="font-size: 18px;color: #242424;line-height: 24px;margin-top: 0;margin-bottom: 10px;font-weight: bold;">
{{ $item->name }}
</p>
<div class="section-content">
<div class="table mb-20">
<table style="overflow-x: auto; border-collapse: collapse;
border-spacing: 0;width: 100%">
<thead>
<tr style="background-color: #f2f2f2">
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.product-name') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.price') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.qty') }}</th>
</tr>
</thead>
<div style="margin-bottom: 10px;">
<label style="font-size: 16px;color: #5E5E5E;">
{{ __('shop::app.mail.order.price') }}
</label>
<span style="font-size: 18px;color: #242424;margin-left: 40px;font-weight: bold;">
{{ core()->formatPrice($item->price, $invoice->order_currency_code) }}
</span>
</div>
<tbody>
@foreach ($invoice->items as $item)
<tr>
<td data-value="{{ __('shop::app.customer.account.order.view.product-name') }}" style="text-align: left;padding: 8px">{{ $item->name }}</td>
<div style="margin-bottom: 10px;">
<label style="font-size: 16px;color: #5E5E5E;">
{{ __('shop::app.mail.order.quantity') }}
</label>
<span style="font-size: 18px;color: #242424;margin-left: 40px;font-weight: bold;">
{{ $item->qty }}
</span>
</div>
@if ($html = $item->getOptionDetailHtml())
<div style="">
<label style="margin-top: 10px; font-size: 16px;color: #5E5E5E; display: block;">
{{ $html }}
</label>
</div>
@elseif ($item->type == 'downloadable')
<p><b>Downloads : </b>{{ $item->getDownloadableDetailHtml() }}</p>
@endif
<td data-value="{{ __('shop::app.customer.account.order.view.price') }}" style="text-align: left;padding: 8px">{{ core()->formatPrice($item->price, $order->order_currency_code) }}
</td>
<td data-value="{{ __('shop::app.customer.account.order.view.qty') }}" style="text-align: left;padding: 8px">{{ $item->qty }}</td>
@if ($html = $item->getOptionDetailHtml())
<div style="">
<label style="margin-top: 10px; font-size: 16px;color: #5E5E5E; display: block;">
{{ $html }}
</label>
</div>
@elseif ($item->type == 'downloadable')
<p><b>Downloads : </b>{{ $item->getDownloadableDetailHtml() }}</p>
@endif
</tr>
@endforeach
</tbody>
</table>
</div>
@endforeach
</div>
<div style="font-size: 16px;color: #242424;line-height: 30px;float: right;width: 40%;margin-top: 20px;">
<div>
@ -177,10 +180,10 @@
<div style="margin-top: 65px;font-size: 16px;color: #5E5E5E;line-height: 24px;display: inline-block;width: 100%">
<p style="font-size: 16px;color: #5E5E5E;line-height: 24px;">
{!!
{!!
__('shop::app.mail.order.help', [
'support_email' => '<a style="color:#0041FF" href="mailto:' . config('mail.from.address') . '">' . config('mail.from.address'). '</a>'
])
])
!!}
</p>

View File

@ -96,41 +96,46 @@
</div>
</div>
@foreach ($order->items as $item)
<div style="background: #FFFFFF;border: 1px solid #E8E8E8;border-radius: 3px;padding: 20px;margin-bottom: 10px">
<p style="font-size: 18px;color: #242424;line-height: 24px;margin-top: 0;margin-bottom: 10px;font-weight: bold;">
{{ $item->name }}
</p>
<div class="section-content">
<div class="table mb-20">
<table style="overflow-x: auto; border-collapse: collapse;
border-spacing: 0;width: 100%">
<thead>
<tr style="background-color: #f2f2f2">
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.SKU') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.product-name') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.price') }}</th>
<th style="text-align: left;padding: 8px">{{ __('shop::app.customer.account.order.view.qty') }}</th>
</tr>
</thead>
<div style="margin-bottom: 10px;">
<label style="font-size: 16px;color: #5E5E5E;">
{{ __('shop::app.mail.order.price') }}
</label>
<span style="font-size: 18px;color: #242424;margin-left: 40px;font-weight: bold;">
{{ core()->formatPrice($item->price, $order->order_currency_code) }}
</span>
</div>
<tbody>
@foreach ($order->items as $item)
<tr>
<td data-value="{{ __('shop::app.customer.account.order.view.SKU') }}" style="text-align: left;padding: 8px">{{ $item->child ? $item->child->sku : $item->sku }}</td>
<div style="margin-bottom: 10px;">
<label style="font-size: 16px;color: #5E5E5E;">
{{ __('shop::app.mail.order.quantity') }}
</label>
<span style="font-size: 18px;color: #242424;margin-left: 40px;font-weight: bold;">
{{ $item->qty_ordered }}
</span>
</div>
<td data-value="{{ __('shop::app.customer.account.order.view.product-name') }}" style="text-align: left;padding: 8px">{{ $item->name }}</td>
@if ($html = $item->getOptionDetailHtml())
<div style="">
<label style="margin-top: 10px; font-size: 16px;color: #5E5E5E; display: block;">
{{ $html }}
</label>
</div>
@elseif ($item->type == 'downloadable')
<p><b>Downloads : </b>{{ $item->getDownloadableDetailHtml() }}</p>
@endif
<td data-value="{{ __('shop::app.customer.account.order.view.price') }}" style="text-align: left;padding: 8px">{{ core()->formatPrice($item->price, $order->order_currency_code) }}
</td>
<td data-value="{{ __('shop::app.customer.account.order.view.qty') }}" style="text-align: left;padding: 8px">{{ $item->qty_ordered }}</td>
@if ($html = $item->getOptionDetailHtml())
<div style="">
<label style="margin-top: 10px; font-size: 16px;color: #5E5E5E; display: block;">
{{ $html }}
</label>
</div>
@elseif ($item->type == 'downloadable')
<p><b>Downloads : </b>{{ $item->getDownloadableDetailHtml() }}</p>
@endif
</tr>
@endforeach
</tbody>
</table>
</div>
@endforeach
</div>
<div style="font-size: 16px;color: #242424;line-height: 30px;float: right;width: 40%;margin-top: 20px;">
<div>

View File

@ -75,7 +75,7 @@
@include ('shop::products.view.configurable-options')
@include ('shop::products.view.downloadable')
{!! view_render_event('bagisto.shop.products.view.description.before', ['product' => $product]) !!}
<accordian :title="'{{ __('shop::app.products.description') }}'" :active="true">
@ -148,18 +148,11 @@
}
});
document.onreadystatechange = function () {
var state = document.readyState
var galleryTemplate = document.getElementById('product-gallery-template');
$(document).ready(function() {
var addTOButton = document.getElementsByClassName('add-to-buttons')[0];
if (galleryTemplate) {
if (state != 'interactive') {
document.getElementById('loader').style.display="none";
addTOButton.style.display="flex";
}
}
}
document.getElementById('loader').style.display="none";
addTOButton.style.display="flex";
});
window.onload = function() {
var thumbList = document.getElementsByClassName('thumb-list')[0];
@ -211,19 +204,6 @@
}
document.getElementById("quantity").value = quantity;
var buyNowLink = $('.btn.buynow').attr('data-href');
var splitted = buyNowLink.split("/");
lastItem = splitted[splitted.length - 2];
splitted.pop();
splitted.pop();
var joined = splitted.join('/');
var newBuyNowUrl = joined + '/' + lastItem + '/' + quantity;
$('.btn.buynow').attr('data-href', newBuyNowUrl);
event.preventDefault();
}
</script>

View File

@ -21,13 +21,13 @@
@endif
@if ($attribute['type'] == 'file' && $attribute['value'])
<td>
<a href="{{ Storage::url($attribute['value']) }}" target="_blank">
<a href="{{ route('shop.product.file.download', [$product->product_id, $attribute['id']])}}">
<i class="icon sort-down-icon download"></i>
</a>
</td>
@elseif ($attribute['type'] == 'image' && $attribute['value'])
<td>
<a href="{{ Storage::url($attribute['value']) }}" target="_blank">
<a href="{{ route('shop.product.file.download', [$product->product_id, $attribute['id']])}}">
<img src="{{ Storage::url($attribute['value']) }}" style="height: 20px; width: 20px;"/>
</a>
</td>
@ -35,7 +35,6 @@
<td>{{ $attribute['value'] }}</td>
@endif
</tr>
@endforeach
</table>

View File

@ -148,14 +148,13 @@
if (this.selectedProductId != '' && buyNowLink) {
var splitted = buyNowLink.split("/");
splitted.pop();
splitted.pop();
lastItem = this.selectedProductId;
var joined = splitted.join('/');
var newBuyNowUrl = joined + '/' + lastItem + '/' + quantity;
var newBuyNowUrl = joined + '/' + lastItem;
$('.btn.buynow').attr('data-href', newBuyNowUrl);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/ui.js": "/js/ui.js?id=f4ffa4c6ada363152cf9",
"/css/ui.css": "/css/ui.css?id=c846938a649c221ac297"
}
"/js/ui.js": "/js/ui.js?id=729bc198a4974d8b8079",
"/css/ui.css": "/css/ui.css?id=8cdfc8863d8ef37f6b93"
}