Оглавление / Бизнес-процессы / Библиотека бизнес-процессов
Технические особенности настройки бизнес-процесса «Автоматическая ротация продвижения объектов в рамках выкупленного пакета»
Пример бизнес-процесса по данной схеме размене в Библиотеке с названием "Автоматическая ротация продвижения объектов в рамках выкупленного пакета"
Если объект находится с продвижением больше 2х и у него указана ротация, то его место продвижения ТОП3 может быть передано другому объекту с ротацией, который на данный момент не продвигается. Приоритет дается объектам, которые были дольше всех без продвижения (высший у тех объектов, которые никогда не продвигались). Алгоритм учитывает:
-
Общее количество доступных мест (выкупленный пакет продвижения).
-
Объекты, которые не нужно снимать с продвижения (объекты с указанным продвижением без ротации).
Пример. Если у нас max_package (пакет) выкуплен на 5 объявлений, но 3 из них занимаю объекты с продвижением без ротации, то для ротации остается только 2 места. Алгоритм учитывает то, что фактически освобождено сейчас или через заданное время может быть не более 2х мест.
$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;
Вернуться к оглавлению