Last active
February 2, 2025 21:51
-
-
Save kalbac/0def0cd93d70b12681273f084055233a to your computer and use it in GitHub Desktop.
Пример изменения формирования грузо-мест в заказе для расчёта стоимости Яндекс доставки
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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