Configurable options added

This commit is contained in:
jitendra 2018-09-11 16:00:02 +05:30
parent 4fb084557d
commit 5202729391
11 changed files with 227 additions and 32 deletions

View File

@ -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
]
];

View File

@ -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);

View File

@ -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)
],
];
}

View File

@ -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
]
]
];
}
}
?>

View File

@ -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
]
]
];
}
}
?>

View File

@ -0,0 +1,9 @@
<?php
abstract class Carrier {
abstract public function calculateRates();
}
?>

View File

@ -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;
}
}
?>

View File

@ -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

View File

@ -15,8 +15,6 @@
@csrf()
<input type="hidden" name="product">
<input type="hidden" name="selected_configurable_option">
@include ('shop::products.view.gallery')

View File

@ -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])
},
}

View File

@ -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