Оглавление / Бизнес-процессы / Библиотека бизнес-процессов

    Технические особенности настройки бизнес-процесса «Автоматическая ротация продвижения объектов в рамках выкупленного пакета»

    Пример бизнес-процесса по данной схеме размене в Библиотеке с названием "Автоматическая ротация продвижения объектов в рамках выкупленного пакета"

    Если объект находится с продвижением больше 2х и у него указана ротация, то его место продвижения ТОП3 может быть передано другому объекту с ротацией, который на данный момент не продвигается. Приоритет дается объектам, которые были дольше всех без продвижения (высший у тех объектов, которые никогда не продвигались). Алгоритм учитывает:

    • Общее количество доступных мест (выкупленный пакет продвижения).

    • Объекты, которые не нужно снимать с продвижения (объекты с указанным продвижением без ротации).

    Пример. Если у нас max_package (пакет) выкуплен на 5 объявлений, но 3 из них занимаю объекты с продвижением без ротации, то для ротации остается только 2 места. Алгоритм учитывает то, что фактически освобождено сейчас или через заданное время может быть не более 2х мест.

    /// V1.1 ///
    $max_duration = '2'; // Максимальная длительность нахождения объекта с подвижениям в днях
    $max_package = '5'; // Выкупленный пакет размещения (макс количество одновременных топов)
    $type_promotion = 'Топ 3[top3]'; /// Тип продвижения
     
    //// Ключевые поля /////
    $object_type_id = '1'; /// ID тип объекта
    $id_field_rotation = '2174'; /// ID поля с отметкой Ротации продвижения - Поле с типом "Да/Нет"
    $id_field_promotion = '1346'; /// ID поля с указаием продвижения
    $id_field_date_promotion = '2175'; /// ID поля с датой последнего продвижения , тип поля Дата+Время
     
    /* begin Данные для доступа по API */
    $domen = 'domen';
    $apikey = 'XXXXXXXXXXXXXXXXXXXXXXX';
    /* end Данные для доступа по API */
     
    $now = time();
     
    /* begin Функции */
    //// Функция делает ключем одно из значений вложенного массива
    //// применяется для использования ID поля как ключа массива
    function fetchByField(array $array,$field_key)
    {
    $formatted = array();
    foreach($array as $item){
    $key = $item[$field_key];
    $formatted[$key] = $item;
    }
     
    return $formatted;
    }
     
    /// Функция сортировки массива от Большего к Меньшему по длительности продвижения
    function cmp($a, $b) {
    return $b['duration'] - $a['duration'];
    }
    function cmps($a, $b) {
    return $a['duration'] - $b['duration'];
    }
    /* end Функции */
     
     
    $all_dataset_rotation = array(); /// Массив всех объектов с меткой ротации
    $all_dataset_promotion = array(); /// Массив всех объектов с меткой ротации
    $all_count_promotion = 0; /// У скольки объектов всего отмечено продвижение (значение переписывается ниже)
    $all_count_rotation = 0; /// У скольки объектов всего отмечена ротация (значение переписывается ниже)
     
     
    $url="http://$domen.intrumnet.com:81/sharedapi/stock/filter";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     
    /// ШАГ 1
    //// Получить список квартир с установленным продвижением ////
    $count_stock = '1'; /// Стартовое значение счетчика
    $limit_stock = '500';
     
    for ($x = 1; $x <= $count_stock; $x++) {
    $params=array(
    'type' => $object_type_id,
    'fields' => array(
    array('id'=>$id_field_promotion,'value'=>$type_promotion)
    ),
    'limit' => $limit_stock,
    'count_total' => '1'
    );
     
    $post = array(
    'apikey' =>"$apikey",
    'params'=>$params
    );
     
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    $result = json_decode(curl_exec($ch),true);
    $list = $result['data']['list'];
     
    foreach ($list as $value) {
    $all_dataset_promotion[] = $value;
    }
     
    $all_count_promotion = $result['data']['count'];
    $count_stock = ceil($result['data']['count'] / $limit_stock);
    /* удаление мусора */
    unset($result);
    unset($list);
    ////////////////////
    }
     
    curl_close ($ch);
     
    /* ххх 1.1 ОПИСАНИ С ДОП ИНФОРМАЦИЙ ххх
    На этом этапе у нас есть
    $all_count_promotion - общее количество объектов с продвижением
    $all_dataset_promotion - массив со всеми объектами у которых установлено продвижение
    ------------------------- */
     
    $overdue_object = array(); /// Перечень просроченных объектов (с которых можно снять топ)
     
    foreach ($all_dataset_promotion as $value) {
    $id_object = $value['id']; /// ID проверяемого объекта
    $fields = $value['fields']; /// список полей проверяемого объекта
    $fields = fetchByField($fields,'id'); /// Сделать ID поля ключем.
    if(isset($fields[$id_field_date_promotion]) !== false){
    /// Проверка просроченности даты в поле у объекта
    $date = strtotime($fields[$id_field_date_promotion]['value']);
    $diff_day = round(($now - $date)/86400);
    if($diff_day > $max_duration && $fields[$id_field_rotation]['value'] == '1'){
    $overdue_object[] = [
    'id' => $id_object,
    'duration' => $diff_day,
    'rotation' => $fields[$id_field_rotation]['value']
    ];
    }
    }
    }
     
    usort($overdue_object, 'cmp'); /// Сортировать объекты для снятия по длительности продвижения
     
    /* ххх 1.2 ОПИСАНИ С ДОП ИНФОРМАЦИЙ ххх
    На этом этапе у нас есть
    $all_count_promotion - общее количество объектов с продвижением
    $all_dataset_promotion - массив со всеми объектами у которых установлено продвижение
    $overdue_object - перечень просроченных объектов с которых уже можно снимать топ. от нсиболее старых с новым
    $max_package - Выкупленный пакет размещения (макс количество одновременных топов)
    ------------------------- */
     
    /* Посчитать количество возможных свободных слотов пакета */
    $count_overdue_object = count($overdue_object);
    $free_package = $max_package - $all_count_promotion + $count_overdue_object;
     
    /// ШАГ 2 --- нужен только при наличии свободных слотов или возможности освободить
    if($free_package > 0){
    $expects_object = array();
    $count_stock = '1'; /// Стартовое значение счетчика
    $limit_stock = '500';
     
    //// Получить список квартир с отмеченной ротацией продвижения ////
    $url="http://$domen.intrumnet.com:81/sharedapi/stock/filter";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     
    for ($x = 1; $x <= $count_stock; $x++) {
    $params=array(
    'type' => $object_type_id,
    'fields' => array(
    array('id'=>$id_field_rotation,'value'=>"1")
    ),
    'limit' => $limit_stock,
    'count_total' => '1'
    );
     
    $post = array(
    'apikey' =>"$apikey",
    'params'=>$params
    );
     
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    $result = json_decode(curl_exec($ch),true);
    $list = $result['data']['list'];
     
    foreach ($list as $value) {
    $all_dataset_rotation[] = $value;
    }
     
    $all_count_rotation = $result['data']['count'];
    $count_stock = ceil($result['data']['count'] / $limit_stock);
    /* удаление мусора */
    unset($result);
    unset($list);
    ////////////////////
    }
     
    curl_close ($ch);
     
    /* ххх 2.1 ОПИСАНИ С ДОП ИНФОРМАЦИЙ ххх
    На этом этапе у нас есть
    $all_count_promotion - общее количество объектов с продвижением
    $all_dataset_promotion - массив со всеми объектами у которых установлено продвижение
    $overdue_object - перечень просроченных объектов с которых уже можно снимать топ. от нсиболее старых с новым
    $max_package - Выкупленный пакет размещения (макс количество одновременных топов)
     
    $free_package - количество доступных слотов продвижения
    $all_dataset_rotation - массив со всеми объектами с ротацией
    $all_count_rotation - общее количество объектов с ротацией
    ------------------------- */
     
    foreach ($all_dataset_rotation as $value) {
    $id_object = $value['id']; /// ID проверяемого объекта
    $fields = $value['fields']; /// список полей проверяемого объекта
    $fields = fetchByField($fields,'id'); /// Сделать ID поля ключем.
     
    /// Проверка просроченности даты в поле у объекта
    if(isset($fields[$id_field_date_promotion]['value'])!== false){
    $date = strtotime($fields[$id_field_date_promotion]['value']);
    $diff_day = round(($now - $date)/86400);
    }
    if(isset($fields[$id_field_date_promotion]['value'])=== false){
    $diff_day = '-1';
    }
     
    /// Проверка записанного типа продвижения
    if(isset($fields[$id_field_promotion]) === false){
    $proverka_prodvijenya = 'нет';
    }
    if(isset($fields[$id_field_promotion])){
    $proverka_prodvijenya = $fields[$id_field_promotion]['value'];
    }
     
    if($proverka_prodvijenya != $type_promotion){
    $expects_object[] = [
    'id' => $id_object,
    'duration' => $diff_day,
    'rotation' => $fields[$id_field_rotation]['value']
    ];
    }
    }
     
    usort($expects_object, 'cmps'); /// Сортировать объекты для снятия по длительности продвижения
     
    /* ххх 2.2 ОПИСАНИ С ДОП ИНФОРМАЦИЙ ххх
    На этом этапе у нас есть
    $all_count_promotion - общее количество объектов с продвижением
    $all_dataset_promotion - массив со всеми объектами у которых установлено продвижение
    $overdue_object - перечень просроченных объектов с которых уже можно снимать топ. от нсиболее старых с новым
    $max_package - Выкупленный пакет размещения (макс количество одновременных топов)
     
    $free_package - количество доступных слотов продвижения
    $all_dataset_rotation - массив со всеми объектами с ротацией
    $all_count_rotation - общее количество объектов с ротацией
     
    $expects_object - список объектов, которые ожидают продвижения
    ------------------------- */
     
    /* Если число уже продвигаемых объектов + Число объектов ожидающих продвижение больше максимального пакета,
    то нужня снять продвижение у объектов из перечня overdue_object так, чтобы в max_package поместилось максимальное число объектов из expects_object,
    но не больше чем того требует общее число expects_object */
     
    if(count($expects_object)> 0){
    $array_places = array(); /// для подсчета доступных и требуемых мест
    $params_expects_object = array();
    $params_overdue_object = array();
    $need_package = $max_package - $all_count_promotion - count($expects_object);
     
    /// Выкупленный пакет имеет запас или подходит впритык
    //// Ничего не удаляем, добавляем выгрузку ко всем объектам из expects_object
    if($need_package >= 0 ){
    $array_places = [
    'need' => '0',
    'free' => $need_package
    ];
     
    foreach ($expects_object as $value) {
    $id_object = $value['id'];
    $params_expects_object[] = [
    'id' => $id_object,
    'fields' => [
    ['id' => $id_field_promotion,'value' => $type_promotion],
    ['id' => $id_field_date_promotion,'value' => date("Y-m-d H:i:s",time())]
    ]
    ];
    }
     
    //// Проставить продвижение
    if(count($params_expects_object)>0)
    $url="http://$domen.intrumnet.com:81/sharedapi/stock/update";
    $params=$params_expects_object;
    $post = array(
    'apikey' =>"$apikey",
    'params'=>$params
    );
     
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = json_decode(curl_exec($ch));
    curl_close ($ch);
    /// print_r($result);
    //////
     
    }
    ///////////////////////////////////////////////////////////////////////////
     
    /// Выкупленного пакета недостаточно на все
    if($need_package < 0){
    $array_places = [
    'need' => abs($need_package),
    'free' => $free_package
    ];
     
    $need_count = $array_places['need'];
    $start_num_del = '0';
     
    foreach ($overdue_object as $value) {
    $id_object = $value['id'];
    $params_overdue_object[] = [
    'id' => $id_object,
    'fields' => [
    ['id' => $id_field_promotion,'value' => '']
    ]
    ];
    $start_num_del++;
    if($start_num_del >= $need_count){
    break 1;
    }
    }
     
    //// убрать продвижение для освобождения мест
    if(count($params_overdue_object) > 0){
    $url="http://$domen.intrumnet.com:81/sharedapi/stock/update";
    $params=$params_overdue_object;
    $post = array(
    'apikey' =>"$apikey",
    'params'=>$params
    );
     
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = json_decode(curl_exec($ch));
    curl_close ($ch);
    /// print_r($result);
    }
    //////
     
    $start_num_expects = '0';
    foreach ($expects_object as $value) {
    $id_object = $value['id'];
    $params_expects_object[] = [
    'id' => $id_object,
    'fields' => [
    ['id' => $id_field_promotion,'value' => $type_promotion],
    ['id' => $id_field_date_promotion,'value' => date("Y-m-d H:i:s",time())]
    ]
    ];
    $start_num_expects++;
    if($start_num_expects >= $free_package){
    break 1;
    }
    }
     
    //// Проставить продвижение
    if(count($params_expects_object)>0){
    $url="http://$domen.intrumnet.com:81/sharedapi/stock/update";
    $params=$params_expects_object;
    $post = array(
    'apikey' =>"$apikey",
    'params'=>$params
    );
     
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = json_decode(curl_exec($ch));
    curl_close ($ch);
    /// print_r($result);
    //////
    }
    }
     
    }
    return true;
    }
     
    return false;
     

    Возможно вам также будет интересно: Календарь общих событий (брони, дежурства)

    Вернуться к оглавлению


    Система реализуется как облачное решение SaaS, т. е. размещается на наших серверных мощностях. CRM гибко настраивается персонально под ваш бизнес. При использовании сервиса у вас будет аккаунт-менеджер для консультации и помощи в настройках