Merge branch 'development' of http://github.com/prashant-webkul/bagisto into development

This commit is contained in:
Prashant Singh 2019-05-13 20:28:01 +05:30
commit 7dbe5d4c9b
14 changed files with 320 additions and 187 deletions

View File

@ -1,6 +1,4 @@
<?php
return [
];
?>
];

5
config/pricerules.php Normal file
View File

@ -0,0 +1,5 @@
<?php
return [
];

View File

@ -2,6 +2,4 @@
return [
];
?>
];

View File

@ -8,83 +8,72 @@ Vue.prototype.$http = axios
window.eventBus = new Vue();
window.onload = function () {
$(document).ready(function() {
navbarLeftCssTop = parseInt($('.navbar-left').css("top"));
windowHeight = $(window).height();
menubarHeight = $('ul.menubar').height();
documentHeight = $(document).height();
contentHeight = $('.content').height();
innerSectionHeight = $('.inner-section').height();
asideNavHeight = $('.aside-nav').height();
pageContentHeight = $('.page-content').height();
accordianHeight = $('.accordian').height();
window.addEventListener('DOMContentLoaded', function() {
moveDown = 60;
moveUp = -60;
count = 0;
countKeyUp = 0;
pageDown = 60;
pageUp = -60;
scroll = 0;
if (menubarHeight < windowHeight) {
differenceInHeight = windowHeight - menubarHeight;
} else {
differenceInHeight = menubarHeight - windowHeight;
}
listLastElement = $('.menubar li:last-child').offset();
lastElementOfNavBar = listLastElement.top;
if(pageContentHeight <= innerSectionHeight - 60) {
$('.navbar-left').css("position","absolute");
// $('.content').css({"position": "fixed", "width": "65%"});
// $('.content-wrapper').css({"position": "sticky", "top": "60px"});
}
else {
$('.accordian-header').on('click',function(event) {
pageContentHeightOnAccordianClick = $('.page-content').height();
navbarTop = $('.navbar-left').css("top");
menuTopValue = $('.navbar-left').css('top');
menubarTopValue = menuTopValue;
if(pageContentHeightOnAccordianClick <= innerSectionHeight) {
$('.navbar-left').css("position","absolute");
$('.content').css("position","fixed");
$('.content-wrapper').css({"position": "sticky", "top": "60px"});
}
});
}
documentHeight = $(document).height();
menubarHeight = $('ul.menubar').height();
navbarHeight = $('.navbar-left').height();
windowHeight = $(window).height();
contentHeight = $('.content').height();
innerSectionHeight = $('.inner-section').height();
gridHeight = $('.grid-container').height();
pageContentHeight = $('.page-content').height();
scrollTopWhenWindowLoaded = $(document).scrollTop();
if (menubarHeight <= windowHeight) {
differenceInHeight = windowHeight - menubarHeight;
} else {
differenceInHeight = menubarHeight - windowHeight;
}
if (menubarHeight > windowHeight) {
document.addEventListener("keydown", function(event) {
if ((event.keyCode == 38) && count <= 0) {
count = count + moveDown;
$('.navbar-left').css("top", count + "px");
} else if ((event.keyCode == 40) && count >= -differenceInHeight) {
count = count + moveUp;
$('.navbar-left').css("top", count + "px");
} else if ((event.keyCode == 33) && countKeyUp <= 0) {
countKeyUp = countKeyUp + pageDown;
$('.navbar-left').css("top", countKeyUp + "px");
} else if ((event.keyCode == 34) && countKeyUp >= -differenceInHeight) {
countKeyUp = countKeyUp + pageUp;
$('.navbar-left').css("top", countKeyUp + "px");
} else {
$('.navbar-left').css("position", "fixed");
}
});
$("body").css({minHeight: $(".menubar").outerHeight() + 100 + "px"});
window.addEventListener('scroll', function() {
documentScrollWhenScrolled = $(document).scrollTop();
if (menubarHeight > documentHeight && menubarHeight > windowHeight) {
$(document).scroll(function() {
documentScrollWhenScrolled = $(document).scrollTop();
if (documentScrollWhenScrolled <= differenceInHeight + 200) {
$('.navbar-left').css('top', documentScrollWhenScrolled + 60 + 'px');
$('.navbar-left').css('top', -documentScrollWhenScrolled + 60 + 'px');
scrollTopValueWhenNavBarFixed = $(document).scrollTop();
}
});
} else if (menubarHeight < windowHeight) {
$('.navbar-left').css("position", "fixed");
} else if (menubarHeight < documentHeight) {
if (scrollTopWhenWindowLoaded > differenceInHeight) {
$('.navbar-left').css('top', -differenceInHeight + 'px');
}
if (menubarHeight > windowHeight) {
$(document).scroll(function() {
documentScrollWhenScrolled = $(document).scrollTop();
if (documentScrollWhenScrolled <= differenceInHeight + 200) {
$('.navbar-left').css('top', -documentScrollWhenScrolled + 60 + 'px');
scrollTopValueWhenNavBarFixed = $(document).scrollTop();
}
});
} else if (menubarHeight < windowHeight) {
$(document).scroll(function() {
documentScrollWhenScrolled = $(document).scrollTop();
if (documentScrollWhenScrolled <= differenceInHeight + 70) {
$('.navbar-left').css('top', -documentScrollWhenScrolled + 60 + 'px');
scrollTopValueWhenNavBarFixed = $(document).scrollTop();
}
});
}
}
});
}
});
}
});
$(document).ready(function () {
Vue.config.ignoredElements = [

View File

@ -787,15 +787,23 @@ return [
'priority' => 'Priority',
'add-condition' => 'Add Conditions',
'disc_amt' => 'Discount Amount',
'disc_percent' => 'Discount Percentage'
'disc_percent' => 'Discount Percentage',
'is-coupon' => 'Use Coupon',
'is-coupon-yes' => 'Yes',
'is-coupon-no' => 'No',
'uses-per-cust' => 'Uses per customer',
],
'catalog' => [
'name' => 'Name',
'description' => 'Description',
'apply-percent' => 'Apply as percentage',
'apply-fixed' => 'Apply as fixed Amount',
'apply-fixed' => 'Apply as fixed amount',
'adjust-to-percent' => 'Adjust to percentage',
'adjust-to-value' => 'Adjust to discount value'
],
'cart' => [
'buy-atleast' => 'Buy Atleast (N)',
'apply-to-shipping' => 'Apply to shipping'
]
],

View File

@ -1,12 +1,12 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.promotion.add-catalog-rule') }}
{{ __('admin::app.promotion.add-cart-rule') }}
@stop
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.catalog-rule.store') }}" @submit.prevent="onSubmit">
<form method="POST" action="{{ route('admin.cart-rule.store') }}" @submit.prevent="onSubmit">
@csrf
<div class="page-header">
@ -14,7 +14,7 @@
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
{{ __('admin::app.promotion.add-catalog-rule') }}
{{ __('admin::app.promotion.add-cart-rule') }}
</h1>
</div>
@ -27,14 +27,14 @@
<div class="page-content">
<div class="form-container">
<catalog-rule></catalog-rule>
<cart-rule></cart-rule>
</div>
</div>
</form>
</div>
@push('scripts')
<script type="text/x-template" id="catalog-rule-form-template">
<script type="text/x-template" id="cart-rule-form-template">
<div>
@csrf()
@ -44,6 +44,7 @@
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
<input type="text" class="control" name="name" v-model="name" v-validate="'required'" value="{{ old('name') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.name') }}&quot;">
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
@ -51,6 +52,7 @@
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
<textarea class="control" name="description" v-model="description" v-validate="'required'" value="{{ old('description') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.description') }}&quot;"></textarea>
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
</div>
@ -69,15 +71,36 @@
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;" multiple="multiple">
<option disabled="disabled">Select Channels</option>
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channels[]')">@{{ errors.first('channels') }}</span>
</div>
<div class="control-group" :class="[errors.has('is_coupon') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.is-coupon') }}</label>
<select type="text" class="control" name="is_coupon" v-model="is_coupon" v-validate="'required'" value="{{ old('is_coupon') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.is-coupon') }}&quot;">
<option value="0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('is_coupon')">@{{ errors.first('is_coupon') }}</span>
</div>
<div class="control-group" :class="[errors.has('uses_per_cust') ? 'has-error' : '']">
<label for="uses_per_cust" class="required">{{ __('admin::app.promotion.general-info.uses-per-cust') }}</label>
<input type="number" step="1" class="control" name="uses_per_cust" v-model="uses_per_cust" v-validate="'required|numeric|min_value:1'" value="{{ old('uses_per_cust') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.uses-per-cust') }}&quot;">
<span class="control-error" v-if="errors.has('uses_per_cust')">@{{ errors.first('uses_per_cust') }}</span>
</div>
<datetime :name="starts_from">
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
<label for="starts_from" class="required">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
@ -101,7 +124,7 @@
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
<input type="text" class="control" name="priority" v-model="priority" v-validate="'required|numeric|max:1'" value="{{ old('priority') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.priority') }}&quot;">
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.priority') }}&quot;">
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
</div>
@ -115,8 +138,8 @@
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
<select type="text" class="control" name="criteria" v-model="criteria" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;">
<option value="attribute">Attribute</option>
<option value="category">Category</option>
<option value="cart">Cart Attribute</option>
<option value="product_subselection">Product's subselection</option>
</select>
<span class="control-error" v-if="errors.has('criteria')">@{{ errors.first('criteria') }}</span>
@ -126,49 +149,37 @@
</div>
<div class="condition-set">
<!-- Attribute -->
<div v-for="(attr, index) in attrs" :key="index">
<!-- Cart Attribute -->
<div v-for="(cart_attr, index) in cart_attrs" :key="index">
<div class="control-container mt-20">
<div class="title-bar">
<span>Attribute is </span>
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
<span>Cart Attribute is </span>
<span class="icon cross-icon" v-on:click="removeCartAttr(index)"></span>
</div>
<div class="control-group mt-10" :key="index">
<select class="control" name="attributes[]" v-model="attrs[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;">
<select class="control" name="cart_attributes[]" v-model="cart_attrs[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;">
<option disabled="disabled">Select attribute</option>
<option v-for="attribute in attributes" :value="attribute.id">@{{ attribute.name }}</option>
<option v-for="(cart_attribute, index) in cart_attributes" :value="cart_attribute.id" :key="index">@{{ cart_attribute.name }}</option>
</select>
<select class="control" name="attributes[]" v-model="attrs[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option>is</option>
<option>is any of</option>
<option>contains</option>
</select>
<div v-if='cart_attrs[index].type == "string"'>
<select class="control" name="cart_attributes[]" v-model="cart_attrs[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option v-for="(cart_attribute, index) in cart_attributes.conditions.text" value="cart_attribute" :key="index">@{{ cart_attribute }}</option>
</select>
<input type="text" class="control" name="attributes[]" v-model="attrs[index].value" placeholder="Enter Value(s)" title="Use comma for multiple values">
</div>
</div>
</div>
<input type="text" class="control" name="cart_attributes[]" v-model="cart_attrs[index].value" placeholder="Enter Value">
</div>
<!-- category -->
<div v-for="(cat, index) in cats">
<div class="control-container mt-20">
<div class="title-bar">
<span>Category </span>
<span class="icon cross-icon" v-on:click="removeCat(index)"></span>
</div>
<div v-if='cart_attrs[index].type == "numeric"'>
<select class="control" name="attributes[]" v-model="cart_attrs[index].condition" v-validate="'required'" style="margin-right: 15px;">
<option v-for="(cart_attribute, index) in cart_attributes.conditions.numeric" value="cart_attribute" :key="index">@{{ cart_attribute }}</option>
</select>
<div class="control-group mt-15" :key="index">
<select class="control" name="categories[]" v-model="cats[index].condition" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;">
<option>is</option>
<option>is any of</option>
<option>contains</option>
</select>
<select class="control" name="categories[]" v-model="cats[index].category" v-validate="'required'" value="{{ old('category') }}" data-vv-as="&quot;{{ __('admin::app.promotion.category') }}&quot;" multiple>
<option disabled="disabled">Select Category</option>
<option v-for="category in categories" :value="category.id">@{{ category.name }}</option>
</select>
<input type="number" step="0.1000" class="control" name="cart_attributes[]" v-model="cart_attrs[index].value" placeholder="Enter Value">
</div>
</div>
</div>
</div>
@ -191,25 +202,49 @@
<span class="control-error" v-if="errors.has('apply')">@{{ errors.first('apply') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_amt') ? 'has-error' : '']" v-if="apply_amt">
<label for="disc_amt" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="text" class="control" name="disc_amt" v-model="disc_amt" v-validate="'required|numeric'" value="{{ old('disc_amt') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amt')">@{{ errors.first('disc_amt') }}</span>
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']" v-if="apply_amt">
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="number" step="1.0000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_percent') ? 'has-error' : '']" v-if="apply_prct">
<label for="disc_percent" class="required">{{ __('admin::app.promotion.general-info.disc_percent') }}</label>
<input type="text" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|numeric'" value="{{ old('disc_percent') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_percent') }}&quot;">
<input type="number" step="0.5000" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_percent') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_percent') }}&quot;">
<span class="control-error" v-if="errors.has('disc_percent')">@{{ errors.first('disc_percent') }}</span>
</div>
<div class="control-group" :class="[errors.has('buy_atleast') ? 'has-error' : '']">
<label for="buy_atleast" class="required">{{ __('admin::app.promotion.cart.buy-atleast') }}</label>
<input type="number" step="1" class="control" name="buy_atleast" v-model="buy_atleast" v-validate="'required|numeric|min_value:1'" value="{{ old('buy_atleast') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.buy-atleast') }}&quot;">
<span class="control-error" v-if="errors.has('buy_atleast')">@{{ errors.first('buy_atleast') }}</span>
</div>
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as="&quot;{{ __('admin::app.promotion.cart.apply-to-shipping') }}&quot;">
<option value="0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
<option value="1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
</select>
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
</div>
</div>
</accordian>
</div>
</script>
<script>
Vue.component('catalog-rule', {
template: '#catalog-rule-form-template',
Vue.component('cart-rule', {
template: '#cart-rule-form-template',
inject: ['$validator'],
@ -218,21 +253,16 @@
apply: null,
apply_amt: false,
apply_prct: false,
attributes: @json($criteria[0]),
attr: {
apply_to_shipping: null,
buy_atleast: null,
cart_attributes: @json($criteria[0]).cart,
cart_attr: {
attribute: null,
condition: null,
value: null
},
attrs: [],
attrs_count: 0,
cat: {
category: null,
condition: null,
},
categories: @json($criteria[1]),
cats: [],
cats_count: 0,
cart_attrs: [],
cart_attrs_count: 0,
channels: [],
conditions: [],
criteria: null,
@ -242,9 +272,11 @@
disc_percent: 0.0,
ends_till: null,
end_other_rules: null,
is_coupon: null,
name: null,
priority: 0,
starts_from: null
starts_from: null,
uses_per_cust: 0,
}
},
@ -253,7 +285,9 @@
methods: {
addCondition () {
if (this.criteria == 'attribute' || this.criteria == 'category') {
console.log(this.criteria);
if (this.criteria == 'product_subselection' || this.criteria == 'cart') {
this.condition_on = this.criteria;
} else {
alert('please try again');
@ -261,21 +295,21 @@
return false;
}
if (this.condition_on == 'attribute') {
this.attrs.push(this.attr);
if (this.condition_on == 'cart') {
this.cart_attrs.push(this.cart_attr);
this.attr = {
this.cart_attr = {
attribute: null,
condition: null,
value: null
};
} else if (this.condition_on == 'category') {
this.cats.push(this.cat);
} else if (this.condition_on == 'product_subselection') {
// this.cats.push(this.cat);
this.cat = {
category: null,
condition: null
};
// this.cat = {
// category: null,
// condition: null
// };
}
},
@ -289,8 +323,8 @@
}
},
removeAttr(index) {
this.attrs.splice(index, 1);
removeCartAttr(index) {
this.cart_attrs.splice(index, 1);
},
removeCat(index) {

View File

@ -44,6 +44,7 @@
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
<input type="text" class="control" name="name" v-model="name" v-validate="'required'" value="{{ old('name') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.name') }}&quot;">
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
@ -51,6 +52,7 @@
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
<textarea class="control" name="description" v-model="description" v-validate="'required'" value="{{ old('description') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.description') }}&quot;"></textarea>
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
</div>
@ -69,12 +71,14 @@
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" value="{{ old('channels') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.cust-groups') }}&quot;" multiple="multiple">
<option disabled="disabled">Select Channels</option>
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channels[]')">@{{ errors.first('channels') }}</span>
</div>
@ -101,7 +105,7 @@
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
<input type="text" class="control" name="priority" v-model="priority" v-validate="'required|numeric|max:1'" value="{{ old('priority') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.priority') }}&quot;">
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.priority') }}&quot;">
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
</div>
@ -133,6 +137,7 @@
<span>Attribute is </span>
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
</div>
<div class="control-group mt-10" :key="index">
<select class="control" name="attributes[]" v-model="attrs[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;">
<option disabled="disabled">Select attribute</option>
@ -191,15 +196,19 @@
<span class="control-error" v-if="errors.has('apply')">@{{ errors.first('apply') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_amt') ? 'has-error' : '']" v-if="apply_amt">
<label for="disc_amt" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="text" class="control" name="disc_amt" v-model="disc_amt" v-validate="'required|numeric'" value="{{ old('disc_amt') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amt')">@{{ errors.first('disc_amt') }}</span>
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']" v-if="apply_amt">
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
<input type="number" step="1.0000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_amt') }}&quot;">
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
</div>
<div class="control-group" :class="[errors.has('disc_percent') ? 'has-error' : '']" v-if="apply_prct">
<label for="disc_percent" class="required">{{ __('admin::app.promotion.general-info.disc_percent') }}</label>
<input type="text" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|numeric'" value="{{ old('disc_percent') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_percent') }}&quot;">
<input type="number" step="0.5000" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_percent') }}" data-vv-as="&quot;{{ __('admin::app.promotion.general-info.disc_percent') }}&quot;">
<span class="control-error" v-if="errors.has('disc_percent')">@{{ errors.first('disc_percent') }}</span>
</div>
</div>

View File

@ -0,0 +1,55 @@
<?php
return [
'catalog' => [
0 => 'Apply as percentage',
1 => 'Apply as fixed amount',
2 => 'Adjust to percentage',
3 => 'Adjust to discount value'
],
'cart' => [
0 => [
'name' => 'Sub-total',
'type' => 'numeric'
],
1 => [
'name' => 'Total Items Quantity',
'type' => 'numeric'
],
2 => [
'name' => 'Total Weight',
'type' => 'numeric'
],
3 => [
'name' => 'Payment Method',
'type' => 'string'
],
4 => [
'name' => 'Shipping Postcode',
'type' => 'string'
],
5 => [
'name' => 'Shipping State',
'type' => 'string'
],
6 => [
'name' => 'Shipping Country',
'type' => 'string'
]
],
'conditions' => [
'numeric' => [
0 => 'Greater than',
1 => 'Lesser than',
2 => 'Equals'
],
'text' => [
0 => 'is',
1 => 'is any of',
2 => 'contains'
],
]
];

View File

@ -84,7 +84,7 @@ class CartRuleController extends Controller
public function create()
{
return view($this->_config['view'])->with('criteria', [$this->attribute->getNameAndId(), $this->category->getNameAndId()]);
return view($this->_config['view'])->with('criteria', [config('pricerules')]);
}
public function store()

View File

@ -58,23 +58,11 @@ class CatalogRuleController extends Controller
public function __construct(Attribute $attribute, AttributeFamily $attributeFamily, Category $category, Product $product, CatalogRule $catalogRule)
{
$this->_config = request('_config');
$this->attribute = $attribute;
$this->attributeFamily = $attributeFamily;
$this->category = $category;
$this->product = $product;
$this->catalogRule = $catalogRule;
$this->appliedConfig = [
0 => trans('admin::app.promotion.catalog.apply-percent'),
1 => trans('admin::app.promotion.catalog.apply-fixed'),
2 => trans('admin::app.promotion.catalog.adjust-to-percent'),
3 => trans('admin::app.promotion.catalog.adjust-to-value')
];
}
public function index()

View File

@ -24,6 +24,16 @@ class DiscountServiceProvider extends ServiceProvider
*/
public function register()
{
$this->registerConfig();
}
/**
* To merge the price rule configuration in price rule configuration
*/
protected function registerConfig()
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/cart-attributes.php', 'pricerules'
);
}
}

View File

@ -7,8 +7,6 @@ use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Webkul\Product\Http\Requests\ProductForm;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Repositories\ProductGridRepository as ProductGrid;
use Webkul\Product\Repositories\ProductFlatRepository as ProductFlat;
use Webkul\Product\Repositories\ProductAttributeValueRepository as ProductAttributeValue;
use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily;
use Webkul\Category\Repositories\CategoryRepository as Category;
@ -58,21 +56,20 @@ class ProductController extends Controller
protected $product;
/**
* ProductGrid Repository object
* ProductAttributeValueRepository object
*
* @var array
*/
protected $productGrid;
protected $productFlat;
protected $productAttributeValue;
/**
* Create a new controller instance.
*
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamily
* @param \Webkul\Category\Repositories\CategoryRepository $category
* @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySource
* @param \Webkul\Product\Repositories\ProductRepository $product
* @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamily
* @param \Webkul\Category\Repositories\CategoryRepository $category
* @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySource
* @param \Webkul\Product\Repositories\ProductRepository $product
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $productAttributeValue
* @return void
*/
public function __construct(
@ -80,9 +77,8 @@ class ProductController extends Controller
Category $category,
InventorySource $inventorySource,
Product $product,
ProductGrid $productGrid,
ProductFlat $productFlat,
ProductAttributeValue $productAttributeValue)
ProductAttributeValue $productAttributeValue
)
{
$this->attributeFamily = $attributeFamily;
@ -92,10 +88,6 @@ class ProductController extends Controller
$this->product = $product;
$this->productGrid = $productGrid;
$this->productFlat = $productFlat;
$this->productAttributeValue = $productAttributeValue;
$this->_config = request('_config');
@ -173,8 +165,6 @@ class ProductController extends Controller
$inventorySources = $this->inventorySource->all();
$allProducts = $this->productGrid->all();
return view($this->_config['view'], compact('product', 'categories', 'inventorySources', 'allProducts'));
}

View File

@ -14,7 +14,7 @@
<div class="product-image">
<a href="{{ route('shop.products.index', $product->url_key) }}" title="{{ $product->name }}">
<img src="{{ $productBaseImage['medium_image_url'] }}" />
<img src="{{ $productBaseImage['medium_image_url'] }}" onerror="this.src='{{ asset('vendor/webkul/ui/assets/images/product/meduim-product-placeholder.png') }}'"/>
</a>
</div>

View File

@ -0,0 +1,49 @@
<?php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ProductCategoryTest extends DuskTestCase
{
/**
* A basic browser test example.
*
* @return void
*/
public function testGuestAddToCart()
{
$categories = app('Webkul\Category\Repositories\CategoryRepository')->all();
$products = app('Webkul\Product\Repositories\ProductRepository')->all();
$slugs = array();
foreach ($categories as $category) {
if ($category->slug != 'root') {
array_push($slugs, $category->slug);
}
}
$slugIndex = array_rand($slugs);
$testSlug = $slugs[$slugIndex];
$testProduct = array();
foreach ($products as $product) {
$categories = $product->categories;
if ($categories->last()->slug == $testSlug) {
array_push($testProduct, ['name' => $product->name, 'url_key' => $product->url_key]);
break;
}
}
$this->browse(function (Browser $browser) use($testSlug, $testProduct) {
$browser->visit(route('shop.categories.index', $testSlug));
$browser->assertSeeLink($testProduct[0]['name']);
$browser->pause(5000);
});
}
}