Product system performance optimization

This commit is contained in:
jitendra 2022-07-07 17:19:32 +05:30
parent 2790a6e1ff
commit a5a1111484
15 changed files with 314 additions and 220 deletions

View File

@ -206,6 +206,23 @@ class AttributeRepository extends Repository
return $attributes[$code] = $this->findOneByField('code', $code);
}
/**
* Get attribute by id.
*
* @param integer $id
* @return \Webkul\Attribute\Contracts\Attribute
*/
public function getAttributeById($id)
{
static $attributes = [];
if (array_key_exists($id, $attributes)) {
return $attributes[$id];
}
return $attributes[$id] = $this->find($id);
}
/**
* Get family attributes.
*

View File

@ -367,6 +367,8 @@ class CartRule
$cart->save();
Cart::setCart($cart);
return $this;
}
@ -430,6 +432,8 @@ class CartRule
$cart->applied_cart_rule_ids = join(',', $cartAppliedCartRuleIds);
$cart->save();
Cart::setCart($cart);
}
/**

View File

@ -49,6 +49,7 @@ class Cart
{
}
protected $cart;
/**
* Returns cart.
*
@ -56,20 +57,31 @@ class Cart
*/
public function getCart(): ?\Webkul\Checkout\Contracts\Cart
{
$cart = null;
if ($this->cart) {
return $this->cart;
}
if (auth()->guard()->check()) {
$cart = $this->cartRepository->findOneWhere([
$this->cart = $this->cartRepository->findOneWhere([
'customer_id' => auth()->guard()->user()->id,
'is_active' => 1,
]);
} else if (session()->has('cart')) {
$cart = $this->cartRepository->find(session()->get('cart')->id);
$this->cart = $this->cartRepository->find(session()->get('cart')->id);
}
$this->removeInactiveItems($cart);
$this->removeInactiveItems($this->cart);
return $cart;
return $this->cart;
}
/**
* Returns cart.
*
* @return \Webkul\Checkout\Contracts\Cart|null
*/
public function setCart($cart)
{
$this->cart = $cart;
}
/**
@ -158,6 +170,8 @@ class Cart
}
}
$this->setCart($cart);
Event::dispatch('checkout.cart.add.after', $cart);
$this->collectTotals();
@ -280,6 +294,8 @@ class Cart
if (session()->has('cart')) {
session()->forget('cart');
}
$this->setCart(null);
}
Shipping::collectRates();
@ -313,7 +329,9 @@ class Cart
$this->removeItem($item->id);
}
Event::dispatch('checkout.cart.delete.all.after', $cart);
$this->setCart(null);
Event::dispatch('checkout.cart.delete.all.after', null);
return $cart;
}
@ -341,6 +359,8 @@ class Cart
if (session()->has('cart')) {
session()->forget('cart');
}
$this->setCart(null);
}
session()->flash('info', __('shop::app.checkout.cart.item.inactive'));
@ -377,6 +397,8 @@ class Cart
$cart->save();
$this->setCart($cart);
$this->collectTotals();
return true;
@ -401,6 +423,8 @@ class Cart
$cart->shipping_method = $shippingMethodCode;
$cart->save();
$this->setCart($cart);
return true;
}
@ -492,6 +516,8 @@ class Cart
$cart->save();
$this->setCart($cart);
Event::dispatch('checkout.cart.collect.totals.after', $cart);
}
@ -543,6 +569,8 @@ class Cart
$item->save();
}
$this->setCart($cart);
Event::dispatch('checkout.cart.calculate.items.tax.after', $cart);
}

View File

@ -49,6 +49,6 @@ class CheckoutServiceProvider extends ServiceProvider
return new Cart();
});
$this->app->bind('cart', \Webkul\Checkout\Cart::class);
$this->app->singleton('cart', \Webkul\Checkout\Cart::class);
}
}

View File

@ -25,6 +25,8 @@ trait CartCoupons
$cart->save();
$this->setCart($cart);
return $this;
}
@ -41,6 +43,8 @@ trait CartCoupons
$cart->save();
$this->setCart($cart);
return $this;
}
}

View File

@ -68,6 +68,8 @@ trait CartTools
$this->cartRepository->delete($guestCart->id);
$this->setCart($cart);
session()->forget('cart');
}
}
@ -239,6 +241,8 @@ trait CartTools
if (! $cart->items->count()) {
$this->cartRepository->delete($cart->id);
$this->setCart(null);
}
$this->collectTotals();

View File

@ -55,12 +55,18 @@ class ConfigurableOption extends AbstractProduct
/**
* Get allowed attributes.
*
* @param \Webkul\Product\Contracts\Product|\Webkul\Product\Contracts\ProductFlat $product
* @param \W\Webkul\Product\Contracts\ProductFlat $product
* @return \Illuminate\Support\Collection
*/
public function getAllowAttributes($product)
{
return $product->product->super_attributes;
static $productSuperAttributes = [];
if (isset($productSuperAttributes[$product->id])) {
return $productSuperAttributes[$product->id];
}
return $productSuperAttributes[$product->id] = $product->product->super_attributes()->with(['translation', 'options', 'options.translation'])->get();
}
/**

View File

@ -151,33 +151,7 @@ class ProductController extends Controller
*/
public function update(ProductForm $request, $id)
{
$data = request()->all();
$multiselectAttributeCodes = [];
$productAttributes = $this->productRepository->findOrFail($id);
foreach ($productAttributes->attribute_family->attribute_groups as $attributeGroup) {
$customAttributes = $productAttributes->getEditableAttributes($attributeGroup);
if (count($customAttributes)) {
foreach ($customAttributes as $attribute) {
if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox') {
array_push($multiselectAttributeCodes, $attribute->code);
}
}
}
}
if (count($multiselectAttributeCodes)) {
foreach ($multiselectAttributeCodes as $multiselectAttributeCode) {
if (! isset($data[$multiselectAttributeCode])) {
$data[$multiselectAttributeCode] = [];
}
}
}
$this->productRepository->update($data, $id);
$this->productRepository->update(request()->all(), $id);
session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Product']));

View File

@ -13,13 +13,6 @@ use Webkul\Product\Models\ProductAttributeValue;
class ProductFlat
{
/**
* Attribute Object
*
* @var \Webkul\Attribute\Contracts\Attribute
*/
protected $attribute;
/**
* Attribute codes that can be fill during flat creation.
*
@ -50,6 +43,11 @@ class ProductFlat
'checkbox' => 'text',
];
/**
* @var array
*/
protected $flatColumns = [];
/**
* Create a new listener instance.
*
@ -66,6 +64,7 @@ class ProductFlat
protected ProductAttributeValueRepository $productAttributeValueRepository
)
{
$this->flatColumns = Schema::getColumnListing('product_flat');
}
/**
@ -82,10 +81,11 @@ class ProductFlat
if (! $attribute->use_in_flat) {
$this->afterAttributeDeleted($attribute->id);
return false;
}
if (! Schema::hasColumn('product_flat', $attribute->code)) {
if (! in_array($attribute->code, $this->flatColumns)) {
Schema::table('product_flat', function (Blueprint $table) use($attribute) {
$table->{$this->attributeTypeFields[$attribute->type]}($attribute->code)->nullable();
@ -106,7 +106,7 @@ class ProductFlat
{
$attribute = $this->attributeRepository->find($attributeId);
if (Schema::hasColumn('product_flat', strtolower($attribute->code))) {
if (in_array(strtolower($attribute->code), $this->flatColumns)) {
Schema::table('product_flat', function (Blueprint $table) use($attribute) {
$table->dropColumn($attribute->code);
@ -115,7 +115,7 @@ class ProductFlat
}
});
$this->productFlatRepository->updateAttributeColumn( $attribute , $this );
$this->productFlatRepository->updateAttributeColumn( $attribute , $this);
}
}
@ -150,8 +150,8 @@ class ProductFlat
static $superAttributes = [];
if (! array_key_exists($product->attribute_family->id, $familyAttributes)) {
$familyAttributes[$product->attribute_family->id] = $product->attribute_family->custom_attributes;
if (! array_key_exists($product->attribute_family_id, $familyAttributes)) {
$familyAttributes[$product->attribute_family_id] = $product->attribute_family->custom_attributes;
}
if ($parentProduct && ! array_key_exists($parentProduct->id, $superAttributes)) {
@ -161,72 +161,69 @@ class ProductFlat
if (isset($product['channels'])) {
foreach ($product['channels'] as $channel) {
$channel = app('Webkul\Core\Repositories\ChannelRepository')->findOrFail($channel);
$channels[] = $channel['code'];
}
} elseif (isset($parentProduct['channels'])){
} else if (isset($parentProduct['channels'])){
foreach ($parentProduct['channels'] as $channel) {
$channel = app('Webkul\Core\Repositories\ChannelRepository')->findOrFail($channel);
$channels[] = $channel['code'];
}
} else {
$channels[] = core()->getDefaultChannelCode();
}
$attributeValues = $product->attribute_values()->get();
foreach (core()->getAllChannels() as $channel) {
if (in_array($channel->code, $channels)) {
foreach ($channel->locales as $locale) {
$productFlat = $this->productFlatRepository->findOneWhere([
$productFlat = $this->productFlatRepository->updateOrCreate([
'product_id' => $product->id,
'channel' => $channel->code,
'locale' => $locale->code,
]);
if (! $productFlat) {
$productFlat = $this->productFlatRepository->create([
'product_id' => $product->id,
'channel' => $channel->code,
'locale' => $locale->code,
]);
}
foreach ($familyAttributes[$product->attribute_family->id] as $attribute) {
if ($parentProduct && ! in_array($attribute->code, array_merge($superAttributes[$parentProduct->id], $this->fillableAttributeCodes))) {
continue;
}
if (in_array($attribute->code, ['tax_category_id'])) {
continue;
}
if (! Schema::hasColumn('product_flat', $attribute->code)) {
foreach ($familyAttributes[$product->attribute_family_id] as $attribute) {
if (($parentProduct
&& ! in_array($attribute->code, array_merge($superAttributes[$parentProduct->id], $this->fillableAttributeCodes)))
|| in_array($attribute->code, ['tax_category_id'])
|| ! in_array($attribute->code, $this->flatColumns)
) {
continue;
}
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
$productAttributeValue = $product->attribute_values()
->where('channel', $channel->code)
->where('locale', $locale->code)
->where('attribute_id', $attribute->id)
->first();
$productAttributeValue = $attributeValues
->where('channel', $channel->code)
->where('locale', $locale->code)
->where('attribute_id', $attribute->id)
->first();
} else {
$productAttributeValue = $product->attribute_values()
->where('channel', $channel->code)
->where('attribute_id', $attribute->id)
->first();
$productAttributeValue = $attributeValues
->where('channel', $channel->code)
->where('attribute_id', $attribute->id)
->first();
}
} else {
if ($attribute->value_per_locale) {
$productAttributeValue = $product->attribute_values()->where('locale', $locale->code)->where('attribute_id', $attribute->id)->first();
$productAttributeValue = $attributeValues
->where('locale', $locale->code)
->where('attribute_id', $attribute->id)
->first();
} else {
$productAttributeValue = $product->attribute_values()->where('attribute_id', $attribute->id)->first();
$productAttributeValue = $attributeValues
->where('attribute_id', $attribute->id)
->first();
}
}
$productFlat->{$attribute->code} = $productAttributeValue[ProductAttributeValue::$attributeTypeFields[$attribute->type]] ?? null;
if ($attribute->type == 'select') {
$attributeOption = $this->attributeOptionRepository->find($product->{$attribute->code});
$attributeOption = $this->getAttributeOptions($productFlat->{$attribute->code});
if ($attributeOption) {
if ($attributeOptionTranslation = $attributeOption->translate($locale->code)) {
@ -236,10 +233,10 @@ class ProductFlat
}
}
} elseif ($attribute->type == 'multiselect') {
$attributeOptionIds = explode(',', $product->{$attribute->code});
$attributeOptionIds = explode(',', $productFlat->{$attribute->code});
if (count($attributeOptionIds)) {
$attributeOptions = $this->attributeOptionRepository->findWhereIn('id', $attributeOptionIds);
$attributeOptions = $this->getAttributeOptions($productFlat->{$attribute->code});
$optionLabels = [];
@ -256,10 +253,6 @@ class ProductFlat
}
}
$productFlat->created_at = $product->created_at;
$productFlat->updated_at = $product->updated_at;
$productFlat->min_price = $product->getTypeInstance()->getMinimalPrice();
$productFlat->max_price = $product->getTypeInstance()->getMaximamPrice();
@ -294,4 +287,29 @@ class ProductFlat
}
}
}
/**
* @param string $value
* @return mixed
*/
public function getAttributeOptions($value)
{
if (! $value) {
return;
}
static $attributeOptions = [];
if (array_key_exists($value, $attributeOptions)) {
return $attributeOptions[$value];
}
if (is_numeric($value)) {
return $attributeOptions[$value] = $this->attributeOptionRepository->find($value);
} else {
$attributeOptionIds = explode(',', $value);
return $attributeOptions[$value] = $this->attributeOptionRepository->findWhereIn('id', $attributeOptionIds);
}
}
}

View File

@ -441,19 +441,17 @@ class Product extends Model implements ProductContract
*/
public function getAttribute($key)
{
if (! method_exists(static::class, $key)
&& ! in_array($key, [
'pivot',
'parent_id',
'attribute_family_id',
])
&& ! isset($this->attributes[$key])) {
&& ! isset($this->attributes[$key])
) {
if (isset($this->id)) {
$this->attributes[$key] = '';
$attribute = core()
->getSingletonInstance(AttributeRepository::class)
->getAttributeByCode($key);
$attribute = $this->checkInLoadedFamilyAttributes()->where('code', $key)->first();
$this->attributes[$key] = $this->getCustomAttributeValue($attribute);
@ -500,25 +498,25 @@ class Product extends Model implements ProductContract
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
$attributeValue = $this->attribute_values()
$attributeValue = $this->attribute_values
->where('channel', $channel)
->where('locale', $locale)
->where('attribute_id', $attribute->id)
->first();
} else {
$attributeValue = $this->attribute_values()
$attributeValue = $this->attribute_values
->where('channel', $channel)
->where('attribute_id', $attribute->id)
->first();
}
} else {
if ($attribute->value_per_locale) {
$attributeValue = $this->attribute_values()
$attributeValue = $this->attribute_values
->where('locale', $locale)
->where('attribute_id', $attribute->id)
->first();
} else {
$attributeValue = $this->attribute_values()
$attributeValue = $this->attribute_values
->where('attribute_id', $attribute->id)
->first();
}

View File

@ -45,7 +45,7 @@ class ProductFlat extends Model implements ProductFlatContract
*
* @var boolean
*/
public $timestamps = false;
// public $timestamps = false;
/**
* Get the index name for the model.
@ -137,16 +137,6 @@ class ProductFlat extends Model implements ProductFlatContract
return $this->hasMany(static::class, 'parent_id');
}
/**
* Get all of the attributes for the attribute groups.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function getImagesAttribute()
{
return $this->images()->get();
}
/**
* The images that belong to the product.
*
@ -165,18 +155,7 @@ class ProductFlat extends Model implements ProductFlatContract
*/
public function videos()
{
return $this->product->videos()
->orderBy('position');
}
/**
* Get all of the reviews for the attribute groups.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function getReviewsAttribute()
{
return $this->reviews()->get();
return $this->product->videos()->orderBy('position');
}
/**

View File

@ -9,21 +9,6 @@ use Webkul\Product\Models\ProductAttributeValueProxy;
class ProductAttributeValueRepository extends Repository
{
/**
* Create a new reposotory instance.
*
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
* @param \Illuminate\Container\Container $app
* @return void
*/
public function __construct(
protected AttributeRepository $attributeRepository,
App $app
)
{
parent::__construct($app);
}
/**
* Specify Model class name
*
@ -34,27 +19,6 @@ class ProductAttributeValueRepository extends Repository
return 'Webkul\Product\Contracts\ProductAttributeValue';
}
/**
* @param array $data
* @return \Webkul\Product\Contracts\ProductAttributeValue
*/
public function create(array $data)
{
if (isset($data['attribute_id'])) {
$attribute = $this->attributeRepository->find($data['attribute_id']);
} else {
$attribute = $this->attributeRepository->findOneByField('code', $data['attribute_code']);
}
if (! $attribute) {
return;
}
$data[ProductAttributeValueProxy::modelClass()::$attributeTypeFields[$attribute->type]] = $data['value'];
return $this->model->create($data);
}
/**
* @param string $column
* @param int $attributeId

View File

@ -77,7 +77,7 @@ class ProductRepository extends Repository
{
Event::dispatch('catalog.product.update.before', $id);
$product = $this->find($id);
$product = $this->findOrFail($id);
$product = $product->getTypeInstance()->update($data, $id, $attribute);

View File

@ -177,6 +177,10 @@ abstract class AbstractType
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
}
if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox') {
$data[$attribute->code] = isset($data[$attribute->code]) ? implode(',', $data[$attribute->code]) : null;
}
if (! isset($data[$attribute->code])) {
continue;
}
@ -189,38 +193,50 @@ abstract class AbstractType
$data[$attribute->code] = null;
}
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'
? request()->file($attribute->code)->store('product/' . $product->id)
: null;
}
$attributeValue = $this->attributeValueRepository->findOneWhere([
'product_id' => $product->id,
'attribute_id' => $attribute->id,
'channel' => $attribute->value_per_channel ? $data['channel'] : null,
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
]);
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
$productAttributeValue = $product->attribute_values
->where('channel', $attribute->value_per_channel ? $data['channel'] : null)
->where('locale', $attribute->value_per_locale ? $data['locale'] : null)
->where('attribute_id', $attribute->id)
->first();
} else {
$productAttributeValue = $product->attribute_values
->where('channel', $attribute->value_per_channel ? $data['channel'] : null)
->where('attribute_id', $attribute->id)
->first();
}
} else {
if ($attribute->value_per_locale) {
$productAttributeValue = $product->attribute_values
->where('locale', $attribute->value_per_locale ? $data['locale'] : null)
->where('attribute_id', $attribute->id)
->first();
} else {
$productAttributeValue = $product->attribute_values
->where('attribute_id', $attribute->id)
->first();
}
}
if (! $attributeValue) {
$columnName = ProductAttributeValue::$attributeTypeFields[$attribute->type];
if (! $productAttributeValue) {
$this->attributeValueRepository->create([
'product_id' => $product->id,
'attribute_id' => $attribute->id,
'value' => $data[$attribute->code],
$columnName => $data[$attribute->code],
'channel' => $attribute->value_per_channel ? $data['channel'] : null,
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
]);
} else {
$this->attributeValueRepository->update(
[
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code],
],
$attributeValue->id
);
$productAttributeValue->update([$columnName => $data[$attribute->code]]);
if ($attribute->type == 'image' || $attribute->type == 'file') {
Storage::delete($attributeValue->text_value);
@ -271,6 +287,28 @@ abstract class AbstractType
return $this;
}
/**
* @param string $code
* @return mixed
*/
public function getAttributeByCode($code)
{
return core()
->getSingletonInstance(AttributeRepository::class)
->getAttributeByCode($code);
}
/**
* @param integer $id
* @return mixed
*/
public function getAttributeById($id)
{
return core()
->getSingletonInstance(AttributeRepository::class)
->getAttributeById($id);
}
/**
* Returns children ids.
*
@ -413,7 +451,7 @@ abstract class AbstractType
}
}
$orderedInventory = $this->product->ordered_inventories()
$orderedInventory = $this->product->ordered_inventories
->where('channel_id', core()->getCurrentChannel()->id)->first();
if ($orderedInventory) {
@ -535,6 +573,12 @@ abstract class AbstractType
*/
public function haveSpecialPrice($qty = null)
{
static $haveSpecialPrice = null;
if (! is_null($haveSpecialPrice)) {
return $haveSpecialPrice;
}
$customerGroupPrice = $this->getCustomerGroupPrice($this->product, $qty);
$rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
@ -715,7 +759,7 @@ abstract class AbstractType
if ($taxCategory = $this->getTaxCategory()) {
if ($address === null && auth()->guard('customer')->check()) {
$address = auth()->guard('customer')->user()->addresses()->where('default_address', 1)->first();
$address = auth()->guard('customer')->user()->addresses->where('default_address', 1)->first();
}
if ($address === null) {
@ -959,9 +1003,7 @@ abstract class AbstractType
if (auth()->guard()->check()) {
$customerGroupId = auth()->guard()->user()->customer_group_id;
} else {
$customerGroupRepository = app('Webkul\Customer\Repositories\CustomerGroupRepository');
if ($customerGuestGroup = $customerGroupRepository->findOneByField('code', 'guest')) {
if ($customerGuestGroup = app(CustomerGroupRepository::class)->findOneByField('code', 'guest')) {
$customerGroupId = $customerGuestGroup->id;
}
}

View File

@ -129,7 +129,7 @@ class Configurable extends AbstractType
$super_attributes = [];
foreach ($data['super_attributes'] as $attributeCode => $attributeOptions) {
$attribute = $this->attributeRepository->findOneByField('code', $attributeCode);
$attribute = $this->getAttributeByCode($attributeCode);
$super_attributes[$attribute->id] = $attributeOptions;
@ -233,69 +233,92 @@ class Configurable extends AbstractType
'sku' => $data['sku'],
]);
$attributeValues = [];
foreach ($this->fillableTypes as $attributeCode) {
if (! isset($data[$attributeCode])) {
continue;
}
$attribute = $this->attributeRepository->findOneByField('code', $attributeCode);
$attribute = $this->getAttributeByCode($attributeCode);
$attributeTypeFields = $this->getAttributeTypeValues($attribute->type, $data[$attributeCode]);
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
foreach (core()->getAllChannels() as $channel) {
foreach (core()->getAllLocales() as $locale) {
$this->attributeValueRepository->create([
$attributeValues[] = array_merge($attributeTypeFields, [
'product_id' => $variant->id,
'attribute_id' => $attribute->id,
'channel' => $channel->code,
'locale' => $locale->code,
'value' => $data[$attributeCode],
]);
}
}
} else {
foreach (core()->getAllChannels() as $channel) {
$this->attributeValueRepository->create([
$attributeValues[] = array_merge($attributeTypeFields, [
'product_id' => $variant->id,
'attribute_id' => $attribute->id,
'channel' => $channel->code,
'value' => $data[$attributeCode],
'locale' => null,
]);
}
}
} else {
if ($attribute->value_per_locale) {
foreach (core()->getAllLocales() as $locale) {
$this->attributeValueRepository->create([
$attributeValues[] = array_merge($attributeTypeFields, [
'product_id' => $variant->id,
'attribute_id' => $attribute->id,
'channel' => null,
'locale' => $locale->code,
'value' => $data[$attributeCode],
]);
}
} else {
$this->attributeValueRepository->create([
$attributeValues[] = array_merge($attributeTypeFields, [
'product_id' => $variant->id,
'attribute_id' => $attribute->id,
'value' => $data[$attributeCode],
'channel' => null,
'locale' => null,
]);
}
}
}
foreach ($permutation as $attributeId => $optionId) {
$this->attributeValueRepository->create([
$attribute = $this->getAttributeById($attributeId);
$attributeValues[] = array_merge($this->getAttributeTypeValues($attribute->type, $optionId), [
'product_id' => $variant->id,
'attribute_id' => $attributeId,
'value' => $optionId,
'channel' => null,
'locale' => null,
]);
}
$this->attributeValueRepository->insert($attributeValues);
$this->productInventoryRepository->saveInventories($data, $variant);
return $variant;
}
/**
* @param string $attributeType
* @param mixed $value
* @return array
*/
public function getAttributeTypeValues($attributeType, $value)
{
$attributeTypeFields = array_fill_keys(array_values(ProductAttributeValue::$attributeTypeFields), null);
$attributeTypeFields[ProductAttributeValue::$attributeTypeFields[$attributeType]] = $value;
return $attributeTypeFields;
}
/**
* Update variant.
*
@ -314,27 +337,46 @@ class Configurable extends AbstractType
continue;
}
$attribute = $this->attributeRepository->findOneByField('code', $attributeCode);
$attribute = $this->getAttributeByCode($attributeCode);
$attributeValue = $this->attributeValueRepository->findOneWhere([
'product_id' => $id,
'attribute_id' => $attribute->id,
'channel' => $attribute->value_per_channel ? $data['channel'] : null,
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
]);
if ($attribute->value_per_channel) {
if ($attribute->value_per_locale) {
$productAttributeValue = $variant->attribute_values
->where('channel', $attribute->value_per_channel ? $data['channel'] : null)
->where('locale', $attribute->value_per_locale ? $data['locale'] : null)
->where('attribute_id', $attribute->id)
->first();
} else {
$productAttributeValue = $variant->attribute_values
->where('channel', $attribute->value_per_channel ? $data['channel'] : null)
->where('attribute_id', $attribute->id)
->first();
}
} else {
if ($attribute->value_per_locale) {
$productAttributeValue = $variant->attribute_values
->where('locale', $attribute->value_per_locale ? $data['locale'] : null)
->where('attribute_id', $attribute->id)
->first();
} else {
$productAttributeValue = $variant->attribute_values
->where('attribute_id', $attribute->id)
->first();
}
}
if (! $attributeValue) {
$columnName = ProductAttributeValue::$attributeTypeFields[$attribute->type];
if (! $productAttributeValue) {
$this->attributeValueRepository->create([
'product_id' => $id,
'product_id' => $variant->id,
'attribute_id' => $attribute->id,
'value' => $data[$attribute->code],
$columnName => $data[$attribute->code],
'channel' => $attribute->value_per_channel ? $data['channel'] : null,
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
]);
} else {
$this->attributeValueRepository->update([
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code],
], $attributeValue->id);
$productAttributeValue->update([$columnName => $data[$attribute->code]]);
}
}
@ -457,7 +499,11 @@ class Configurable extends AbstractType
*/
public function getMinimalPrice($qty = null)
{
$minPrices = [];
static $minPrice = null;
if (! is_null($minPrice)) {
return $minPrice;
}
/* method is calling many time so using variable */
$tablePrefix = DB::getTablePrefix();
@ -471,6 +517,9 @@ class Configurable extends AbstractType
->where('product_flat.channel', core()->getCurrentChannelCode())
->get();
$minPrices = [];
foreach ($result as $price) {
$minPrices[] = $price->min_price;
}
@ -479,7 +528,7 @@ class Configurable extends AbstractType
return 0;
}
return min($minPrices);
return $minPrice = min($minPrices);
}
/**
@ -489,6 +538,12 @@ class Configurable extends AbstractType
*/
public function getOfferPrice()
{
static $offerPrice = null;
if (! is_null($offerPrice)) {
return $offerPrice;
}
$rulePrices = $customerGroupPrices = [];
foreach ($this->product->variants as $variant) {
@ -502,10 +557,10 @@ class Configurable extends AbstractType
}
if ($rulePrices || $customerGroupPrices) {
return min(array_merge($rulePrices, $customerGroupPrices));
return $offerPrice = min(array_merge($rulePrices, $customerGroupPrices));
}
return [];
return $offerPrice = [];
}
/**
@ -515,16 +570,11 @@ class Configurable extends AbstractType
*/
public function haveOffer()
{
$haveOffer = false;
$offerPrice = $this->getOfferPrice();
$minPrice = $this->getMinimalPrice();
if ($offerPrice < $minPrice) {
$haveOffer = true;
if ($this->getOfferPrice() < $this->getMinimalPrice()) {
return true;
}
return $haveOffer;
return false;
}
/**
@ -534,6 +584,12 @@ class Configurable extends AbstractType
*/
public function getMaximamPrice()
{
static $maxPrice = null;
if (! is_null($maxPrice)) {
return $maxPrice;
}
$productFlat = ProductFlat::join('products', 'product_flat.product_id', '=', 'products.id')
->distinct()
->where('products.parent_id', $this->product->id)
@ -542,7 +598,7 @@ class Configurable extends AbstractType
->where('product_flat.locale', app()->getLocale())
->first();
return $productFlat ? $productFlat->max_price : 0;
return $maxPrice = $productFlat ? $productFlat->max_price : 0;
}
/**
@ -823,7 +879,7 @@ class Configurable extends AbstractType
$total = 0;
$channelInventorySourceIds = core()->getCurrentChannel()
->inventory_sources()
->inventory_sources
->where('status', 1)
->pluck('id');
@ -834,7 +890,7 @@ class Configurable extends AbstractType
}
}
$orderedInventory = $variant->ordered_inventories()
$orderedInventory = $variant->ordered_inventories
->where('channel_id', core()->getCurrentChannel()->id)
->first();