Skip to content

Commit

Permalink
Fixed #3328 element site status and sales
Browse files Browse the repository at this point in the history
  • Loading branch information
nfourtythree committed Nov 15, 2023
1 parent ec844e6 commit 07bc44a
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 59 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
- Improved the performance of the `craft\commerce\elements\db\VariantQuery::hasProduct()` and `craft\commerce\elements\db\ProductQuery::hasVariant()` query params. ([#3325](https://github.com/craftcms/commerce/pull/3325))
- Order statuses with long names no longer line wrap on the Orders index page. ([#3335](https://github.com/craftcms/commerce/issues/3335))
- Fixed duplicate validate errors that occurred when submitting a zero quantity to the cart. ([3334](https://github.com/craftcms/commerce/issues/3334))
- Fixed a bug where tab selection was inconsistent on the Edit Order page.
- Fixed a bug where tab selection was inconsistent on the Edit Order page.
- Fixed a bug where sales weren’t respecting site element statuses. ([#3328](https://github.com/craftcms/commerce/issues/3328))

## 4.3.2 - 2023-10-31

Expand Down
107 changes: 54 additions & 53 deletions src/elements/db/VariantQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -783,21 +783,21 @@ protected function beforePrepare(): bool
// Check to see if we have any sales that match all products and categories
// so we can skip extra processing if needed
$allProductsAndCategoriesSales = ArrayHelper::whereMultiple($activeSales, ['allPurchasables' => 1, 'allCategories' => 1]);
$hasSalesVariantConditions = [];
$hasSalesProductConditions = [];

if (empty($allProductsAndCategoriesSales)) {
$purchasableRestrictedSales = ArrayHelper::whereMultiple($activeSales, ['allPurchasables' => 0]);
$categoryRestrictedSales = ArrayHelper::whereMultiple($activeSales, ['allCategories' => 0]);

$purchasableRestrictedIds = (new Query())
$purchasableRestrictedQuery = (new Query())
->select('purchasableId')
->from(Table::SALE_PURCHASABLES . ' sp')
->where([
'saleId' => ArrayHelper::getColumn($purchasableRestrictedSales, 'id'),
])
->column();
]);
$hasSalesVariantConditions[] = ['commerce_variants.id' => $purchasableRestrictedQuery];

$categoryRestrictedVariantIds = [];
$categoryRestrictedProductIds = [];
if (!empty($categoryRestrictedSales)) {
$sourceSales = ArrayHelper::whereMultiple($categoryRestrictedSales, [
'categoryRelationshipType' => [
Expand All @@ -813,69 +813,70 @@ protected function beforePrepare(): bool
]);

// Source relationships
$sourceVariantIds = [];
$sourceProductIds = [];
if (!empty($sourceSales)) {
$sourceRows = (new Query())
->select('elements.type, rel.sourceId')
$sourceQueryProduct = (new Query())
->select('rel.sourceId')
->from(Table::SALE_CATEGORIES . ' sc')
->leftJoin(CraftTable::RELATIONS . ' rel', '[[rel.targetId]] = [[sc.categoryId]]')
->leftJoin(CraftTable::ELEMENTS . ' elements', '[[elements.id]] = [[rel.sourceId]]')
->leftJoin(CraftTable::ELEMENTS_SITES . ' es', '[[es.elementId]] = [[sc.categoryId]]')
->where(['saleId' => ArrayHelper::getColumn($sourceSales, 'id')])
->andWhere(['elements.type' => Product::class])
->andWhere(Db::parseParam('es.siteId', $this->siteId))
->andWhere(['es.enabled' => true]);
$hasSalesProductConditions[] = ['commerce_variants.productId' => $sourceQueryProduct];

$sourceQueryVariant = (new Query())
->select('rel.sourceId')
->from(Table::SALE_CATEGORIES . ' sc')
->leftJoin(CraftTable::RELATIONS . ' rel', '[[rel.targetId]] = [[sc.categoryId]]')
->leftJoin(CraftTable::ELEMENTS . ' elements', '[[elements.id]] = [[rel.sourceId]]')
->where([
'saleId' => ArrayHelper::getColumn($sourceSales, 'id'),
])
->all();

$sourceProductIds = collect($sourceRows)
->filter(fn($row) => $row['type'] === Product::class)
->map(fn($row) => $row['sourceId'])
->all();

$sourceVariantIds = collect($sourceRows)
->filter(fn($row) => $row['type'] === Variant::class)
->map(fn($row) => $row['sourceId'])
->all();
->leftJoin(CraftTable::ELEMENTS_SITES . ' es', '[[es.elementId]] = [[sc.categoryId]]')
->where(['saleId' => ArrayHelper::getColumn($sourceSales, 'id')])
->andWhere(['elements.type' => Variant::class])
->andWhere(Db::parseParam('es.siteId', $this->siteId))
->andWhere(['es.enabled' => true]);
$hasSalesVariantConditions[] = ['commerce_variants.id' => $sourceQueryVariant];
}

// Target relationships
$targetVariantIds = [];
$targetProductIds = [];
if (!empty($targetSales)) {
$targetRows = (new Query())
->select('elements.type, rel.targetId')
$targetQueryProduct = (new Query())
->select('rel.targetId')
->from(Table::SALE_CATEGORIES . ' sc')
->leftJoin(CraftTable::RELATIONS . ' rel', '[[rel.sourceId]] = [[sc.categoryId]]')
->leftJoin(CraftTable::ELEMENTS . ' elements', '[[elements.id]] = [[rel.targetId]]')
->leftJoin(CraftTable::ELEMENTS_SITES . ' es', '[[es.elementId]] = [[sc.categoryId]]')
->where(['saleId' => ArrayHelper::getColumn($targetSales, 'id')])
->andWhere(['elements.type' => Product::class])
->andWhere(Db::parseParam('es.siteId', $this->siteId))
->andWhere(['es.enabled' => true]);
$hasSalesProductConditions[] = ['commerce_variants.productId' => $targetQueryProduct];

$targetQueryVariant = (new Query())
->select('rel.targetId')
->from(Table::SALE_CATEGORIES . ' sc')
->leftJoin(CraftTable::RELATIONS . ' rel', '[[rel.sourceId]] = [[sc.categoryId]]')
->leftJoin(CraftTable::ELEMENTS . ' elements', '[[elements.id]] = [[rel.targetId]]')
->where([
'saleId' => ArrayHelper::getColumn($targetSales, 'id'),
])
->all();

$targetProductIds = collect($targetRows)
->filter(fn($row) => $row['type'] === Product::class)
->map(fn($row) => $row['targetId'])
->all();

$targetVariantIds = collect($targetRows)
->filter(fn($row) => $row['type'] === Product::class)
->map(fn($row) => $row['targetId'])
->all();
->leftJoin(CraftTable::ELEMENTS_SITES . ' es', '[[es.elementId]] = [[sc.categoryId]]')
->where(['saleId' => ArrayHelper::getColumn($targetSales, 'id')])
->andWhere(['elements.type' => Variant::class])
->andWhere(Db::parseParam('es.siteId', $this->siteId))
->andWhere(['es.enabled' => true]);
$hasSalesVariantConditions[] = ['commerce_variants.id' => $targetQueryVariant];
}

$categoryRestrictedVariantIds = array_merge($sourceVariantIds, $targetVariantIds);
$categoryRestrictedProductIds = array_merge($sourceProductIds, $targetProductIds);
}

$variantIds = array_unique(array_merge($purchasableRestrictedIds, $categoryRestrictedVariantIds));
$productIds = $categoryRestrictedProductIds;
}
}

$hasSalesCondition = [
'or',
['commerce_variants.id' => $variantIds],
['commerce_variants.productId' => $productIds],
];
$hasSalesCondition = ['or'];
if (!empty($hasSalesVariantConditions)) {
$hasSalesCondition[] = array_merge(['or'], $hasSalesVariantConditions);
}

if (!empty($hasSalesProductConditions)) {
$hasSalesCondition[] = array_merge(['or'], $hasSalesProductConditions);
}

if ($this->hasSales) {
$this->subQuery->andWhere($hasSalesCondition);
Expand Down Expand Up @@ -930,7 +931,7 @@ private function _applyHasProductParam(): void

// Remove any blank product IDs (if any)
$productQuery->andWhere(['not', ['commerce_products.id' => null]]);

$this->subQuery->andWhere(['commerce_variants.productId' => $productQuery]);
}

Expand Down
30 changes: 25 additions & 5 deletions src/services/Sales.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,13 @@ public function getSalesForPurchasable(PurchasableInterface $purchasable, Order
return $matchedSales;
}


/**
* @param PurchasableInterface $purchasable
* @return array
*/
public function getSalesRelatedToPurchasable(PurchasableInterface $purchasable): array
{
/** @var Purchasable $purchasable */
$sales = [];
$id = $purchasable->getId();

Expand All @@ -291,8 +295,16 @@ public function getSalesRelatedToPurchasable(PurchasableInterface $purchasable):
$relatedTo = [$sale->categoryRelationshipType => $purchasable->getPromotionRelationSource()];
$saleCategories = $sale->getCategoryIds();

$relatedCategories = Category::find()->id($saleCategories)->relatedTo($relatedTo)->ids();
$relatedEntries = Entry::find()->id($saleCategories)->relatedTo($relatedTo)->ids();
$relatedCategories = Category::find()
->id($saleCategories)
->relatedTo($relatedTo)
->siteId($purchasable->siteId)
->ids();
$relatedEntries = Entry::find()
->id($saleCategories)
->relatedTo($relatedTo)
->siteId($purchasable->siteId)
->ids();
$relatedCategoriesOrEntries = array_merge($relatedCategories, $relatedEntries);

if (in_array($id, $purchasableIds, false) || !empty($relatedCategoriesOrEntries)) {
Expand Down Expand Up @@ -453,8 +465,16 @@ public function matchPurchasableAndSale(PurchasableInterface $purchasable, Sale
if (!$sale->allCategories) {
$relatedTo = [$sale->categoryRelationshipType => $purchasable->getPromotionRelationSource()];
$saleCategories = $sale->getCategoryIds();
$relatedCategories = Category::find()->id($saleCategories)->relatedTo($relatedTo)->ids();
$relatedEntries = Entry::find()->id($saleCategories)->relatedTo($relatedTo)->ids();
$relatedCategories = Category::find()
->id($saleCategories)
->relatedTo($relatedTo)
->siteId($purchasable->siteId)
->ids();
$relatedEntries = Entry::find()
->id($saleCategories)
->relatedTo($relatedTo)
->siteId($purchasable->siteId)
->ids();
$relatedCategoriesOrEntries = array_merge($relatedCategories, $relatedEntries);
if (empty($relatedCategoriesOrEntries)) {
return false;
Expand Down

0 comments on commit 07bc44a

Please sign in to comment.