Skip to content

Instantly share code, notes, and snippets.

@kalbac
Last active February 2, 2025 21:51
Show Gist options
  • Select an option

  • Save kalbac/0def0cd93d70b12681273f084055233a to your computer and use it in GitHub Desktop.

Select an option

Save kalbac/0def0cd93d70b12681273f084055233a to your computer and use it in GitHub Desktop.
Пример изменения формирования грузо-мест в заказе для расчёта стоимости Яндекс доставки
<?php
/**
* Фильтр для изменения параметров расчета стоимости доставки через Яндекс.Доставку.
*
* Функция обрабатывает содержимое корзины и изменяет параметры расчета доставки
* в зависимости от характеристик товаров. Особое внимание уделяется товарам типа
* "бобинная пряжа", для которых рассчитываются специальные габариты.
*
* @param array $places Грузовые места в заказе для расчета стоимости доставки.
* @param array $package Информация о содержимом корзины (товары, их количество и т.д.).
*
* @return array Возвращает измененные параметры расчета доставки.
*
* @since 1.0.0
*
* @see wc_yandex_delivery_get_product_dimensions_weight() Для получения габаритов и веса товара.
*
* Логика работы:
* 1. Проверяет, есть ли товары в корзине.
* 2. Для каждого товара:
* - Проверяет, требуется ли для товара доставка.
* - Получает габариты и вес товара.
* - Если товар является "бобинной пряжей" (габариты 1x1x1 см и количество >= 100 гр):
* - Рассчитывает габариты для доставки: высота всегда 18 см, ширина и длина зависят от веса.
* - Если вес превышает 500 гр, товар разделяется на несколько мест.
* - Для остальных товаров создает отдельные места с оригинальными габаритами.
* 3. Использует кэширование для избежания повторных расчетов для одинаковых товаров.
* 4. Возвращает измененные параметры расчета доставки.
*
* Пример использования:
* - Товар: "Бобинная пряжа", 1000 гр:
* - Создаст два места: 500 гр, 12x18x12 см и 500 гр, 12x18x12 см.
* - Товар: "Обычный товар", 3 шт:
* - Создаст три места с оригинальными габаритами.
*/
add_filter( 'wc_yandex_delivery_order_places', function( array $places, array $package ) {
if ( ! empty( $package['contents'] ) ) {
$cache = []; // Кэш для хранения результатов расчетов
$places = [];
foreach ( $package['contents'] as $values ) {
$product = $values['data'];
if( $product->needs_shipping() ) {
$dimensions = wc_yandex_delivery_get_product_dimensions_weight( $product );
$quantity = max( 1, ceil( $values['quantity'] ) );
// Генерация уникального ключа для кэширования
$cache_key = md5( serialize( [ $dimensions, $quantity ] ) );
// Если результат уже есть в кэше, используем его
if( isset( $cache[ $cache_key ] ) ) {
$places = array_merge( $places, $cache[ $cache_key ] );
continue;
}
// Проверка на "бобинную пряжу"
if ( $quantity >= 100 && $dimensions['width'] == 1 && $dimensions['height'] == 1 && $dimensions['length'] == 1 ) {
$max_weight_per_place = 500; // Максимальный вес на одно место (в граммах)
$remaining_weight = $dimensions['weight'] * $quantity; // Общий вес товара
while( $remaining_weight > 0 ) {
$weight = min( $remaining_weight, $max_weight_per_place ); // Вес текущего места
$count = ceil( $weight / 100 ); // Количество сотен грамм
$height = 18;
$width = $length = 8 + ($count - 1) * 2;
// Добавление места для "бобинной пряжи"
$places[] = [
'weight' => $weight,
'width' => $width,
'height' => $height,
'length' => $length
];
$remaining_weight -= $weight; // Уменьшение оставшегося веса
}
} else {
// Добавление мест для остальных товаров
for ($i = 0; $i < $quantity; $i++) {
$places[] = $dimensions;
}
}
// Сохранение результатов в кэш
$cache[ $cache_key ] = $places;
}
}
}
return $places;
}, 10, 2 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment