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

This commit is contained in:
rahul shukla 2019-11-26 18:33:01 +05:30
commit 8948aeaea7
27 changed files with 450 additions and 149 deletions

View File

@ -1,5 +1,5 @@
---
name: "🧐 Support Question"
name: " Support Question"
about: 'This repository is only for reporting bugs or problems. If you need help, see:
https://github.com/bagisto/bagisto#documentation'
---
@ -8,4 +8,4 @@ This repository is only for reporting bugs or issues. If you need support, pleas
1. Create support ticket on https://bagisto.uvdesk.com
Thanks!
Thanks!

View File

@ -2,9 +2,10 @@
"name": "bagisto/bagisto",
"description": "Bagisto Laravel ECommerce",
"keywords": [
"framework",
"laravel"
"framework",
"laravel"
],
"license": "MIT",
"type": "project",
"require": {
@ -17,6 +18,7 @@
"ext-pdo_mysql": "*",
"ext-tokenizer": "*",
"astrotomic/laravel-translatable": "^11.0.0",
"alkhachatryan/laravel-web-console": "1.5.1",
"barryvdh/laravel-dompdf": "0.8.3",
"doctrine/dbal": "2.9.2",
"fideloper/proxy": "^4.0",
@ -33,94 +35,103 @@
"prettus/l5-repository": "2.6.32",
"tymon/jwt-auth": "1.0.0-rc.4"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.1",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"laravel/dusk": "^4.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
"barryvdh/laravel-debugbar": "^3.1",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"laravel/dusk": "^4.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
},
"replace": {
"bagisto/laravel-user": "v0.1.0",
"bagisto/laravel-admin": "v0.1.0",
"bagisto/laravel-ui": "v0.1.0",
"bagisto/laravel-core": "v0.1.0",
"bagisto/laravel-attribute": "v0.1.0",
"bagisto/laravel-checkout": "v0.1.0",
"bagisto/laravel-customer": "v0.1.0",
"bagisto/laravel-inventory": "v0.1.0",
"bagisto/laravel-category": "v0.1.0",
"bagisto/laravel-product": "v0.1.0",
"bagisto/laravel-shop": "v0.1.0",
"bagisto/laravel-theme": "v0.1.0",
"bagisto/laravel-shipping": "v0.1.0",
"bagisto/laravel-payment": "v0.1.0",
"bagisto/laravel-sales": "v0.1.0",
"bagisto/laravel-tax": "v0.1.0",
"bagisto/laravel-api": "v0.1.0",
"bagisto/laravel-paypal": "v0.1.0",
"bagisto/laravel-discount": "v0.1.0"
"bagisto/laravel-user": "v0.1.0",
"bagisto/laravel-admin": "v0.1.0",
"bagisto/laravel-ui": "v0.1.0",
"bagisto/laravel-core": "v0.1.0",
"bagisto/laravel-attribute": "v0.1.0",
"bagisto/laravel-checkout": "v0.1.0",
"bagisto/laravel-customer": "v0.1.0",
"bagisto/laravel-inventory": "v0.1.0",
"bagisto/laravel-category": "v0.1.0",
"bagisto/laravel-product": "v0.1.0",
"bagisto/laravel-shop": "v0.1.0",
"bagisto/laravel-theme": "v0.1.0",
"bagisto/laravel-shipping": "v0.1.0",
"bagisto/laravel-payment": "v0.1.0",
"bagisto/laravel-sales": "v0.1.0",
"bagisto/laravel-tax": "v0.1.0",
"bagisto/laravel-api": "v0.1.0",
"bagisto/laravel-paypal": "v0.1.0",
"bagisto/laravel-discount": "v0.1.0"
},
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/",
"Webkul\\User\\": "packages/Webkul/User/src",
"Webkul\\Admin\\": "packages/Webkul/Admin/src",
"Webkul\\Ui\\": "packages/Webkul/Ui/src",
"Webkul\\Category\\": "packages/Webkul/Category/src",
"Webkul\\Checkout\\": "packages/Webkul/Checkout/src",
"Webkul\\Attribute\\": "packages/Webkul/Attribute/src",
"Webkul\\Shop\\": "packages/Webkul/Shop/src",
"Webkul\\Core\\": "packages/Webkul/Core/src",
"Webkul\\Customer\\": "packages/Webkul/Customer/src",
"Webkul\\Inventory\\": "packages/Webkul/Inventory/src",
"Webkul\\Product\\": "packages/Webkul/Product/src",
"Webkul\\Theme\\": "packages/Webkul/Theme/src",
"Webkul\\Shipping\\": "packages/Webkul/Shipping/src",
"Webkul\\Payment\\": "packages/Webkul/Payment/src",
"Webkul\\Paypal\\": "packages/Webkul/Paypal/src",
"Webkul\\Sales\\": "packages/Webkul/Sales/src",
"Webkul\\Tax\\": "packages/Webkul/Tax/src",
"Webkul\\API\\": "packages/Webkul/API",
"Webkul\\Discount\\": "packages/Webkul/Discount/src",
"Webkul\\CMS\\": "packages/Webkul/CMS/src"
}
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/",
"Webkul\\User\\": "packages/Webkul/User/src",
"Webkul\\Admin\\": "packages/Webkul/Admin/src",
"Webkul\\Ui\\": "packages/Webkul/Ui/src",
"Webkul\\Category\\": "packages/Webkul/Category/src",
"Webkul\\Checkout\\": "packages/Webkul/Checkout/src",
"Webkul\\Attribute\\": "packages/Webkul/Attribute/src",
"Webkul\\Shop\\": "packages/Webkul/Shop/src",
"Webkul\\Core\\": "packages/Webkul/Core/src",
"Webkul\\Customer\\": "packages/Webkul/Customer/src",
"Webkul\\Inventory\\": "packages/Webkul/Inventory/src",
"Webkul\\Product\\": "packages/Webkul/Product/src",
"Webkul\\Theme\\": "packages/Webkul/Theme/src",
"Webkul\\Shipping\\": "packages/Webkul/Shipping/src",
"Webkul\\Payment\\": "packages/Webkul/Payment/src",
"Webkul\\Paypal\\": "packages/Webkul/Paypal/src",
"Webkul\\Sales\\": "packages/Webkul/Sales/src",
"Webkul\\Tax\\": "packages/Webkul/Tax/src",
"Webkul\\API\\": "packages/Webkul/API",
"Webkul\\Discount\\": "packages/Webkul/Discount/src",
"Webkul\\CMS\\": "packages/Webkul/CMS/src"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar",
"laravel/dusk"
]
}
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar",
"laravel/dusk"
]
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate",
"Webkul\\Core\\Events\\ComposerEvents::postCreateProject"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
},
"config": {
"preferred-install": "stable",
"sort-packages": true,
"optimize-autoloader": true
"preferred-install": "stable",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev"
}
}

View File

@ -0,0 +1,51 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| User accesses
|--------------------------------------------------------------------------
|
| This file contains the connection settings with your custom user.
|
|
| !!!!! ATTENTION !!!!!
|
| These user credentials ARE NOT your server user credentials.
| You can type here everything you want.
| This method of custom login is a small addition in the protection.
| Anyway you can disable it.
|
|
|
| The preferred type of editing the accesses is to edit your .env file
| Kindly add the following lines in your .env file
| CONSOLE_USER_NAME={name}
| CONSOLE_USER_PASSWORD={password}
|
*/
// Disable login (don't ask for credentials, be careful)
'no_login' => false,
// Single-user credentials (REQUIRED)
'user' => [
'name' => env('CONSOLE_USER_NAME', 'root'),
'password' => env('CONSOLE_USER_PASSWORD', 'root'),
],
// Multi-user credentials (OPTIONAL)
// Example: 'user' => 'password', 'user1' => 'password1'
'accounts' => [
// 'user' => 'password',
],
// Hash incoming password
// By default it's sha256
'password_hash_algorithm' => '',
// Home directory (multi-user mode supported)
// Example: 'home_dir' => '/tmp';
// 'home_dir' => array('user1' => '/home/user1', 'user2' => '/home/user2');
'home_dir' => '',
];

View File

@ -3,6 +3,7 @@
namespace Webkul\API\Http\Resources\Catalog;
use Illuminate\Http\Resources\Json\JsonResource;
use Webkul\Product\Helpers\ProductType;
class Product extends JsonResource
{
@ -44,7 +45,7 @@ class Product extends JsonResource
'base_image' => $this->productImageHelper->getProductBaseImage($product),
'variants' => Self::collection($this->variants),
'in_stock' => $product->haveSufficientQuantity(1),
$this->mergeWhen($product->type == 'configurable', [
$this->mergeWhen($product->getTypeInstance()->isComposite(), [
'super_attributes' => Attribute::collection($product->super_attributes),
]),
'special_price' => $this->when(

View File

@ -182,6 +182,12 @@ return [
'sort' => 2,
'icon-class' => ''
], [
'key' => 'settings.development',
'name' => 'admin::app.settings.development.title',
'route' => 'admin.development.index',
'sort' => 8,
'icon-class' => ''
],[
'key' => 'promotions',
'name' => 'admin::app.layouts.promotion',
'route' => 'admin.cart-rule.index',

View File

@ -0,0 +1,24 @@
<?php
namespace Webkul\Admin\Http\Controllers\Development;
use Webkul\Admin\Http\Controllers\Controller;
/**
* Dashboard controller
*
* @author Alexey Khachatryan <info@khachatryan.org>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class DashboardController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\View\View
*/
public function index()
{
return view('admin::settings.development.dashboard');
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Webkul\Admin\Http\Controllers\Development;
use Alkhachatryan\LaravelWebConsole\LaravelWebConsole;
use Webkul\Admin\Http\Controllers\Controller;
/**
* WebConsole controller
*
* @author Alexey Khachatryan <info@khachatryan.org>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class WebConsoleController extends Controller
{
/**
* Show the Web Console.
*
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
public function index(){
return LaravelWebConsole::show();
}
}

View File

@ -278,7 +278,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');
@ -760,6 +760,15 @@ Route::group(['middleware' => ['web']], function () {
// 'redirect' => 'admin.cms.index'
// ])->name('admin.cms.delete');
});
// Development settings
Route::prefix('development')->group(function () {
Route::get('/', 'Webkul\Admin\Http\Controllers\Development\DashboardController@index')
->name('admin.development.index');
Route::get('webconsole', 'Webkul\Admin\Http\Controllers\Development\WebConsoleController@index')
->name('admin.development.webconsole');
});
});
});
});

View File

@ -726,6 +726,10 @@ return [
'update-error' => 'خطأ! معدل الضرائب لا يمكن تحديثه',
'delete' => 'معدل الضريبة محذوف بنجاح',
'atleast-one' => 'لا يستطيع حذف الأخير ضريبة معدل'
],
'development' => [
'title' => 'تطوير',
'webconsole' => 'وحدة تحكم الويب',
]
],

View File

@ -835,6 +835,10 @@ return [
'update-error' => 'Error! Tax Rate Cannot Be Updated',
'delete' => 'Tax Rate Deleted Successfully',
'atleast-one' => 'Cannot Delete Last Tax Rate'
],
'development' => [
'title' => 'Development',
'webconsole' => 'Web Console',
]
],

View File

@ -761,6 +761,10 @@ return [
'update-error' => 'خطا! نرخ مالیات نمی تواند به روز شود',
'delete' => 'نرخ مالیات با موفقیت حذف شد',
'atleast-one' => 'آخرین نرخ مالیات نمی تواند حذف شود'
],
'development' => [
'title' => 'توسعه',
'webconsole' => 'کنسول وب',
]
],

View File

@ -584,7 +584,6 @@ return [
'title' => 'Idiomas',
'add-title' => 'Add Idioma',
'edit-title' => 'Editar Idioma',
'add-title' => 'Add Idioma',
'save-btn-title' => 'Salvar Idioma',
'general' => 'Geral',
'code' => 'Código',
@ -753,6 +752,10 @@ return [
'update-error' => 'Erro! Taxas de Impostos Não Poderam ser Atualizadas',
'delete' => 'Taxas de Impostos Excluídas com Sucesso',
'atleast-one' => 'Não é Possível Excluir a Última Taxa de Impostos'
],
'development' => [
'title' => 'Desenvolvimento',
'webconsole' => 'Console da Web',
]
],
'customers' => [

View File

@ -17,7 +17,8 @@
<div class="page-title">
<h1>
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
<i class="icon angle-left-icon back-link"
onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
{{ __('admin::app.catalog.products.edit-title') }}
</h1>
@ -26,7 +27,8 @@
<select class="control" id="channel-switcher" name="channel">
@foreach (core()->getAllChannels() as $channelModel)
<option value="{{ $channelModel->code }}" {{ ($channelModel->code) == $channel ? 'selected' : '' }}>
<option
value="{{ $channelModel->code }}" {{ ($channelModel->code) == $channel ? 'selected' : '' }}>
{{ $channelModel->name }}
</option>
@ -38,7 +40,8 @@
<select class="control" id="locale-switcher" name="locale">
@foreach (core()->getAllLocales() as $localeModel)
<option value="{{ $localeModel->code }}" {{ ($localeModel->code) == $locale ? 'selected' : '' }}>
<option
value="{{ $localeModel->code }}" {{ ($localeModel->code) == $locale ? 'selected' : '' }}>
{{ $localeModel->name }}
</option>
@ -66,31 +69,37 @@
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.' . $attributeGroup->name . '.before', ['product' => $product]) !!}
<accordian :title="'{{ __($attributeGroup->name) }}'" :active="{{$index == 0 ? 'true' : 'false'}}">
<accordian :title="'{{ __($attributeGroup->name) }}'"
:active="{{$index == 0 ? 'true' : 'false'}}">
<div slot="body">
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.' . $attributeGroup->name . '.controls.before', ['product' => $product]) !!}
@foreach ($customAttributes as $attribute)
<?php
$validations = [];
$validations = [];
if ($attribute->is_required)
array_push($validations, 'required');
if ($attribute->is_required) {
array_push($validations, 'required');
}
if ($attribute->type == 'price')
array_push($validations, 'decimal');
if ($attribute->type == 'price') {
array_push($validations, 'decimal');
}
array_push($validations, $attribute->validation);
array_push($validations, $attribute->validation);
$validations = implode('|', array_filter($validations));
$validations = implode('|', array_filter($validations));
?>
@if (view()->exists($typeView = 'admin::catalog.products.field-types.' . $attribute->type))
<div class="control-group {{ $attribute->type }}" @if ($attribute->type == 'multiselect') :class="[errors.has('{{ $attribute->code }}[]') ? 'has-error' : '']" @else :class="[errors.has('{{ $attribute->code }}') ? 'has-error' : '']" @endif>
<div class="control-group {{ $attribute->type }}"
@if ($attribute->type == 'multiselect') :class="[errors.has('{{ $attribute->code }}[]') ? 'has-error' : '']"
@else :class="[errors.has('{{ $attribute->code }}') ? 'has-error' : '']" @endif>
<label for="{{ $attribute->code }}" {{ $attribute->is_required ? 'class=required' : '' }}>
<label
for="{{ $attribute->code }}" {{ $attribute->is_required ? 'class=required' : '' }}>
{{ $attribute->admin_name }}
@if ($attribute->type == 'price')
@ -98,13 +107,15 @@
@endif
<?php
$channel_locale = [];
$channel_locale = [];
if ($attribute->value_per_channel)
array_push($channel_locale, $channel);
if ($attribute->value_per_channel) {
array_push($channel_locale, $channel);
}
if ($attribute->value_per_locale)
array_push($channel_locale, $locale);
if ($attribute->value_per_locale) {
array_push($channel_locale, $locale);
}
?>
@if (count($channel_locale))
@ -114,7 +125,9 @@
@include ($typeView)
<span class="control-error" @if ($attribute->type == 'multiselect') v-if="errors.has('{{ $attribute->code }}[]')" @else v-if="errors.has('{{ $attribute->code }}')" @endif>
<span class="control-error"
@if ($attribute->type == 'multiselect') v-if="errors.has('{{ $attribute->code }}[]')"
@else v-if="errors.has('{{ $attribute->code }}')" @endif>
@if ($attribute->type == 'multiselect')
@{{ errors.first('{!! $attribute->code !!}[]') }}
@else
@ -137,12 +150,20 @@
@endforeach
{!! view_render_event(
'bagisto.admin.catalog.product.edit_form_accordian.additional_views.before',
['product' => $product])
!!}
@foreach ($product->getTypeInstance()->getAdditionalViews() as $view)
@include ($view)
@endforeach
{!! view_render_event(
'bagisto.admin.catalog.product.edit_form_accordian.additional_views.after',
['product' => $product])
!!}
</div>
</form>
@ -173,4 +194,4 @@
});
});
</script>
@endpush
@endpush

View File

@ -241,14 +241,14 @@
<tbody>
@foreach ($order->items as $item)
<tr>
<td>{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}</td>
<td>{{ Webkul\Product\Helpers\ProductType::hasVariants($item->type) ? $item->child->sku : $item->sku }}</td>
<td>
{{ $item->name }}
@if (isset($item->additional['attributes']))
<div class="item-options">
@foreach ($item->additional['attributes'] as $attribute)
<b>{{ $attribute['attribute_name'] }} : </b>{{ $attribute['option_label'] }}</br>
@endforeach
@ -417,7 +417,7 @@
if (! response.data) {
window.flashMessages = [{
'type': 'alert-error',
'message': "{{ __('admin::app.sales.refunds.invalid-qty') }}"
'message': "{{ __('admin::app.sales.refunds.invalid-qty') }}"
}];
this_this.$root.addFlashMessages()

View File

@ -0,0 +1,28 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.settings.development.title') }}
@stop
@section('content')
<div class="content">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.settings.development.title') }}</h1>
</div>
</div>
<div class="page-content">
<a href="{{ route('admin.development.webconsole') }}" target="_blank">
<div class="rad-info-box">
<p>
<span class="heading">{{ __('admin::app.settings.development.webconsole') }}</span>
</p>
<p>
<i class="icon cms-icon"></i>
</p>
</div>
</a>
</div>
</div>
@stop

View File

@ -0,0 +1,15 @@
<?php
namespace Webkul\Core\Events;
use Symfony\Component\Console\Output\ConsoleOutput;
class ComposerEvents
{
public static function postCreateProject()
{
$output = new ConsoleOutput();
$output->writeln(file_get_contents(__DIR__ . '/../Templates/on-boarding.php'));
}
}

View File

@ -0,0 +1,14 @@
____ _ _
| __ ) __ _ __ _(_)___| |_ ___
| _ \ / _` |/ _` | / __| __/ _ \
| |_) | (_| | (_| | \__ \ || (_) |
|____/ \__,_|\__, |_|___/\__\___/
|___/
</>
Welcome to the <info>Bagisto</info> project! Bagisto Community is an <comment>open-source e-commerce ecosystem </comment>
which is built on top of top of Laravel and Vue.js.
Made with 💖 by the Bagisto Team. Happy helping :)

View File

@ -6,6 +6,7 @@ use Webkul\Discount\Repositories\CatalogRuleRepository as CatalogRule;
use Webkul\Discount\Repositories\CatalogRuleProductsRepository as CatalogRuleProducts;
use Webkul\Discount\Repositories\CatalogRuleProductsPriceRepository as CatalogRuleProductsPrice;
use Webkul\Discount\Helpers\Catalog\ConvertXToProductId as ConvertX;
use Webkul\Product\Helpers\ProductType;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Discount\Helpers\Catalog\Sale;
@ -451,7 +452,7 @@ class Apply extends Sale
foreach ($productIDs as $productID) {
$product = $products->find($productID);
if ($product->type == 'configurable') {
if (ProductType::hasVariants($product->type)) {
$variants = $product->variants;
foreach($variants as $variant) {

View File

@ -6,6 +6,7 @@ use Webkul\Discount\Repositories\CatalogRuleRepository as CatalogRule;
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
use Webkul\Attribute\Repositories\AttributeOptionRepository as AttributeOption;
use Webkul\Category\Repositories\CategoryRepository as Category;
use Webkul\Product\Helpers\ProductType;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Models\ProductAttributeValue as ProductAttributeValue;
@ -110,7 +111,7 @@ class ConvertXToProductId
$products = collect();
foreach ($attributeOptions as $attributeOption) {
if (isset($attributeOption->type) && $attributeOption->name != null && $attributeOption->condition != null && $attributeOption->value != [] && $attributeOption->type != null) {
if (isset($attributeOption->type) && $attributeOption->attribute != null && $attributeOption->condition != null && $attributeOption->value != [] && $attributeOption->type != null) {
$selectedOptions = $attributeOption->value;
if ($attributeOption->type == 'select' || $attributeOption->type == 'multiselect') {
@ -154,17 +155,17 @@ class ConvertXToProductId
if ($testCondition == '{}') {
$foundProducts = $this->product->findWhere([
['sku', 'like', '%' . $testValue . '%'],
['type', '!=', 'configurable']
])->flatten()->all();
['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
])->flatten()->all();
} else if ($testCondition == '!{}') {
$foundProducts = $this->product->findWhere([
['sku', 'not like', '%' . $testValue . '%'],
['type', '!=', 'configurable']
['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
])->flatten()->all();
} else if ($testCondition == '=') {
$foundProducts = $this->product->findWhere([
['sku', '=', $testValue],
['type', '!=', 'configurable']
['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
])->flatten()->all();
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Webkul\Product\Helpers;
use Webkul\Product\Type\AbstractType;
class ProductType extends AbstractProduct
{
/**
* Checks if a ProductType may have variants
*
* @param string $typeKey as defined in config('product_types)
*
* @return bool whether ProductType is able to have variants
*/
public static function hasVariants(string $typeKey): bool
{
/** @var AbstractType $type */
$type = app(config('product_types.' . $typeKey . '.class'));
return $type->hasVariants();
}
/**
* Get all ProductTypes that are allowed to have variants
*
* @return array of product_types->keys
*/
public static function getAllTypesHavingVariants(): array
{
foreach (config('product_types') as $type) {
if (self::hasVariants($type['key'])) {
array_push($havingVariants, $type['key']);
}
}
return $havingVariants;
}
}

View File

@ -4,6 +4,7 @@ namespace Webkul\Product\Http\Controllers;
use Illuminate\Support\Facades\Event;
use Webkul\Product\Http\Requests\ProductForm;
use Webkul\Product\Helpers\ProductType;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
@ -140,13 +141,13 @@ class ProductController extends Controller
public function store()
{
if (! request()->get('family')
&& request()->input('type') == 'configurable'
&& ProductType::hasVariants(request()->input('type'))
&& request()->input('sku') != '') {
return redirect(url()->current() . '?type=' . request()->input('type') . '&family=' . request()->input('attribute_family_id') . '&sku=' . request()->input('sku'));
}
if (request()->input('type') == 'configurable'
if (ProductType::hasVariants(request()->input('type'))
&& (! request()->has('super_attributes')
|| ! count(request()->get('super_attributes')))) {

View File

@ -6,6 +6,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Attribute\Repositories\AttributeOptionRepository;
use Webkul\Product\Helpers\ProductType;
use Webkul\Product\Repositories\ProductFlatRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Models\ProductAttributeValue;
@ -148,7 +149,7 @@ class ProductFlat
{
$this->createFlat($product);
if ($product->type == 'configurable') {
if (ProductType::hasVariants($product->type)) {
foreach ($product->variants()->get() as $variant) {
$this->createFlat($variant, $product);
}

View File

@ -3,6 +3,7 @@
namespace Webkul\Product\Type;
use Illuminate\Support\Facades\Storage;
use phpDocumentor\Reflection\Types\Boolean;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
@ -57,7 +58,7 @@ abstract class AbstractType
/**
* Product Image helper instance
*
*
* @var ProductImage
*/
protected $productImageHelper;
@ -104,6 +105,13 @@ abstract class AbstractType
*/
protected $canBeMovedFromWishlistToCart = true;
/**
* Has child products aka variants
*
* @var boolean
*/
protected $hasVariants = false;
/**
* Create a new product type instance.
*
@ -159,17 +167,21 @@ abstract class AbstractType
$product->update($data);
foreach ($product->attribute_family->custom_attributes as $attribute) {
if ($attribute->type == 'boolean')
if ($attribute->type == 'boolean') {
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
}
if (! isset($data[$attribute->code]))
if (! isset($data[$attribute->code])) {
continue;
}
if ($attribute->type == 'date' && $data[$attribute->code] == '')
if ($attribute->type == 'date' && $data[$attribute->code] == '') {
$data[$attribute->code] = null;
}
if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox')
if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox') {
$data[$attribute->code] = implode(",", $data[$attribute->code]);
}
if ($attribute->type == 'image' || $attribute->type == 'file') {
$data[$attribute->code] = gettype($data[$attribute->code]) == 'object'
@ -198,16 +210,18 @@ abstract class AbstractType
], $attributeValue->id
);
if ($attribute->type == 'image' || $attribute->type == 'file')
if ($attribute->type == 'image' || $attribute->type == 'file') {
Storage::delete($attributeValue->text_value);
}
}
}
$route = request()->route() ? request()->route()->getName() : "";
$route = request()->route() ? request()->route()->getName() : "";
if ($route != 'admin.catalog.products.massupdate') {
if (isset($data['categories']))
if (isset($data['categories'])) {
$product->categories()->sync($data['categories']);
}
$product->up_sells()->sync($data['up_sell'] ?? []);
@ -243,9 +257,10 @@ abstract class AbstractType
*/
public function isSaleable()
{
if (! $this->product->status)
if (! $this->product->status) {
return false;
}
return true;
}
@ -260,7 +275,7 @@ abstract class AbstractType
}
/**
* Return true if this product can have inventory
* Return true if this product can be composite
*
* @return boolean
*/
@ -269,6 +284,16 @@ abstract class AbstractType
return $this->isComposite;
}
/**
* Return true if this product can have variants
*
* @return bool
*/
public function hasVariants(): bool
{
return $this->hasVariants;
}
/**
* @param integer $qty
* @return bool
@ -277,7 +302,7 @@ abstract class AbstractType
{
return $this->haveSufficientQuantity;
}
/**
* Return true if this product can have inventory
*
@ -310,8 +335,9 @@ abstract class AbstractType
->pluck('id');
foreach ($this->product->inventories as $inventory) {
if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id)))
if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) {
$total += $inventory->qty;
}
}
$orderedInventory = $this->product->ordered_inventories()
@ -344,11 +370,13 @@ abstract class AbstractType
*/
public function getEditableAttributes($group = null, $skipSuperAttribute = true)
{
if ($skipSuperAttribute)
if ($skipSuperAttribute) {
$this->skipAttributes = array_merge($this->product->super_attributes->pluck('code')->toArray(), $this->skipAttributes);
}
if (! $group)
if (! $group) {
return $this->product->attribute_family->custom_attributes()->whereNotIn('attributes.code', $this->skipAttributes)->get();
}
return $group->custom_attributes()->whereNotIn('code', $this->skipAttributes)->get();
}
@ -380,8 +408,9 @@ abstract class AbstractType
*/
public function getMinimalPrice()
{
if ($this->haveSpecialPrice())
if ($this->haveSpecialPrice()) {
return $this->product->special_price;
}
return $this->product->price;
}
@ -421,11 +450,13 @@ abstract class AbstractType
*/
public function haveSpecialPrice()
{
if (is_null($this->product->special_price) || ! (float) $this->product->special_price)
if (is_null($this->product->special_price) || ! (float) $this->product->special_price) {
return false;
}
if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to))
if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to)) {
return true;
}
return false;
}
@ -479,8 +510,9 @@ abstract class AbstractType
$data = $this->getQtyRequest($data);
if (! $this->haveSufficientQuantity($data['quantity']))
if (! $this->haveSufficientQuantity($data['quantity'])) {
return trans('shop::app.checkout.cart.quantity.inventory_warning');
}
$price = $this->getFinalPrice();
@ -514,12 +546,13 @@ abstract class AbstractType
*/
public function getQtyRequest($data)
{
if ($item = Cart::getItemByProduct(['additional' => $data]))
if ($item = Cart::getItemByProduct(['additional' => $data])) {
$data['quantity'] += $item->quantity;
}
return $data;
}
/**
*
* @param array $options1
@ -546,7 +579,7 @@ abstract class AbstractType
return true;
}
/**
* Returns additional information for items
*
@ -590,8 +623,9 @@ abstract class AbstractType
{
$price = $item->product->getTypeInstance()->getFinalPrice();
if ($price == $item->base_price)
if ($price == $item->base_price) {
return;
}
$item->base_price = $price;
$item->price = core()->convertPrice($price);

View File

@ -22,7 +22,7 @@ class Configurable extends AbstractType
/**
* These blade files will be included in product edit page
*
*
* @var array
*/
protected $additionalViews = [
@ -47,6 +47,13 @@ class Configurable extends AbstractType
*/
protected $showQuantityBox = true;
/**
* Has child products aka variants
*
* @var boolean
*/
protected $hasVariants = true;
/**
* @param array $data
* @return Product
@ -416,7 +423,7 @@ class Configurable extends AbstractType
return $products;
}
/**
*
* @param array $options1
@ -451,7 +458,7 @@ class Configurable extends AbstractType
];
}
return $data;
return $data;
}
/**

View File

@ -19,12 +19,10 @@
<span class="checkmark"></span>
{{-- <label class="radio-view" for="{{ $payment['method'] }}"></label> --}}
<span class="payment-method method-label">
<b>{{ $payment['method_title'] }}</b>
</span>
</label>
<span class="payment-method method-label">
<b>{{ $payment['method_title'] }}</b>
</span>
</div>
<div class="line-two mt-5">

View File

@ -1,4 +1,4 @@
@if ($product->type == 'configurable')
@if (Webkul\Product\Helpers\ProductType::hasVariants($product->type))
@inject ('configurableOptionHelper', 'Webkul\Product\Helpers\ConfigurableOption')

File diff suppressed because one or more lines are too long