У заказчика облачный битрикс24 тариф "Профессиональный" Аналитику можно смотреть, когда не более 100тыс. контактов, что было превышено. Сначала вручную удалены были старые лиды. Задача: удалить контакты с типом НЕ "дилер", у которых нет лидов с источником "бесплатная версия" или сделки |
Завела в битрикс24 в контактах 3 свойства типа да/нет
- есть лиды
- есть сделки
- есть лиды или сделки
function CleanContacts() - на самом деле метод спец класса, для работы с битрикс24
self::CONTACT_PROPS["ххх"] - это просто код поля в битрикс типа "UF_CRM_yyy"
self::CONTACT_TYPES["dealer"] - тип клиента - тоже срока например "UC_FZVJ48"
static::SendRequest - описана там же
принцип такой обходим контакты, для каждого ищем лид или сделку
- если находим, то проставляем, поле, что есть, чтобы при следующей итерации не учитывать
- если не находим, то удаляем
Но айдишники удаленных контактов на всякий случаю логирую в файл.
За одну итерацию обходит максимум 50*50 = 2500 контактов. Занимает примерно 500 секунд.
Если у вас время исполнения крипта меньшее 500. можно поставить $max не 50, меньше (хоть 1). Тогда будет обходить по 50 контактов за 1 запуск агента.
Агент запустила раз в 900 секунд. За 9 часов должен обойти 100тыс контактов.
В следующий раз. чтобы чистить, надо будет новые поля завести, чтобы в данных их не было
- есть лиды
- есть сделки
- есть лиды или сделки
function CleanContacts(){ $i = 0; $max = 50;//1-50 while($i>=0){ //для простого выхода //получаем список контактов max запросов по 50 штук $arContactsDeletedAllIds = []; $arContactsNotDeletedIds = []; $arContactsNotDeleted = []; $batch = []; for ($j=0; $j < $max; $j++) { $batch[] = 'crm.contact.list?'.http_build_query([ "order" => ["ID" => "ASC"], "select" => ["ID"], "filter" => [ "!TYPE_ID"=>self::CONTACT_TYPES["dealer"],//не дилеров self::CONTACT_PROPS["hasDealsOrLeads"] => false, //исключаем тех, кого уже проверили и поставили, что у них ЕСТЬ лиды или сделки ], "start" => $i*50 ]); $i++; } $arData = [ "halt" => 0, "cmd" => $batch ]; $result = static::SendRequest("batch.json", $arData); $total = $result["result"]["result_total"][0]??0; if($total == 0){ $i = -1; break; } sleep(1); //для каждого получаем 1 лид и 1 сделку, где он клиент, 1 сделку, где он в свойстве конечник (при заказе через дилера) for ($j=0; $j < $max; $j++) { if(is_array($result["result"]["result"][$j])){ for ($l=0; $l < 4; $l++) { // для 50 контактов мне надо сделать по 3 проверки $arContactsIds = []; $arContactsDeletedIds = []; $batch2 = []; for ($k = 16*$l; $k < (16+16*$l); $k++) { //у меня 3 проверки, поэтому floor(50/3) = 16. $contactId = $result["result"]["result"][$j][$k]["ID"] ?? false; if (!empty($contactId)) { $arContactsIds[] = $contactId; $batch2["lead" . $contactId] = 'crm.lead.list?' . http_build_query([ "select" => ["ID"], "filter" => ["CONTACT_ID" => $contactId], "limit" => 1 ]); $batch2["deal" . $contactId] = 'crm.deal.list?' . http_build_query([ "select" => ["ID"], "filter" => ["CONTACT_ID" => $contactId], "limit" => 1 ]); $batch2["dealDealer" . $contactId] = 'crm.deal.list?' . http_build_query([ "select" => ["ID"], "filter" => [self::DEAL_PROPS["client"] => $contactId], "limit" => 1 ]); } } if(!empty($batch2)) { $arData = [ "halt" => 0, "cmd" => $batch2 ]; $result2 = static::SendRequest("batch.json", $arData); sleep(1); foreach ($arContactsIds as $contactId) { if ( empty($result2["result"]["result"]["lead" . $contactId]) && empty($result2["result"]["result"]["deal" . $contactId]) && empty($result2["result"]["result"]["dealDealer" . $contactId]) ) { $arContactsDeletedIds[] = $contactId; $arContactsDeletedAllIds[] = $contactId; } else { $arContactsNotDeleted[] = [ 'id' => $contactId, 'hasDeals' => (!empty($result2["result"]["result"]["deal" . $contactId])||!empty($result2["result"]["result"]["dealDealer" . $contactId])), 'hasLeads' => (!empty($result2["result"]["result"]["lead" . $contactId])) ]; $arContactsNotDeletedIds[] = $contactId; } } } } } } if(!empty($arContactsDeletedAllIds)){ $file = fopen($_SERVER["DOCUMENT_ROOT"] . "/b24deletelog.txt", 'a+'); fputs($file, implode(", ",$arContactsDeletedAllIds) . "\r\n"); } // echo "удаленные<br>"; // echo implode(", ",$arContactsDeletedAllIds); // echo "<br>"; // echo "НЕудаленные<br>"; // echo implode(", ",$arContactsNotDeletedIds); // echo "<br>"; if(!empty($arContactsDeletedAllIds)) { $arContactsDeletedAllIds = array_chunk($arContactsDeletedAllIds, 50); foreach ($arContactsDeletedAllIds as $arContactsDeletedIds) { $batch2 = []; //удаляем контакт в битрикс24, айдишник автоматом чистится foreach ($arContactsDeletedIds as $contactId) { $batch2[] = 'crm.contact.delete?' . http_build_query([ 'id' => $contactId ]); } if (!empty($batch2)) { $arData = [ "halt" => 0, "cmd" => $batch2 ]; $result2 = static::SendRequest("batch.json", $arData); sleep(1); } } } if(!empty($arContactsNotDeleted)){ $arContactsNotDeleted = array_chunk($arContactsNotDeleted, 50); foreach ($arContactsNotDeleted as $arContactsNotDeletedTemp) { $batch2 = []; //$batchTemp = []; foreach ($arContactsNotDeletedTemp as $arContactFields) { $batch2[] = 'crm.contact.update?' . http_build_query([ 'id' => $arContactFields["id"], 'fields' => [ self::CONTACT_PROPS['hasLeads'] => $arContactFields['hasLeads'], self::CONTACT_PROPS['hasDeals'] => $arContactFields['hasDeals'], self::CONTACT_PROPS['hasDealsOrLeads'] => true ], 'params' => [ 'REGISTER_SONET_EVENT' => 'N' ] ]); } $arData = [ "halt" => 0, "cmd" => $batch2 ]; $result2 = static::SendRequest("batch.json", $arData); sleep(1); } } break; } return ($i>=0)?"nikaverro\dev\bitrix24\Bitrix24::CleanContacts();":""; } |