корзина кеш
This commit is contained in:
@@ -211,6 +211,145 @@ final class ProductRepository extends BaseRepository
|
||||
return $statement->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $items
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function cartSnapshots(array $items): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$key = (string) ($item['key'] ?? '');
|
||||
$productId = (int) ($item['productId'] ?? 0);
|
||||
$variantId = (int) ($item['variantId'] ?? 0);
|
||||
$desiredPackageQuantity = (float) ($item['packageQuantity'] ?? 0);
|
||||
|
||||
if ($key === '' || $productId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$variantJoin = $variantId > 0
|
||||
? 'v.product_id = p.id AND v.id = :variant_id'
|
||||
: 'v.id = (
|
||||
SELECT pv.id
|
||||
FROM product_variants pv
|
||||
WHERE pv.product_id = p.id
|
||||
ORDER BY pv.is_default DESC, pv.sort_order, pv.id
|
||||
LIMIT 1
|
||||
)';
|
||||
|
||||
$statement = $this->pdo()->prepare(
|
||||
'SELECT
|
||||
p.id AS product_id,
|
||||
p.name,
|
||||
p.slug,
|
||||
p.main_image_path,
|
||||
p.is_published AS product_is_published,
|
||||
p.is_available AS product_is_available,
|
||||
v.id AS variant_id,
|
||||
v.name AS variant_name,
|
||||
v.unit,
|
||||
v.package_quantity,
|
||||
v.price_per_unit,
|
||||
v.package_price,
|
||||
v.is_published AS variant_is_published,
|
||||
v.is_available AS variant_is_available
|
||||
FROM products p
|
||||
LEFT JOIN product_variants v ON ' . $variantJoin . '
|
||||
WHERE p.id = :product_id
|
||||
LIMIT 1'
|
||||
);
|
||||
$params = ['product_id' => $productId];
|
||||
if ($variantId > 0) {
|
||||
$params['variant_id'] = $variantId;
|
||||
}
|
||||
$statement->execute($params);
|
||||
$row = $statement->fetch();
|
||||
|
||||
if (!$row) {
|
||||
$result[] = [
|
||||
'key' => $key,
|
||||
'isAvailable' => false,
|
||||
'reason' => 'Товар больше не найден в каталоге.',
|
||||
];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($row['variant_id'])) {
|
||||
$fallbackStatement = $this->pdo()->prepare(
|
||||
'SELECT
|
||||
p.id AS product_id,
|
||||
p.name,
|
||||
p.slug,
|
||||
p.main_image_path,
|
||||
p.is_published AS product_is_published,
|
||||
p.is_available AS product_is_available,
|
||||
v.id AS variant_id,
|
||||
v.name AS variant_name,
|
||||
v.unit,
|
||||
v.package_quantity,
|
||||
v.price_per_unit,
|
||||
v.package_price,
|
||||
v.is_published AS variant_is_published,
|
||||
v.is_available AS variant_is_available
|
||||
FROM products p
|
||||
INNER JOIN product_variants v ON v.product_id = p.id
|
||||
WHERE p.id = :product_id
|
||||
ORDER BY
|
||||
(v.is_published = 1 AND v.is_available = 1 AND v.package_price > 0) DESC,
|
||||
CASE WHEN :package_quantity_check > 0 THEN ABS(v.package_quantity - :package_quantity) ELSE 0 END,
|
||||
v.is_default DESC,
|
||||
v.sort_order,
|
||||
v.id
|
||||
LIMIT 1'
|
||||
);
|
||||
$fallbackStatement->execute([
|
||||
'product_id' => $productId,
|
||||
'package_quantity' => $desiredPackageQuantity,
|
||||
'package_quantity_check' => $desiredPackageQuantity,
|
||||
]);
|
||||
$fallbackRow = $fallbackStatement->fetch();
|
||||
|
||||
if ($fallbackRow) {
|
||||
$row = $fallbackRow;
|
||||
}
|
||||
}
|
||||
|
||||
$productIsAvailable = (int) ($row['product_is_published'] ?? 0) === 1
|
||||
&& (int) ($row['product_is_available'] ?? 0) === 1;
|
||||
$variantIsAvailable = !empty($row['variant_id'])
|
||||
&& (int) ($row['variant_is_published'] ?? 0) === 1
|
||||
&& (int) ($row['variant_is_available'] ?? 0) === 1
|
||||
&& (float) ($row['package_price'] ?? 0) > 0;
|
||||
|
||||
$reason = '';
|
||||
if (!$productIsAvailable) {
|
||||
$reason = 'Товар сейчас не опубликован или отсутствует в наличии.';
|
||||
} elseif (!$variantIsAvailable) {
|
||||
$reason = 'Выбранная фасовка сейчас недоступна.';
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'key' => $key,
|
||||
'productId' => (int) $row['product_id'],
|
||||
'variantId' => !empty($row['variant_id']) ? (int) $row['variant_id'] : $variantId,
|
||||
'name' => (string) ($row['name'] ?? ''),
|
||||
'slug' => (string) ($row['slug'] ?? ''),
|
||||
'image' => (string) ($row['main_image_path'] ?? ''),
|
||||
'variantName' => (string) ($row['variant_name'] ?? 'Фасовка'),
|
||||
'unit' => (string) ($row['unit'] ?? ''),
|
||||
'packageQuantity' => (float) ($row['package_quantity'] ?? 0),
|
||||
'baseUnitPrice' => (float) ($row['price_per_unit'] ?? 0),
|
||||
'basePackagePrice' => (float) ($row['package_price'] ?? 0),
|
||||
'isAvailable' => $productIsAvailable && $variantIsAvailable,
|
||||
'reason' => $reason,
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user