Merge branch 'master' of https://github.com/bagisto/bagisto into development

This commit is contained in:
Prashant Singh 2019-02-22 16:15:16 +05:30
commit 33a58daa35
17 changed files with 300 additions and 147 deletions

View File

@ -0,0 +1,33 @@
<?php
return [
[
'key' => 'catalog',
'name' => 'Catalog',
'sort' => 1
], [
'key' => 'catalog.products',
'name' => 'Products',
'sort' => 1,
], [
'key' => 'catalog.products.review',
'name' => 'Review',
'sort' => 1,
'fields' => [
[
'name' => 'guest_review',
'title' => 'Allow Guest Review',
'type' => 'select',
'options' => [
[
'title' => 'Yes',
'value' => true
], [
'title' => 'No',
'value' => false
]
],
]
]
],
];

View File

@ -44,7 +44,7 @@ class AdminServiceProvider extends ServiceProvider
Handler::class
);
}
/**
* Register services.
*
@ -115,7 +115,7 @@ class AdminServiceProvider extends ServiceProvider
return $tree;
}
/**
* Register package config.
*
@ -130,5 +130,9 @@ class AdminServiceProvider extends ServiceProvider
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/acl.php', 'acl'
);
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php', 'core'
);
}
}

View File

@ -771,7 +771,8 @@ return [
'xls' => 'XLS',
'file' => 'File',
'upload-error' => 'The file must be a file of type: xls, xlsx, csv.',
'duplicate-error' => 'Identifier must be unique, duplicate identifier :identifier at row :position.'
'duplicate-error' => 'Identifier must be unique, duplicate identifier :identifier at row :position.',
'enough-row-error' => 'file has not enough rows'
],
'response' => [

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterProductReviewsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('product_reviews', function (Blueprint $table) {
$table->string('name');
$table->dropForeign('product_reviews_customer_id_foreign');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

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

View File

@ -9,7 +9,7 @@ use Webkul\Product\Contracts\ProductReview as ProductReviewContract;
class ProductReview extends Model implements ProductReviewContract
{
protected $fillable = ['comment', 'title', 'rating', 'status', 'product_id', 'customer_id'];
protected $fillable = ['comment', 'title', 'rating', 'status', 'product_id', 'customer_id', 'name'];
/**
* Get the product attribute family that owns the product.

View File

@ -30,7 +30,7 @@ return [
], [
'name' => 'active',
'title' => 'Status',
'type' => 'select',
'type' => 'multiselect',
'options' => [
[
'title' => 'Active',

View File

@ -0,0 +1,88 @@
<?php
namespace Webkul\Shop\DataGrids;
use Webkul\Ui\DataGrid\DataGrid;
use DB;
/**
* OrderDataGrid class
*
* @author Rahul Shukla <rahulshkla.symfont517@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class OrderDataGrid extends DataGrid
{
protected $index = 'id'; //the column that needs to be treated as index column
protected $sortOrder = 'desc'; //asc or desc
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('orders as order')
->addSelect('order.id', 'order.status', 'order.created_at', 'order.grand_total')
->where('customer_id', auth()->guard('customer')->user()->id);
$this->setQueryBuilder($queryBuilder);
}
public function addColumns()
{
$this->addColumn([
'index' => 'id',
'label' => trans('shop::app.customer.account.order.index.order_id'),
'type' => 'number',
'searchable' => false,
'sortable' => true,
]);
$this->addColumn([
'index' => 'created_at',
'label' => trans('shop::app.customer.account.order.index.date'),
'type' => 'datetime',
'searchable' => true,
'sortable' => true,
]);
$this->addColumn([
'index' => 'grand_total',
'label' => trans('shop::app.customer.account.order.index.total'),
'type' => 'price',
'searchable' => true,
'sortable' => true,
]);
$this->addColumn([
'index' => 'status',
'label' => trans('shop::app.customer.account.order.index.status'),
'type' => 'string',
'searchable' => false,
'sortable' => true,
'closure' => true,
'wrapper' => function ($value) {
if ($value->status == 'processing')
return '<span class="badge badge-md badge-success">Processing</span>';
else if ($value->status == 'completed')
return '<span class="badge badge-md badge-success">Completed</span>';
else if ($value->status == "canceled")
return '<span class="badge badge-md badge-danger">Canceled</span>';
else if ($value->status == "closed")
return '<span class="badge badge-md badge-info">Closed</span>';
else if ($value->status == "pending")
return '<span class="badge badge-md badge-warning">Pending</span>';
else if ($value->status == "pending_payment")
return '<span class="badge badge-md badge-warning">Pending Payment</span>';
else if ($value->status == "fraud")
return '<span class="badge badge-md badge-danger">Fraud</span>';
}
]);
}
public function prepareActions() {
$this->addAction([
'type' => 'View',
'route' => 'customer.orders.view',
'icon' => 'icon eye-icon'
]);
}
}

View File

@ -65,7 +65,8 @@ class OrderController extends Controller
*
* @return \Illuminate\Http\Response
*/
public function index() {
public function index()
{
$orders = $this->order->findWhere([
'customer_id' => auth()->guard('customer')->user()->id
]);

View File

@ -46,8 +46,6 @@ class ReviewController extends Controller
*/
public function __construct(Product $product, ProductReview $productReview)
{
$this->middleware('customer')->only(['create', 'store', 'destroy']);
$this->product = $product;
$this->productReview = $productReview;
@ -65,7 +63,9 @@ class ReviewController extends Controller
{
$product = $this->product->findBySlugOrFail($slug);
return view($this->_config['view'], compact('product'));
$guest_review = core()->getConfigData('catalog.products.review.guest_review');
return view($this->_config['view'], compact('product', 'guest_review'));
}
/**
@ -84,11 +84,13 @@ class ReviewController extends Controller
$data = request()->all();
$customer_id = auth()->guard('customer')->user()->id;
if (auth()->guard('customer')->user()) {
$data['customer_id'] = auth()->guard('customer')->user()->id;
$data['name'] = auth()->guard('customer')->user()->first_name .' ' . auth()->guard('customer')->user()->last_name;
}
$data['status'] = 'pending';
$data['product_id'] = $id;
$data['customer_id'] = $customer_id;
$this->productReview->create($data);

View File

@ -106,7 +106,7 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function
// Show Product Review Form Store
Route::post('/product/{slug}/review', 'Webkul\Shop\Http\Controllers\ReviewController@store')->defaults('_config', [
'redirect' => 'customer.reviews.index'
'redirect' => 'shop.home.index'
])->name('shop.reviews.store');
//customer routes starts here

View File

@ -80,7 +80,8 @@ return [
'ratingreviews' => ':rating Ratings & :review Reviews',
'star' => 'Star',
'percentage' => ':percentage %',
'id-star' => 'star'
'id-star' => 'star',
'name' => 'Name'
],
'customer' => [

View File

@ -23,71 +23,10 @@
{!! view_render_event('bagisto.shop.customers.account.orders.list.before', ['orders' => $orders]) !!}
<div class="account-items-list">
<div class="account-table-content">
<div class="table">
<table>
<thead>
<tr>
<th> {{ __('shop::app.customer.account.order.index.order_id') }}</th>
<th> {{ __('shop::app.customer.account.order.index.date') }} </th>
<th> {{ __('shop::app.customer.account.order.index.total') }} </th>
<th> {{ __('shop::app.customer.account.order.index.status')}} </th>
</tr>
</thead>
<tbody>
@foreach ($orders as $order)
<tr>
<td data-value="{{ __('shop::app.customer.account.order.index.order_id') }}">
<a href="{{ route('customer.orders.view', $order->id) }}">
#{{ $order->id }}
</a>
</td>
<td data-value="{{ __('shop::app.customer.account.order.index.date') }}">{{ core()->formatDate($order->created_at, 'd M Y') }}</td>
<td data-value="{{ __('shop::app.customer.account.order.index.total') }}">
{{ core()->formatPrice($order->grand_total, $order->order_currency_code) }}
</td>
<td data-value="{{ __('shop::app.customer.account.order.index.status') }}">
@if($order->status == 'processing')
<span class="badge badge-md badge-success">Processing</span>
@elseif ($order->status == 'completed')
<span class="badge badge-md badge-success">Completed</span>
@elseif ($order->status == "canceled")
<span class="badge badge-md badge-danger">Canceled</span>
@elseif ($order->status == "closed")
<span class="badge badge-md badge-info">Closed</span>
@elseif ($order->status == "pending")
<span class="badge badge-md badge-warning">Pending</span>
@elseif ($order->status == "pending_payment")
<span class="badge badge-md badge-warning">Pending Payment</span>
@elseif ($order->status == "fraud")
<span class="badge badge-md badge-danger">Fraud</span>
@endif
</td>
</tr>
@endforeach
@if (! $orders->count())
<tr>
<td class="empty" colspan="10" style="text-align: center;">{{ __('admin::app.common.no-result-found') }}</td>
<tr>
@endif
</tbody>
</table>
</div>
@inject('order','Webkul\Shop\DataGrids\OrderDataGrid')
{!! $order->render() !!}
</div>
@if (!$orders->count())
<div class="responsive-empty">{{ __('admin::app.common.no-result-found') }}</div>
@endif
</div>
{!! view_render_event('bagisto.shop.customers.account.orders.list.after', ['orders' => $orders]) !!}

View File

@ -75,6 +75,16 @@
<span class="control-error" v-if="errors.has('title')">@{{ errors.first('title') }}</span>
</div>
@if ($guest_review && !auth()->guard('customer')->user())
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="title" class="required">
{{ __('shop::app.reviews.name') }}
</label>
<input type="text" class="control" name="name" v-validate="'required'" value="{{ old('name') }}">
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
@endif
<div class="control-group" :class="[errors.has('comment') ? 'has-error' : '']">
<label for="comment" class="required">
{{ __('admin::app.customers.reviews.comment') }}

View File

@ -46,7 +46,11 @@
<div class="heading mt-10">
<span> {{ __('shop::app.reviews.rating-reviews') }} </span>
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary right"> {{ __('shop::app.products.write-review-btn') }}</a>
@if (core()->getConfigData('catalog.products.review.guest_review') || auth()->guard('customer')->check())
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary right">
{{ __('shop::app.products.write-review-btn') }}
</a>
@endif
</div>
<div class="ratings-reviews mt-35">
@ -112,7 +116,7 @@
<div class="reviewer-details">
<span class="by">
{{ __('shop::app.products.by', ['name' => $review->customer->name]) }},
{{ __('shop::app.products.by', ['name' => $review->name]) }},
</span>
<span class="when">

View File

@ -29,11 +29,11 @@
</div>
@auth('customer')
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary">
{{ __('shop::app.products.write-review-btn') }}
</a>
@endauth
@if (core()->getConfigData('catalog.products.review.guest_review') || auth()->guard('customer')->check())
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary">
{{ __('shop::app.products.write-review-btn') }}
</a>
@endif
</div>
@ -59,7 +59,7 @@
<div class="reviewer-details">
<span class="by">
{{ __('shop::app.products.by', ['name' => $review->customer->name]) }},
{{ __('shop::app.products.by', ['name' => $review->name]) }},
</span>
<span class="when">
@ -76,7 +76,7 @@
</div>
</div>
@else
@auth('customer')
@if (core()->getConfigData('catalog.products.review.guest_review') || auth()->guard('customer')->check())
<div class="rating-reviews">
<div class="rating-header">
<a href="{{ route('shop.reviews.create', $product->url_key) }}" class="btn btn-lg btn-primary">
@ -84,7 +84,7 @@
</a>
</div>
</div>
@endauth
@endif
@endif
{!! view_render_event('bagisto.shop.products.view.reviews.after', ['product' => $product]) !!}

View File

@ -9,6 +9,7 @@ use Webkul\Tax\Repositories\TaxRateRepository as TaxRate;
use Webkul\Admin\Imports\DataGridImport;
use Illuminate\Support\Facades\Validator;
use Excel;
use Maatwebsite\Excel\Validators\Failure;
/**
* Tax controller
@ -183,86 +184,92 @@ class TaxRateController extends Controller
if (!in_array(request()->file('file')->getClientOriginalExtension(), $valid_extension)) {
session()->flash('error', trans('admin::app.export.upload-error'));
} else {
$excelData = (new DataGridImport)->toArray(request()->file('file'));
try {
$excelData = (new DataGridImport)->toArray(request()->file('file'));
foreach ($excelData as $data) {
foreach ($data as $column => $uploadData) {
$validator = Validator::make($uploadData, [
'identifier' => 'required|string',
'state' => 'required|string',
'country' => 'required|string',
'tax_rate' => 'required|numeric'
]);
foreach ($excelData as $data) {
foreach ($data as $column => $uploadData) {
$validator = Validator::make($uploadData, [
'identifier' => 'required|string',
'state' => 'required|string',
'country' => 'required|string',
'tax_rate' => 'required|numeric'
]);
if ($validator->fails()) {
$failedRules[$column+1] = $validator->errors();
}
$identiFier[$column+1] = $uploadData['identifier'];
}
$identiFierCount = array_count_values($identiFier);
$filtered = array_filter($identiFier, function ($value) use ($identiFierCount) {
return $identiFierCount[$value] > 1;
});
}
if ($filtered) {
foreach ($filtered as $position => $identifier) {
$message[] = trans('admin::app.export.duplicate-error', ['identifier' => $identifier, 'position' => $position]);
}
$finalMsg = implode(" ", $message);
session()->flash('error', $finalMsg);
} else {
$errorMsg = [];
if (isset($failedRules)) {
foreach ($failedRules as $coulmn => $fail) {
if ($fail->first('identifier')){
$errorMsg[$coulmn] = $fail->first('identifier');
} else if ($fail->first('tax_rate')) {
$errorMsg[$coulmn] = $fail->first('tax_rate');
} else if ($fail->first('country')) {
$errorMsg[$coulmn] = $fail->first('country');
} else if ($fail->first('state')) {
$errorMsg[$coulmn] = $fail->first('state');
if ($validator->fails()) {
$failedRules[$column+1] = $validator->errors();
}
$identiFier[$column+1] = $uploadData['identifier'];
}
foreach ($errorMsg as $key => $msg) {
$msg = str_replace(".", "", $msg);
$message[] = $msg. ' at Row ' .$key . '.';
}
$identiFierCount = array_count_values($identiFier);
$filtered = array_filter($identiFier, function ($value) use ($identiFierCount) {
return $identiFierCount[$value] > 1;
});
}
if ($filtered) {
foreach ($filtered as $position => $identifier) {
$message[] = trans('admin::app.export.duplicate-error', ['identifier' => $identifier, 'position' => $position]);
}
$finalMsg = implode(" ", $message);
session()->flash('error', $finalMsg);
} else {
$taxRate = $this->taxRate->get()->toArray();
$errorMsg = [];
foreach ($taxRate as $rate) {
$rateIdentifier[$rate['id']] = $rate['identifier'];
}
if (isset($failedRules)) {
foreach ($failedRules as $coulmn => $fail) {
if ($fail->first('identifier')){
$errorMsg[$coulmn] = $fail->first('identifier');
} else if ($fail->first('tax_rate')) {
$errorMsg[$coulmn] = $fail->first('tax_rate');
} else if ($fail->first('country')) {
$errorMsg[$coulmn] = $fail->first('country');
} else if ($fail->first('state')) {
$errorMsg[$coulmn] = $fail->first('state');
}
}
foreach ($excelData as $data) {
foreach ($data as $column => $uploadData) {
if (isset($rateIdentifier)) {
$id = array_search($uploadData['identifier'], $rateIdentifier);
if ($id) {
$this->taxRate->update($uploadData, $id);
foreach ($errorMsg as $key => $msg) {
$msg = str_replace(".", "", $msg);
$message[] = $msg. ' at Row ' .$key . '.';
}
$finalMsg = implode(" ", $message);
session()->flash('error', $finalMsg);
} else {
$taxRate = $this->taxRate->get()->toArray();
foreach ($taxRate as $rate) {
$rateIdentifier[$rate['id']] = $rate['identifier'];
}
foreach ($excelData as $data) {
foreach ($data as $column => $uploadData) {
if (isset($rateIdentifier)) {
$id = array_search($uploadData['identifier'], $rateIdentifier);
if ($id) {
$this->taxRate->update($uploadData, $id);
} else {
$this->taxRate->create($uploadData);
}
} else {
$this->taxRate->create($uploadData);
}
} else {
$this->taxRate->create($uploadData);
}
}
}
session()->flash('success', trans('admin::app.response.upload-success', ['name' => 'Tax Rate']));
session()->flash('success', trans('admin::app.response.upload-success', ['name' => 'Tax Rate']));
}
}
} catch (\Exception $e) {
$failure = new Failure(1, 'rows', [0 => trans('admin::app.export.enough-row-error')]);
session()->flash('error', $failure->errors()[0]);
}
}