Merge branch 'master' of https://github.com/jitendra-webkul/bagisto into prashant

Merging with changes in the routes of the customer and some css bugs in the customer view files.
This commit is contained in:
prashant-webkul 2018-08-22 12:59:27 +05:30
commit 8dec681e49
19 changed files with 289 additions and 176 deletions

View File

@ -315,50 +315,4 @@ Route::group(['middleware' => ['web']], function () {
])->name('admin.sliders.store');
});
});
//customer routes starts here
Route::prefix('customer')->group(function () {
// Login Routes
Route::get('login', 'Webkul\Customer\Http\Controllers\SessionController@show')->defaults('_config', [
'view' => 'shop::customers.session.index',
])->name('customer.session.index');
Route::post('login', 'Webkul\Customer\Http\Controllers\SessionController@create')->defaults('_config', [
'redirect' => 'customer.account.profile'
])->name('customer.session.create');
// Registration Routes
Route::get('register', 'Webkul\Customer\Http\Controllers\RegistrationController@show')->defaults('_config', [
'view' => 'shop::customers.signup.index' //hint path
])->name('customer.register.index');
Route::post('register', 'Webkul\Customer\Http\Controllers\RegistrationController@create')->defaults('_config', [
'redirect' => 'customer.account.profile',
])->name('customer.register.create'); //redirect attribute will get changed immediately to account.index when account's index page will be made
// Auth Routes
Route::group(['middleware' => ['customer']], function () {
//route for logout which will be under the auth guard of the customer by default
Route::get('logout', 'Webkul\Customer\Http\Controllers\SessionController@destroy')->defaults('_config', [
'redirect' => 'customer.session.index'
])->name('customer.session.destroy');
//customer account
Route::prefix('account')->group(function () {
Route::get('profile', 'Webkul\Customer\Http\Controllers\CustomerController@profile')->defaults('_config', [
'view' => 'shop::customers.account.profile.home.index'
])->name('customer.account.profile');
//profile edit
Route::get('profile/edit', 'Webkul\Customer\Http\Controllers\CustomerController@editProfile')->defaults('_config', [
'view' => 'shop::customers.account.profile.edit.index'
])->name('customer.profile.edit');
});
});
});
//customer routes end here
});

View File

@ -143,7 +143,7 @@ class ProductController extends Controller
*/
public function edit($id)
{
$product = $this->product->findOrFail($id, ['*'], ['variants', 'inventories']);
$product = $this->product->findOrFail($id, ['*'], ['variants']);
$categories = $this->category->getCategoryTree();

View File

@ -16,7 +16,7 @@ class Product extends Model
{
protected $fillable = ['type', 'attribute_family_id', 'sku', 'parent_id'];
protected $with = ['attribute_family', 'attribute_values', 'inventories'];
protected $with = ['attribute_family', 'inventories'];
/**
* Get the product attribute family that owns the product.
@ -131,14 +131,6 @@ class Product extends Model
{
return $this->attribute_family->custom_attributes->pluck('code')->contains($attribute);
}
/**
* @return bool
*/
public function getFinalPrice()
{
return 0.00;
}
/**
* Get an attribute from the model.
@ -148,11 +140,10 @@ class Product extends Model
*/
public function getAttribute($key)
{
if (!method_exists(self::class, $key) && !isset($this->attributes[$key])) {
$this->attributes[$key] = '';
if (!method_exists(self::class, $key) && !in_array($key, ['parent_id', 'attribute_family_id']) && !isset($this->attributes[$key])) {
if ($this->isCustomAttribute($key)) {
$this->attributes[$key] = '';
$attributeModel = $this->attribute_family->custom_attributes()->where('attributes.code', $key)->first();
if($attributeModel) {
@ -176,9 +167,10 @@ class Product extends Model
$this->attributes[$key] = $attributeValue[ProductAttributeValue::$attributeTypeFields[$attributeModel->type]];
}
return $this->getAttributeValue($key);
}
return $this->getAttributeValue($key);
}
return parent::getAttribute($key);

View File

@ -0,0 +1,36 @@
<?php
namespace Webkul\Product\Product;
abstract class AbstractProduct
{
/**
* Add Channle and Locale filter
*
* @param Attribute $attribute
* @param QB $qb
* @param sting $alias
* @return QB
*/
public function applyChannelLocaleFilter($attribute, $qb, $alias = 'product_attribute_values')
{
$channel = core()->getCurrentChannelCode();
$locale = app()->getLocale();
if($attribute->value_per_channel) {
if($attribute->value_per_locale) {
$qb->where($alias . '.channel', $channel)
->where($alias . '.locale', $locale);
} else {
$qb->where($alias . '.channel', $channel);
}
} else {
if($attribute->value_per_locale) {
$qb->where($alias . '.locale', $locale);
}
}
return $qb;
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace Webkul\Shop\Product;
namespace Webkul\Product\Product;
use Illuminate\Support\Facades\DB;
use Webkul\Product\Repositories\ProductRepository as Product;
@ -15,6 +15,7 @@ class Collection extends AbstractProduct
* @var array
*/
protected $product;
/**
* AttributeRepository object
*
@ -22,6 +23,21 @@ class Collection extends AbstractProduct
*/
protected $attribute;
/**
* array object
*
* @var array
*/
protected $attributesToSelect = [
'name',
'description',
'short_description',
'price',
'special_price',
'special_price_from',
'special_price_to'
];
/**
* Create a new controller instance.
*
@ -36,6 +52,15 @@ class Collection extends AbstractProduct
$this->attribute = $attribute;
}
/**
* @param array $attributes
* @return Void
*/
public function addAttributesToSelect($attributes)
{
$this->attributesToSelect = $attributes;
}
/**
* @param integer $categoryId
* @return Collection
@ -47,44 +72,27 @@ class Collection extends AbstractProduct
->join('product_categories', 'products.id', '=', 'product_categories.product_id')
->where('product_categories.category_id', $categoryId);
$channel = core()->getCurrentChannelCode();
$locale = app()->getLocale();
foreach (['name', 'description', 'short_description', 'price', 'special_price', 'special_price_from', 'special_price_to'] as $code) {
foreach ($this->attributesToSelect as $code) {
$attribute = $this->attribute->findBy('code', $code);
$productValueAlias = 'pav_' . $attribute->code;
$qb->leftJoin('product_attribute_values as ' . $productValueAlias, function($leftJoin) use($channel, $locale, $attribute, $productValueAlias) {
$qb->leftJoin('product_attribute_values as ' . $productValueAlias, function($leftJoin) use($attribute, $productValueAlias) {
$leftJoin->on('products.id', $productValueAlias . '.product_id');
if($attribute->value_per_channel) {
if($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.channel', $channel)
->where($productValueAlias . '.locale', $locale);
} else {
$leftJoin->where($productValueAlias . '.channel', $channel);
}
} else {
if($attribute->value_per_locale) {
$leftJoin->where($productValueAlias . '.locale', $locale);
}
}
$leftJoin->where($productValueAlias . '.attribute_id', $attribute->id);
$leftJoin = $this->applyChannelLocaleFilter($attribute, $leftJoin, $productValueAlias)->where($productValueAlias . '.attribute_id', $attribute->id);
});
$qb->addSelect($productValueAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $code);
// if($code == 'name') {
// $filterAlias = 'filter_' . $attribute->code;
}
foreach (request()->input() as $code => $value) {
$filterAlias = 'filter_' . $code;
// $qb->leftJoin('product_attribute_values as ' . $filterAlias, 'products.id', '=', $filterAlias . '.product_id');
// $qb->where($filterAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type], 'Product Name');
// }
$qb->leftJoin('product_attribute_values as ' . $filterAlias, 'products.id', '=', $filterAlias . '.product_id');
$qb->where($filterAlias . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type], $value);
}
// if(0) {

View File

@ -0,0 +1,102 @@
<?php
namespace Webkul\Product\Product;
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\Product;
class Price extends AbstractProduct
{
/**
* AttributeRepository object
*
* @var array
*/
protected $attribute;
/**
* Create a new controller instance.
*
* @param Webkul\Attribute\Repositories\AttributeRepository $attribute
* @return void
*/
public function __construct(Attribute $attribute)
{
$this->attribute = $attribute;
}
/**
* Returns the product's minimal price
*
* @param Product $product
* @return float
*/
public function getMinimalPrice($product)
{
if($product->type == 'configurable') {
return $this->getVariantMinPrice($product);
} else {
if($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
}
}
}
/**
* Returns the product's minimal price
*
* @param Product $product
* @return float
*/
public function getVariantMinPrice($product)
{
static $attribute;
if(!$attribute)
$attribute = $this->attribute->findBy('code', 'price');
$qb = ProductAttributeValue::join('products', 'product_attribute_values.product_id', '=', 'products.id')
->join('attributes', 'product_attribute_values.attribute_id', '=', 'attributes.id')
->where('products.parent_id', $product->id)
->where('attributes.code', 'price')
->addSelect('product_attribute_values.*');
$qb = $this->applyChannelLocaleFilter($attribute, $qb);
return $qb->min('product_attribute_values.' . ProductAttributeValue::$attributeTypeFields['price']);
}
/**
* Returns the product's minimal price
*
* @param Product $product
* @return float
*/
public function getSpecialPrice($product)
{
if($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
}
}
/**
* @param Product $product
* @return boolean
*/
public function haveSpecialPrice($product)
{
if(is_null($product->special_price) || !$product->special_price)
return false;
if (core()->isChannelDateInInterval($product->special_price_from, $product->special_price_to)) {
return true;
}
return false;
}
}

View File

@ -141,7 +141,7 @@ class ProductRepository extends Repository
$product = $this->findOrFail($id);
if($product->parent_id && $this->checkVariantOptionAvailabiliy($data, $product)) {
$data['parent_id'] = null;
$data['parent_id'] = NULL;
}
$product->update($data);

View File

@ -14,4 +14,49 @@ Route::group(['middleware' => ['web']], function () {
Route::view('/products/{slug}', 'shop::store.product.details.index');
//customer routes starts here
Route::prefix('customer')->group(function () {
// Login Routes
Route::get('login', 'Webkul\Customer\Http\Controllers\SessionController@show')->defaults('_config', [
'view' => 'shop::customers.session.index',
])->name('customer.session.index');
Route::post('login', 'Webkul\Customer\Http\Controllers\SessionController@create')->defaults('_config', [
'redirect' => 'customer.account.profile'
])->name('customer.session.create');
// Registration Routes
Route::get('register', 'Webkul\Customer\Http\Controllers\RegistrationController@show')->defaults('_config', [
'view' => 'shop::customers.signup.index' //hint path
])->name('customer.register.index');
Route::post('register', 'Webkul\Customer\Http\Controllers\RegistrationController@create')->defaults('_config', [
'redirect' => 'customer.account.profile',
])->name('customer.register.create'); //redirect attribute will get changed immediately to account.index when account's index page will be made
// Auth Routes
Route::group(['middleware' => ['customer']], function () {
//route for logout which will be under the auth guard of the customer by default
Route::get('logout', 'Webkul\Customer\Http\Controllers\SessionController@destroy')->defaults('_config', [
'redirect' => 'customer.session.index'
])->name('customer.session.destroy');
//customer account
Route::prefix('account')->group(function () {
Route::get('profile', 'Webkul\Customer\Http\Controllers\CustomerController@profile')->defaults('_config', [
'view' => 'shop::customers.account.profile.index'
])->name('customer.account.profile');
//profile edit
Route::get('profile/edit', 'Webkul\Customer\Http\Controllers\CustomerController@editProfile')->defaults('_config', [
'view' => 'shop::customers.account.profile.edit'
])->name('customer.profile.edit');
});
});
});
//customer routes end here
});

View File

@ -1,7 +0,0 @@
<?php
namespace Webkul\Shop\Product;
abstract class AbstractProduct
{
}

View File

@ -1,55 +0,0 @@
<?php
namespace Webkul\Shop\Product;
class Price extends AbstractProduct
{
/**
* Returns the product's minimal price
*
* @return float
*/
public function getMinimalPrice($product)
{
// return 0;
if($product->type == 'configurable') {
return $product->variants->min('price');
} else {
if($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
}
}
}
/**
* Returns the product's minimal price
*
* @return float
*/
public function getSpecialPrice($product)
{
if($this->haveSpecialPrice($product)) {
return $product->special_price;
} else {
return $product->price;
}
}
/**
* @param Product $product
* @return boolean
*/
public function haveSpecialPrice($product)
{
if(is_null($product->special_price) || !$product->special_price)
return false;
if (core()->isChannelDateInInterval($product->special_price_from, $product->special_price_to)) {
return true;
}
return false;
}
}

View File

@ -7,11 +7,14 @@
body {
margin: 0;
padding: 0;
font-family: "Montserrat", sans-serif;
font-weight: 500;
font-size: 14px;
}
* {
font-family: "Montserrat", sans-serif;
}
.header {
margin-top: 16px;
margin-bottom: 21px;
@ -443,6 +446,11 @@ section.slider-block {
margin-left: 10%;
margin-right: 10%;
.content-container {
display: inline-block;
width: 100%;
}
.product-grid {
display: grid;
grid-gap: 30px;
@ -859,14 +867,6 @@ section.slider-block {
flex-direction: column;
min-height: 345px;
padding: 25px;
.control-group {
input,
select {
font-family: "Montserrat", sans-serif;
width: 100%;
}
}
}
}
//edit form ends

View File

@ -1,24 +1,35 @@
@extends('shop::layouts.master')
@section('content-wrapper')
<div class="account-content">
@include('shop::customers.account.partials.sidemenu')
<div class="edit-form-content">
<div class="edit-text">Edit Profile</div>
<form method="post" action="{{ route('customer.register.create') }}">
<div class="edit-form">
{{ csrf_field() }}
<div class="control-group">
<label for="first_name">First Name</label>
<input type="text" class="control" name="first_name" value="{{ $customer['first_name'] }}" v-validate="'required'"> {{-- <span>@{{ errors.first('first_name') }}</span> --}}
</div>
<div class="control-group">
<label for="last_name">Last Name</label>
<input type="text" class="control" name="last_name" value="{{ $customer['last_name'] }}" v-validate="'required'"> {{-- <span>@{{ errors.first('last_name') }}</span> --}}
</div>
<div class="control-group">
<label for="email">Email</label>
<input type="email" class="control" name="email" value="{{ $customer['email'] }}" v-validate="'required'"> {{-- <span>@{{ errors.first('email') }}</span> --}}
</div>
<div class="control-group">
<label for="email">Gender</label>
<select name="gender" class="control" value="{{ $customer['gender'] }}" v-validate="'required'">
@ -26,25 +37,35 @@
<option value="Female">Female</option>
</select> {{-- <span>@{{ errors.first('gender') }}</span> --}}
</div>
<div class="control-group">
<label for="dob">Date of Birth</label>
<input type="date" class="control" name="dob" value="{{ $customer['date_of_birth'] }}" v-validate="'required'"> {{-- <span>@{{ errors.first('first_name') }}</span> --}}
</div>
<div class="control-group">
<label for="phone">Phone</label>
<input type="text" class="control" name="phone" value="{{ $customer['phone'] }}" v-validate="'required'"> {{-- <span>@{{ errors.first('phone') }}</span> --}}
</div>
<div class="control-group">
<label for="password">Password</label>
<input type="password" class="control" name="password">
</div>
<div class="control-group">
<label for="password">Confirm Password</label>
<input type="password" class="control" name="password">
</div>
<input class="btn btn-primary btn-lg" type="submit" value="Update Profile">
<div class="button-group">
<input class="btn btn-primary btn-lg" type="submit" value="Update Profile">
</div>
</div>
</form>
</div>
</div>
@endsection

View File

@ -1,43 +1,58 @@
@extends('shop::layouts.master')
@section('content-wrapper')
<div class="account-content">
@include('shop::customers.account.partials.sidemenu')
<div class="profile">
<div class="section-head">
<span class="profile-heading">Profile</span>
<span class="profile-edit"><a href="{{ route('customer.profile.edit') }}">Edit</a></span>
<div class="horizontal-rule"></div>
</div>
<div class="profile-content">
<table>
<tbody>
<tr>
<td>First Name</td>
<td>{{ $customer['first_name'] }}</td>
</tr>
<tr>
<td>Last Name</td>
<td>{{ $customer['last_name'] }}</td>
</tr>
<tr>
<td>Gender Name</td>
<td>{{ $customer['gender'] }}</td>
</tr>
<tr>
<td>Date of Birth</td>
<td>{{ $customer['date_of_birth'] }}</td>
</tr>
<tr>
<td>Email Address</td>
<td>{{ $customer['email'] }}</td>
</tr>
<tr>
<td>Mobile</td>
<td>{{ $customer['phone'] }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@ -8,7 +8,7 @@
<div class="product-grid max-3-col">
@inject ('productHelper', 'Webkul\Shop\Product\Collection')
@inject ('productHelper', 'Webkul\Product\Product\Collection')
<?php $products = $productHelper->getProductCollection($category->id); ?>

View File

@ -1,9 +1,9 @@
<div class="product-price">
@inject ('priceHelper', 'Webkul\Shop\Product\Price')
@inject ('priceHelper', 'Webkul\Product\Product\Price')
@if ($product->type == 'configurable')
<span class="price-label">{{ __('shop::app.products.price-label') }}</span>
<span>{{ core()->currency($priceHelper->getMinimalPrice($product)) }}</span>

View File

@ -1,6 +1,6 @@
<div class="product-ratings">
@inject ('reviewHelper', 'Webkul\Shop\Product\Review')
@inject ('reviewHelper', 'Webkul\Product\Product\Review')
@for ($i = 1; $i <= $reviewHelper->getAverageRating($product); $i++)

View File

@ -14,11 +14,14 @@
body {
margin: 0;
padding: 0;
font-family: "Montserrat", sans-serif;
font-weight: 500;
font-size: 14px;
}
* {
font-family: "Montserrat", sans-serif;
}
.header {
margin-top: 16px;
margin-bottom: 21px;
@ -514,6 +517,11 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
margin-right: 10%;
}
.main-container-wrapper .content-container {
display: inline-block;
width: 100%;
}
.main-container-wrapper .product-grid {
display: grid;
grid-gap: 30px;
@ -970,12 +978,6 @@ section.slider-block div.slider-content div.slider-control .light-right-icon {
padding: 25px;
}
.account-content .edit-form-content .edit-form .control-group input,
.account-content .edit-form-content .edit-form .control-group select {
font-family: "Montserrat", sans-serif;
width: 100%;
}
section.product-detail, section.product-review {
font-size: 16px;
color: #242424;

File diff suppressed because one or more lines are too long