Skip to content

Commit

Permalink
Feature/sk 323
Browse files Browse the repository at this point in the history
  • Loading branch information
bjuraszewski authored and bvlinsky committed Jul 3, 2022
1 parent b0f3d23 commit 343134b
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 91 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ REDIS_CACHE_PASSWORD=null
REDIS_CACHE_PORT=6379

SCOUT_DRIVER=database
SCOUT_QUEUE=false

EMAIL_HOST=mail.example.com
EMAIL_PORT=587
Expand Down
3 changes: 3 additions & 0 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Providers;

use App\Models\Product;
use App\Services\AnalyticsService;
use App\Services\AppService;
use App\Services\AttributeOptionService;
Expand Down Expand Up @@ -167,5 +168,7 @@ public function boot(): void

return $this;
});

Product::disableSearchSyncing();
}
}
2 changes: 1 addition & 1 deletion app/Services/Contracts/DiscountServiceContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function applyDiscountOnProduct(

public function applyDiscountsOnProducts(Collection $products): void;

public function applyDiscountsOnProduct(Product $product): void;
public function applyDiscountsOnProduct(Product $product, bool $reindex = true): void;

public function applyDiscountOnOrderProduct(OrderProduct $orderProduct, Discount $discount): OrderProduct;

Expand Down
81 changes: 47 additions & 34 deletions app/Services/DiscountService.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,7 @@ public function calcCartDiscounts(CartDto $cart, Collection $products): CartReso
$price += $schema->getPrice($value, $cartItem->getSchemas());
}
$cartValue += $price * $cartItem->getQuantity();
array_push(
$cartItems,
new CartItemResponse($cartItem->getCartItemId(), $price, $price, $cartItem->getQuantity()),
);
$cartItems[] = new CartItemResponse($cartItem->getCartItemId(), $price, $price, $cartItem->getQuantity());
}
$cartShippingTimeAndDate = $this->shippingTimeDateService->getTimeAndDateForCart($cart, $products);

Expand Down Expand Up @@ -379,10 +376,10 @@ public function applyDiscountsOnProducts(Collection $products): void
}
}

public function applyDiscountsOnProduct(Product $product): void
public function applyDiscountsOnProduct(Product $product, bool $reindex = true): void
{
$salesWithBlockList = $this->getSalesWithBlockList();
$this->applyAllDiscountsOnProduct($product, $salesWithBlockList);
$this->applyAllDiscountsOnProduct($product, $salesWithBlockList, $reindex);
}

public function applyDiscountOnOrderProduct(OrderProduct $orderProduct, Discount $discount): OrderProduct
Expand Down Expand Up @@ -526,13 +523,10 @@ public function calculateDiscount(Discount $discount, bool $updated): void
// if job is called after update, then calculate discount for all products,
// because it may change the list of related products or target_is_allow_list value
if (!$updated) {
$products = $this->allDiscountProducts($discount);
$products = $this->allDiscountProductsIds($discount);
}

$this->applyDiscountsOnProductsLazy($products, $salesWithBlockList);

// @phpstan-ignore-next-line
Product::whereIn('id', $products)->searchable();
}

public function checkActiveSales(): void
Expand All @@ -542,28 +536,36 @@ public function checkActiveSales(): void

$oldActiveSales = Collection::make($activeSales);

$products = Collection::make();

$activeSalesIds = $this->activeSales()->pluck('id');
$sales = $activeSalesIds->diff($oldActiveSales)->merge($oldActiveSales->diff($activeSalesIds));
$sales = $activeSalesIds
->diff($oldActiveSales)
->merge($oldActiveSales->diff($activeSalesIds));

$sales = Discount::whereIn('id', $sales)->with(['products', 'productSets', 'productSets.products'])->get();
$sales = Discount::query()
->whereIn('id', $sales)
->with(['products', 'productSets', 'productSets.products'])
->get();

$products = Collection::make();

foreach ($sales as $sale) {
$products = $products->merge($this->allDiscountProducts($sale))->unique();
$products = $products->merge($this->allDiscountProductsIds($sale));
}
$salesWithBlockList = $this->getSalesWithBlockList();

$this->applyDiscountsOnProductsLazy($products, $salesWithBlockList);

// @phpstan-ignore-next-line
Product::whereIn('id', $products)->searchable();
$products = $products->unique();
$this->applyDiscountsOnProductsLazy(
$products,
$this->getSalesWithBlockList(),
);

Cache::put('sales.active', $activeSalesIds);
}

public function applyAllDiscountsOnProduct(Product $product, Collection $salesWithBlockList): void
{
public function applyAllDiscountsOnProduct(
Product $product,
Collection $salesWithBlockList,
bool $reindex = true,
): void {
$sales = $this->sortDiscounts($product->allProductSales($salesWithBlockList));

// prevent error when price_min or price_max is null
Expand Down Expand Up @@ -598,15 +600,18 @@ public function applyAllDiscountsOnProduct(Product $product, Collection $salesWi
// detach and attach only add 2 queries to database, sync add 1 query for every element in given array,
$product->sales()->detach();
$product->sales()->attach($productSales->pluck('id'));
$product->searchable();

if ($reindex) {
$product->searchable();
}
}

private function allDiscountProducts(Discount $discount): Collection
private function allDiscountProductsIds(Discount $discount): Collection
{
$products = $discount->allProductsIds();

if (!$discount->target_is_allow_list) {
$products = Product::whereNotIn('id', $products)->pluck('id');
$products = Product::query()->whereNotIn('id', $products)->pluck('id');
}

// Return only ids of products, that should be discounted
Expand Down Expand Up @@ -883,7 +888,7 @@ private function applyDiscountOnCartItems(Discount $discount, CartDto $cartDto,

$cartItem = $this->applyDiscountOnCartItem($discount, $item, $cart);

array_push($cartItems, $cartItem);
$cartItems[] = $cartItem;

$cartValue += $cartItem->price_discounted * $item->getQuantity();
}
Expand Down Expand Up @@ -925,7 +930,7 @@ private function applyDiscountOnCartCheapestItem(
if ($price !== $minimalProductPrice) {
$newPrice = round($price - $this->calc($price, $discount), 2, PHP_ROUND_HALF_UP);

$cartItem->price_discounted = $newPrice < $minimalProductPrice ? $minimalProductPrice : $newPrice;
$cartItem->price_discounted = max($newPrice, $minimalProductPrice);

$cart->cart_total -= ($price - $cartItem->price_discounted) * $cartItem->quantity;
}
Expand Down Expand Up @@ -967,7 +972,7 @@ private function calcPrice(float $price, string $productId, Discount $discount):

if ($price !== $minimalProductPrice && $this->checkIsProductInDiscount($productId, $discount)) {
$price -= $this->calc($price, $discount);
$price = $price < $minimalProductPrice ? $minimalProductPrice : $price;
$price = max($price, $minimalProductPrice);
}

return round($price, 2, PHP_ROUND_HALF_UP);
Expand Down Expand Up @@ -1036,7 +1041,7 @@ private function createConditionGroupsToAttach(array $conditions): array
{
$result = [];
foreach ($conditions as $condition) {
array_push($result, $this->createConditionGroup($condition));
$result[] = $this->createConditionGroup($condition);
}
return Collection::make($result)->pluck('id')->all();
}
Expand Down Expand Up @@ -1293,16 +1298,24 @@ private function applyDiscountsOnProductsLazy(Collection $products, Collection $
'sets',
'sets.discounts',
'sets.parent',
])
->lazyById(100);
])->lazyById(100);

if ($products->count() > 0) {
$lazyProducts = $lazyProducts
->filter(fn ($product) => $products->contains($product->getKey()));
$lazyProducts = $lazyProducts->filter(
fn ($product) => $products->contains($product->getKey()),
);
}

foreach ($lazyProducts as $product) {
$this->applyAllDiscountsOnProduct($product, $salesWithBlockList);
$this->applyAllDiscountsOnProduct($product, $salesWithBlockList, false);
}

if ($products->count() > 0) {
// @phpstan-ignore-next-line
Product::query()->whereIn('id', $products->pluck('id'))->searchable();
} else {
// @phpstan-ignore-next-line
Product::query()->searchable();
}
}
}
2 changes: 1 addition & 1 deletion app/Services/ProductService.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private function setup(Product $product, ProductCreateDto|ProductUpdateDto $dto)
$product->price_min_initial = $priceMin;
$product->price_max_initial = $priceMax;
$product->available = $this->availabilityService->isProductAvailable($product);
$this->discountService->applyDiscountsOnProduct($product);
$this->discountService->applyDiscountsOnProduct($product, false);

return $product;
}
Expand Down
10 changes: 4 additions & 6 deletions app/Services/ProductSetService.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,13 @@ public function flattenSetsTree(Collection $sets, string $relation): Collection
*/
public function flattenParentsSetsTree(Collection $sets): Collection
{
$subsets = Collection::make();
$parents = $sets->map(fn ($set) => $set->parent)->filter(fn ($set) => $set !== null);

foreach ($sets as $set) {
if ($set->parent) {
$subsets = $subsets->merge($this->flattenParentsSetsTree(Collection::make([$set->parent])));
}
if ($parents->count() === 0) {
return $sets;
}

return $subsets->flatten()->concat($sets->toArray());
return $sets->merge($this->flattenParentsSetsTree($parents));
}

public function reorderProducts(ProductSet $set, ProductsReorderDto $dto): void
Expand Down
12 changes: 12 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ services:
- app
- mysql_service
- redis
schedule:
build:
context: ./docker
dockerfile: Dockerfile-dev
restart: unless-stopped
volumes:
- .:/usr/src/app
command: php artisan schedule:work
depends_on:
- app
- mysql_service
- redis
mysql_service:
image: mariadb:10.5
restart: unless-stopped
Expand Down
63 changes: 14 additions & 49 deletions tests/Feature/ProductSearchDatabaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -984,16 +984,11 @@ public function testSearchByAttributeNotId($user): void
)
->assertOk()
->assertJsonCount(1, 'data')
->assertJsonFragment([
'name' => $attribute->name,
])
->assertJsonMissing([
'id' => $options[0]->getKey(),
'name' => $options[0]->name,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $options[1]->getKey(),
'name' => $options[1]->name,
'id' => $products[1]->getKey(),
]);
}

Expand Down Expand Up @@ -1049,16 +1044,11 @@ public function testSearchByAttributeNotNumber($user): void
)
->assertOk()
->assertJsonCount(1, 'data')
->assertJsonFragment([
'name' => $attribute->name,
])
->assertJsonMissing([
'id' => $option1->getKey(),
'value_number' => $option1->value_number,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $option2->getKey(),
'value_number' => $option2->value_number,
'id' => $products[1]->getKey(),
]);

$this
Expand Down Expand Up @@ -1093,15 +1083,10 @@ public function testSearchByAttributeNotNumber($user): void
->assertOk()
->assertJsonCount(2, 'data')
->assertJsonFragment([
'name' => $attribute->name,
])
->assertJsonFragment([
'id' => $option1->getKey(),
'value_number' => $option1->value_number,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $option2->getKey(),
'value_number' => $option2->value_number,
'id' => $products[1]->getKey(),
]);

$this
Expand All @@ -1120,15 +1105,10 @@ public function testSearchByAttributeNotNumber($user): void
->assertOk()
->assertJsonCount(2, 'data')
->assertJsonFragment([
'name' => $attribute->name,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $option1->getKey(),
'value_number' => $option1->value_number,
])
->assertJsonFragment([
'id' => $option2->getKey(),
'value_number' => $option2->value_number,
'id' => $products[1]->getKey(),
]);
}

Expand Down Expand Up @@ -1184,16 +1164,11 @@ public function testSearchByAttributeNotDate($user): void
)
->assertOk()
->assertJsonCount(1, 'data')
->assertJsonFragment([
'name' => $attribute->name,
])
->assertJsonMissing([
'id' => $option1->getKey(),
'value_date' => $option1->value_date,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $option2->getKey(),
'value_date' => $option2->value_date,
'id' => $products[1]->getKey(),
]);

$this
Expand Down Expand Up @@ -1229,15 +1204,10 @@ public function testSearchByAttributeNotDate($user): void
->assertOk()
->assertJsonCount(2, 'data')
->assertJsonFragment([
'name' => $attribute->name,
])
->assertJsonFragment([
'id' => $option1->getKey(),
'value_date' => $option1->value_date,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $option2->getKey(),
'value_date' => $option2->value_date,
'id' => $products[1]->getKey(),
]);

$this
Expand All @@ -1256,15 +1226,10 @@ public function testSearchByAttributeNotDate($user): void
->assertOk()
->assertJsonCount(2, 'data')
->assertJsonFragment([
'name' => $attribute->name,
])
->assertJsonFragment([
'id' => $option1->getKey(),
'value_date' => $option1->value_date,
'id' => $products[0]->getKey(),
])
->assertJsonFragment([
'id' => $option2->getKey(),
'value_date' => $option2->value_date,
'id' => $products[1]->getKey(),
]);
}

Expand Down

0 comments on commit 343134b

Please sign in to comment.