Configurable options added
This commit is contained in:
parent
4fb084557d
commit
5202729391
|
|
@ -1,10 +1,26 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
'flatrate' => [
|
||||
'code' => 'flatrate',
|
||||
'name' => 'Flat Rate',
|
||||
'class' => 'Webkul\Shipping\Calculators\FlatRate'
|
||||
'description' => '',
|
||||
'default_type' => 'per_order',
|
||||
'types' => [
|
||||
'per_unit' => 'Per Unit',
|
||||
'per_order' => 'Per Order',
|
||||
],
|
||||
'price' => 10,
|
||||
'class' => 'Webkul\Shipping\Calculators\FlatRate',
|
||||
'status' => 1
|
||||
],
|
||||
|
||||
'fedex' => [
|
||||
'code' => 'fedex',
|
||||
'name' => 'Fedex',
|
||||
'description' => '',
|
||||
'class' => 'Webkul\Shipping\Calculators\FedexRate',
|
||||
'status' => 1
|
||||
]
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,13 @@ class EventServiceProvider extends ServiceProvider
|
|||
Event::listen('admin.acl.build', function ($acl) {
|
||||
$acl->add('dashboard', 'Dashboard', 'admin.dashboard.index', 1);
|
||||
|
||||
$acl->add('catalog', 'Catalog', 'admin.catalog.index', 2);
|
||||
|
||||
$acl->add('catalog.products', 'Products', 'admin.catalog.products.index', 1);
|
||||
|
||||
$acl->add('catalog.categories', 'Categories', 'admin.catalog.categories.index', 1);
|
||||
|
||||
|
||||
$acl->add('configuration', 'Configure', 'admin.account.edit', 5);
|
||||
|
||||
$acl->add('settings', 'Settings', 'admin.users.index', 6);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ class ConfigurableOption extends AbstractProduct
|
|||
$config = [
|
||||
'attributes' => $this->getAttributesData($product, $options),
|
||||
'index' => isset($options['index']) ? $options['index'] : [],
|
||||
'regular_price' => [
|
||||
'formated_price' => core()->currency($this->price->getMinimalPrice($product)),
|
||||
'price' => $this->price->getMinimalPrice($product)
|
||||
],
|
||||
'variant_prices' => $this->getVariantPrices($product),
|
||||
'variant_images' => $this->getVariantImages($product),
|
||||
'chooseText' => trans('shop::app.products.choose-option')
|
||||
|
|
@ -201,8 +205,14 @@ class ConfigurableOption extends AbstractProduct
|
|||
|
||||
foreach ($this->getAllowProducts($product) as $variant) {
|
||||
$prices[$variant->id] = [
|
||||
'regular_price' => $variant->price,
|
||||
'final_price' => $this->price->getMinimalPrice($variant),
|
||||
'regular_price' => [
|
||||
'formated_price' => core()->currency($variant->price),
|
||||
'price' => $variant->price
|
||||
],
|
||||
'final_price' => [
|
||||
'formated_price' => core()->currency($this->price->getMinimalPrice($variant)),
|
||||
'price' => $this->price->getMinimalPrice($variant)
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
use Webkul\Shipping\Contracts\Carrier;
|
||||
|
||||
class FlatRate extends Carrier
|
||||
{
|
||||
public function calculateRates()
|
||||
{
|
||||
return [
|
||||
'code' => 'flatrate',
|
||||
'title' => 'Flatrate',
|
||||
'rates' => [
|
||||
[
|
||||
'title' => 'Flat Rate',
|
||||
'rate' => 10
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
use Webkul\Shipping\Contracts\Carrier;
|
||||
|
||||
class PerProduct extends Carrier
|
||||
{
|
||||
public function calculeRates()
|
||||
{
|
||||
return [
|
||||
'code' => 'perproduct',
|
||||
'title' => 'Per Product',
|
||||
'rates' => [
|
||||
[
|
||||
'title' => 'Per Product',
|
||||
'rate' => 10
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
abstract class Carrier {
|
||||
|
||||
abstract public function calculateRates();
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Config;
|
||||
|
||||
class Rates {
|
||||
|
||||
public function collectRates()
|
||||
{
|
||||
$rates = [];
|
||||
|
||||
foreach(Config::get('carriers') as $shippingMethod) {
|
||||
if(isset($shippingMethod['class'])) {
|
||||
$object = new $shippingMethod['class'];
|
||||
|
||||
if($rate = $object->calculeRates()) {
|
||||
array_push($rates, $rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $rates;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<span class="price-label">{{ __('shop::app.products.price-label') }}</span>
|
||||
|
||||
<span>{{ core()->currency($priceHelper->getMinimalPrice($product)) }}</span>
|
||||
<span class="final-price">{{ core()->currency($priceHelper->getMinimalPrice($product)) }}</span>
|
||||
|
||||
@else
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@
|
|||
@csrf()
|
||||
|
||||
<input type="hidden" name="product">
|
||||
|
||||
<input type="hidden" name="selected_configurable_option">
|
||||
|
||||
@include ('shop::products.view.gallery')
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
@inject ('configurableOptionHelper', 'Webkul\Product\Product\ConfigurableOption')
|
||||
|
||||
|
||||
<product-options></product-options>
|
||||
|
||||
@push('scripts')
|
||||
|
|
@ -10,39 +9,52 @@
|
|||
<script type="text/x-template" id="product-options-template">
|
||||
<div class="attributes">
|
||||
|
||||
<input type="hidden" name="selected_configurable_option" :value="selectedProductId">
|
||||
|
||||
<div v-for='(attribute, index) in childAttributes' class="attribute control-group" :class="[errors.has('super_attribute[' + attribute.id + ']') ? 'has-error' : '']">
|
||||
<label class="reqiured">@{{ attribute.label }}</label>
|
||||
|
||||
<select v-validate="'required'" class="control" :name="['super_attribute[' + attribute.id + ']']" :disabled="attribute.disabled" @change="configure(attribute, $event.target.value)">
|
||||
<select v-validate="'required'" class="control" :name="['super_attribute[' + attribute.id + ']']" :disabled="attribute.disabled" @change="configure(attribute, $event.target.value)" :id="['attribute_' + attribute.id]">
|
||||
|
||||
<option v-for='(option, index) in attribute.options' :value="option.id">@{{ option.label }}</option>
|
||||
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('super_attribute[' + attribute.id + ']')">@{{ errors.first('super_attribute[' + attribute.id + ']') }}</span>
|
||||
<span class="control-error" v-if="errors.has('super_attribute[' + attribute.id + ']')">
|
||||
@{{ errors.first('super_attribute[' + attribute.id + ']') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<?php $config = $configurableOptionHelper->getConfigurationConfig($product) ?>
|
||||
|
||||
<script>
|
||||
|
||||
Vue.component('product-options', {
|
||||
|
||||
template: '#product-options-template',
|
||||
|
||||
data: () => ({
|
||||
config: @json($configurableOptionHelper->getConfigurationConfig($product)),
|
||||
childAttributes: []
|
||||
config: @json($config),
|
||||
|
||||
childAttributes: [],
|
||||
|
||||
selectedProductId: '',
|
||||
|
||||
simpleProduct: null
|
||||
}),
|
||||
|
||||
created () {
|
||||
var config = @json($config);
|
||||
|
||||
var childAttributes = this.childAttributes,
|
||||
attributes = this.config.attributes,
|
||||
attributes = config.attributes.slice(),
|
||||
index = attributes.length,
|
||||
attribute;
|
||||
|
||||
while (index--) {
|
||||
// attribute = Object.assign({}, attributes[index]);
|
||||
attribute = attributes[index];
|
||||
|
||||
attribute.options = [];
|
||||
|
|
@ -65,32 +77,68 @@
|
|||
|
||||
methods: {
|
||||
configure (attribute, value) {
|
||||
// this.simpleProduct = this._getSimpleProductId(attribute);
|
||||
this.simpleProduct = this.getSelectedProductId(attribute, value);
|
||||
|
||||
if (value) {
|
||||
attribute.selectedIndex = this.getSelectedIndex(attribute, value);
|
||||
|
||||
if (attribute.nextAttribute) {
|
||||
attribute.nextAttribute.disabled = false;
|
||||
|
||||
this.fillSelect(attribute.nextAttribute);
|
||||
this.resetChildren(attribute.nextAttribute);
|
||||
} else {
|
||||
//Set product id hidden value
|
||||
this.selectedProductId = attribute.options[attribute.selectedIndex].allowedProducts[0];
|
||||
}
|
||||
} else {
|
||||
attribute.selectedIndex = 0;
|
||||
|
||||
this.resetChildren(attribute);
|
||||
|
||||
this.clearSelect(attribute.nextAttribute)
|
||||
}
|
||||
|
||||
// this.reloadPrice();
|
||||
// this.changeProductImage();
|
||||
this.reloadPrice();
|
||||
this.changeProductImages();
|
||||
},
|
||||
|
||||
getSelectedIndex (attribute, value) {
|
||||
var selectedIndex = 0;
|
||||
|
||||
attribute.options.forEach(function(option, index) {
|
||||
if(option.id == value) {
|
||||
selectedIndex = index;
|
||||
}
|
||||
})
|
||||
|
||||
return selectedIndex;
|
||||
},
|
||||
|
||||
getSelectedProductId (attribute, value) {
|
||||
var options = attribute.options,
|
||||
matchedOptions;
|
||||
|
||||
matchedOptions = options.filter(function (option) {
|
||||
return option.id == value;
|
||||
});
|
||||
|
||||
if(matchedOptions[0] != undefined && matchedOptions[0].allowedProducts != undefined) {
|
||||
return matchedOptions[0].allowedProducts[0];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
|
||||
fillSelect (attribute) {
|
||||
var options = this.getAttributeOptions(attribute.id),
|
||||
prevOption,
|
||||
index = 1,
|
||||
products,
|
||||
allowedProducts,
|
||||
i,
|
||||
j;
|
||||
|
||||
this.clearSelect(attribute)
|
||||
|
||||
attribute.options = [];
|
||||
attribute.options[0] = {'id': '', 'label': this.config.chooseText, 'products': []};
|
||||
|
||||
|
|
@ -98,25 +146,23 @@
|
|||
prevOption = attribute.prevAttribute.options[attribute.prevAttribute.selectedIndex];
|
||||
}
|
||||
|
||||
// console.log(attribute)
|
||||
|
||||
if (options) {
|
||||
for (i = 0; i < options.length; i++) {
|
||||
products = [];
|
||||
allowedProducts = [];
|
||||
|
||||
if (prevOption) {
|
||||
for (j = 0; j < options[i].products.length; j++) {
|
||||
if (prevOption.products &&
|
||||
prevOption.products.indexOf(options[i].products[j]) > -1) {
|
||||
products.push(options[i].products[j]);
|
||||
if (prevOption.products && prevOption.products.indexOf(options[i].products[j]) > -1) {
|
||||
allowedProducts.push(options[i].products[j]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
products = options[i].products.slice(0);
|
||||
allowedProducts = options[i].products.slice(0);
|
||||
}
|
||||
|
||||
if (products.length > 0) {
|
||||
options[i].products = products;
|
||||
if (allowedProducts.length > 0) {
|
||||
options[i].allowedProducts = allowedProducts;
|
||||
|
||||
attribute.options[index] = options[i];
|
||||
|
||||
index++;
|
||||
|
|
@ -133,12 +179,22 @@
|
|||
});
|
||||
}
|
||||
},
|
||||
|
||||
clearSelect: function (attribute) {
|
||||
if(!attribute)
|
||||
return;
|
||||
|
||||
var element = document.getElementById("attribute_" + attribute.id);
|
||||
|
||||
if(element) {
|
||||
element.selectedIndex = "0";
|
||||
}
|
||||
},
|
||||
|
||||
getAttributeOptions (attributeId) {
|
||||
var this_this = this,
|
||||
options;
|
||||
|
||||
|
||||
this.config.attributes.forEach(function(attribute, index) {
|
||||
if (attribute.id == attributeId) {
|
||||
options = attribute.options;
|
||||
|
|
@ -149,11 +205,30 @@
|
|||
},
|
||||
|
||||
reloadPrice () {
|
||||
var selectedOptionCount = 0;
|
||||
|
||||
this.childAttributes.forEach(function(attribute) {
|
||||
if(attribute.selectedIndex) {
|
||||
selectedOptionCount++;
|
||||
}
|
||||
});
|
||||
|
||||
var priceLabelElement = document.querySelector('.price-label');
|
||||
var priceElement = document.querySelector('.final-price');
|
||||
|
||||
if(this.childAttributes.length == selectedOptionCount) {
|
||||
priceLabelElement.style.display = 'none';
|
||||
|
||||
priceElement.innerHTML = this.config.variant_prices[this.simpleProduct].final_price.formated_price;
|
||||
} else {
|
||||
priceLabelElement.style.display = 'inline-block';
|
||||
|
||||
priceElement.innerHTML = this.config.regular_price.formated_price;
|
||||
}
|
||||
},
|
||||
|
||||
changeProductImage () {
|
||||
|
||||
changeProductImages () {
|
||||
console.log(this.config.variant_images[this.simpleProduct])
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,4 +13,16 @@
|
|||
<img class="share" src="{{ bagisto_asset('images/icon-share.svg') }}" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
|
||||
<script>
|
||||
|
||||
Vue.component('product-gallery', {
|
||||
props: ['images']
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@endpush
|
||||
Loading…
Reference in New Issue