Optimization in exception handling for separate admin and shop providers, whilst convertxtoproductid is in UI development

This commit is contained in:
Prashant Singh 2019-07-14 07:30:16 +05:30
parent 5f08f2b9f4
commit 42d067c44a
10 changed files with 232 additions and 46 deletions

View File

@ -8,7 +8,7 @@ return [
], [
'key' => 'catalog.products',
'name' => 'admin::app.admin.system.products',
'sort' => 1,
'sort' => 2
], [
'key' => 'catalog.products.review',
'name' => 'admin::app.admin.system.review',
@ -39,7 +39,7 @@ return [
], [
'key' => 'customer',
'name' => 'admin::app.admin.system.customer',
'sort' => 2,
'sort' => 3,
], [
'key' => 'customer.settings',
'name' => 'admin::app.admin.system.settings',

View File

@ -28,7 +28,7 @@ class Handler extends ExceptionHandler
*/
public function render($request, Exception $exception)
{
$path = $this->isAdminUri() ? 'admin' : 'shop';
$path = 'admin';
if ($exception instanceof HttpException) {
$statusCode = in_array($exception->getStatusCode(), [401, 403, 404, 503]) ? $exception->getStatusCode() : 500;

View File

@ -815,20 +815,17 @@ return [
'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',
'select-products' => 'Select product attributes',
'select-products' => 'How to choose products ?',
'select-category' => 'Select Categories',
'select-attribute' => 'Select Attributes',
'general-info' => [
'sku-like' => 'SKU Like',
'on-shipping' => 'If applied on shipping',
'discount' => 'Discount',
'to-be-applied' => 'Applied On',
'applied-on-info' => 'It signifies how cart rule should be applied on items in cart',
'shipping-apply-info' => 'It signifies how rule behaves when it is used for shipping',
'general-info' => 'General Info',
'config' => 'Configure',
'options' => 'Options',
'name' => 'Rule Name',
'description' => 'Description',
'starts-from' => 'Start',

View File

@ -343,24 +343,61 @@
<accordian :active="true" title="{{ __('admin::app.promotion.select-products') }}">
<div slot="body">
<div class="control-group" :class="[errors.has('categories') ? 'has-error' : '']">
<div class="control-group" :class="[errors.has('category_values') ? 'has-error' : '']">
<label class="mb-10" for="categories">{{ __('admin::app.promotion.select-category') }}</label>
<multiselect v-model="categories" :options="options" :searchable="false" :close-on-select="false" :allow-empty="true" :show-labels="true" placeholder="Select Categories" :multiple="true" :hide-selected="true" :taggable="true" @tag="addTag"></multiselect>
<multiselect v-model="category_values" :options="category_options" :searchable="false" :custom-label="categoryLabel" :show-labels="true" placeholder="Select Categories" track-by="slug" :multiple="true" :taggable="true" @tag="categoryTag"></multiselect>
<pre>
<code>@{{ value }}</code>
</pre>
@{{ category_values }}
</div>
<div class="control-group" :class="[errors.has('attributes') ? 'has-error' : '']">
<label class="mb-10" for="attributes">{{ __('admin::app.promotion.select-category') }}</label>
{{-- <div class="control-group" :class="[errors.has('attribute_values') ? 'has-error' : '']">
<label class="mb-10" for="attribute_values">{{ __('admin::app.promotion.select-attribute') }}</label>
<multiselect v-model="attributes" :options="options" :searchable="false" :close-on-select="false" :allow-empty="true" :show-labels="true" placeholder="Select Categories" :multiple="true" :hide-selected="true" :taggable="true" @tag="addTag"></multiselect>
<multiselect v-model="attribute_values" :options="attribute_options" :searchable="false" :custom-label="attributeLabel" :show-labels="true" placeholder="Select Attributes" track-by="code" :multiple="true" :taggable="true" @tag="categoryTag"></multiselect>
<pre>
<code>@{{ value }}</code>
</pre>
@{{ attribute_values }}
</div> --}}
<div class="control-container mt-20" v-for="(condition, index) in attribute_list" :key="index">
<select class="control" name="attributes[]" v-model="attribute_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 v-if='attribute_list[index].type == "string"' style="display: flex">
<select class="control" name="cart_attributes[]" v-model="attribute_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='attribute_list[index].attribute == "shipping_state"'>
<select class="control" v-model="attribute_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='attribute_list[index].attribute == "shipping_country"'>
<select class="control" v-model="attribute_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="attribute_list[index].value" placeholder="Enter Value" v-if='attribute_list[index].attribute != "shipping_state" && attribute_list[index].attribute != "shipping_country"'>
</div>
<div v-if='attribute_list[index].type == "numeric"' style="display: flex">
<select class="control" name="attributes[]" v-model="attribute_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="attribute_list[index].value" placeholder="Enter Value">
</div>
<span class="icon trash-icon" v-on:click="removeCartAttr(index)"></span>
</div>
</div>
</accordian>
@ -404,10 +441,6 @@
data () {
return {
options: [
1, 2, 3, 4, 5, 6
],
categories: null,
name: null,
description: null,
conditions_list: [],
@ -463,13 +496,20 @@
condition: null,
value: []
},
country_and_states: @json($cart_rule[2])
country_and_states: @json($cart_rule[2]),
category_options: @json($cart_rule[1]),
category_values: null,
attribute_list: [],
attribute_input: @json($cart_rule[3]),
attribute_options: [],
attribute_values: []
}
},
methods: {
addTag (newTag) {
categoryTag (newTag) {
const tag = {
name: newTag,
code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
@ -479,6 +519,14 @@
this.value.push(tag)
},
categoryLabel (category_options) {
return category_options.name + ' [ ' + category_options.slug + ' ]';
},
attributeLabel (attribute_options) {
return attribute_options.name + ' [ ' + attribute_options.type + ' ]';
},
addCondition () {
if (this.criteria == 'product_subselection' || this.criteria == 'cart') {
this.condition_on = this.criteria;
@ -567,6 +615,18 @@
pre {
position: absolute;
}
.multiselect__tag {
background: #4CAF50;
}
.multiselect__option--selected.multiselect__option--highlight {
background: rgba(0, 64, 255, 0.6);
}
.multiselect__option--highlight {
background: #4CAF50;
}
</style>
@endpush
@stop

View File

@ -225,7 +225,7 @@ class AttributeRepository extends Repository
'id' => $attribute->id,
'name' => $attribute->name,
'type' => $attribute->type,
'code' => $attribute->code
'code' => $attribute->code,
]);
}
}

View File

@ -213,7 +213,7 @@ class CategoryRepository extends Repository
}
}
public function getPartial()
public function getPartial($columns = null)
{
$categories = $this->model->all();
$trimmed = array();
@ -222,7 +222,8 @@ class CategoryRepository extends Repository
if ($category->name != null || $category->name != "") {
$trimmed[$key] = [
'id' => $category->id,
'name' => $category->name
'name' => $category->name,
'slug' => $category->slug
];
}
}

View File

@ -11,25 +11,25 @@ return [
'sort' => 1
], [
'key' => 'discount.cart-rules.settings',
'name' => 'admin::app.promotion.general-info.config',
'name' => 'admin::app.promotion.general-info.options',
'sort' => 1,
'fields' => [
[
'name' => 'applied_on',
'title' => 'admin::app.promotion.general-info.to-be-applied',
'name' => 'if_applied_on_shipping',
'title' => 'admin::app.promotion.general-info.on-shipping',
'type' => 'select',
'validation' => 'required',
'channel_based' => true,
'locale_based' => false,
'options' => [
[
'title' => 'Least Worth Item',
'value' => 0
'title' => 'W.R.T grand total',
'value' => 'grand_total'
], [
'title' => 'Max Worth Item',
'title' => 'W.R.T sub total',
'value' => 1
], [
'title' => 'All Items',
'title' => 'W.R.T shipping total',
'value' => 2
], [
'title' => 'Please select an option',
@ -37,7 +37,7 @@ return [
]
],
'info' => 'admin::app.promotion.general-info.applied-on-info'
'info' => 'admin::app.promotion.general-info.shipping-apply-info'
]
]
],

View File

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

View File

@ -3,7 +3,8 @@
namespace Webkul\Discount\Http\Controllers;
use Webkul\Discount\Repositories\CartRuleRepository as CartRule;
use Webkul\Checkout\Repositories\CartRepository as Cart;
use Webkul\Category\Repositories\CategoryRepository as Category;
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
use Webkul\Discount\Repositories\CartRuleLabelsRepository as CartRuleLabels;
use Webkul\Discount\Repositories\CartRuleCouponsRepository as CartRuleCoupons;
@ -40,6 +41,16 @@ class CartRuleController extends Controller
*/
protected $cartRuleCoupon;
/**
* To hold category repository instance
*/
protected $category;
/**
* To hold attribute repository instance
*/
protected $attribute;
/**
* To hold the cart repository instance
*/
@ -48,7 +59,9 @@ class CartRuleController extends Controller
public function __construct(
CartRule $cartRule,
CartRuleCoupons $cartRuleCoupon,
CartRuleLabels $cartRuleLabel
CartRuleLabels $cartRuleLabel,
Attribute $attribute,
Category $category
)
{
$this->_config = request('_config');
@ -59,6 +72,10 @@ class CartRuleController extends Controller
$this->cartRuleLabel = $cartRuleLabel;
$this->attribute = $attribute;
$this->category = $category;
$this->appliedConfig = config('pricerules.cart');
}
@ -75,7 +92,7 @@ class CartRuleController extends Controller
*/
public function create()
{
return view($this->_config['view'])->with('cart_rule', [$this->appliedConfig, [], $this->getStatesAndCountries()]);
return view($this->_config['view'])->with('cart_rule', [$this->appliedConfig, $this->category->getPartial(), $this->getStatesAndCountries(), $this->attribute->getPartial()]);
}
/**
@ -141,11 +158,11 @@ class CartRuleController extends Controller
// prepare json object from actions
if (isset($data['disc_amount']) && $data['action_type'] == config('pricerules.cart.validations.2')) {
$data['actions'] = [
'action_type' => $data['action_type'],
'disc_amount' => $data['disc_amount'],
'disc_threshold' => $data['disc_threshold']
];
$data['actions'] = [
'action_type' => $data['action_type'],
'disc_amount' => $data['disc_amount'],
'disc_threshold' => $data['disc_threshold']
];
$data['disc_quantity'] = $data['disc_amount'];
} else {

View File

@ -0,0 +1,79 @@
<?php
namespace Webkul\Shop\Exceptions;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\PDOException;
use Illuminate\Database\Eloquent\ErrorException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
protected $jsonErrorMessages = [
404 => 'Resource not found',
403 => '403 forbidden Error',
401 => 'Unauthenticated',
500 => '500 Internal Server Error',
];
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
$path = 'shop';
if ($exception instanceof HttpException) {
$statusCode = in_array($exception->getStatusCode(), [401, 403, 404, 503]) ? $exception->getStatusCode() : 500;
return $this->response($path, $statusCode);
} else if ($exception instanceof ModelNotFoundException) {
return $this->response($path, 404);
} else if ($exception instanceof PDOException) {
return $this->response($path, 500);
}
return parent::render($request, $exception);
}
/**
* Convert an authentication exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => $this->jsonErrorMessages[401]], 401);
}
return redirect()->guest(route('auth.login'));
}
private function isSopUri()
{
return strpos($_SERVER['REQUEST_URI'], 'shop') !== false ? true : false;
}
private function response($path, $statusCode)
{
if (request()->expectsJson()) {
return response()->json([
'error' => isset($this->jsonErrorMessages[$statusCode])
? $this->jsonErrorMessages[$statusCode]
: 'Something went wrong, please try again later.'
], $statusCode);
}
return response()->view("{$path}::errors.{$statusCode}", [], $statusCode);
}
}