From e7705a4fa17b758577a8790468790d2ff76e20e3 Mon Sep 17 00:00:00 2001 From: Arsen Mirzaev Tatyano-Muradovich Date: Wed, 21 Jun 2023 07:38:58 +0700 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D1=82=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BC=D0=B0=D0=B3?= =?UTF-8?q?=D0=B0=D0=B7=D0=B8=D0=BD=D0=BE=D0=B2=20=D0=B8=20=D1=81=D0=BE?= =?UTF-8?q?=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2,=20?= =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=B2=20=D0=B7=D0=B0=D0=B4=D0=B0?= =?UTF-8?q?=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../parser/system/public/.gitignore | 2 - .../parser/system/public/markets.php | 80 ++++++-- .../parser/system/public/workers.php | 173 ++++++++++++++---- .../parser/system/public/works.php | 13 +- 4 files changed, 217 insertions(+), 51 deletions(-) delete mode 100644 mirzaev/spetsresurs/google_sheets/parser/system/public/.gitignore diff --git a/mirzaev/spetsresurs/google_sheets/parser/system/public/.gitignore b/mirzaev/spetsresurs/google_sheets/parser/system/public/.gitignore deleted file mode 100644 index fee99d8..0000000 --- a/mirzaev/spetsresurs/google_sheets/parser/system/public/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -storage/* -!storage diff --git a/mirzaev/spetsresurs/google_sheets/parser/system/public/markets.php b/mirzaev/spetsresurs/google_sheets/parser/system/public/markets.php index d1b496c..ba3cf8f 100644 --- a/mirzaev/spetsresurs/google_sheets/parser/system/public/markets.php +++ b/mirzaev/spetsresurs/google_sheets/parser/system/public/markets.php @@ -36,7 +36,7 @@ function generateLabel(string $name): string 'type', 'ТИП', 'Тип', 'тип' => 'type', 'director', 'ДИРЕКТОР', 'Директор', 'директор' => 'director', 'address', 'АДРЕС', 'Адрес', 'адрес' => 'address', - default => throw new exception("Неизвестный столбец: $name") + default => $name }; } @@ -47,7 +47,7 @@ function degenerateLabel(string $name): string 'ТИП', 'type' => 'ТИП', 'ДИРЕКТОР', 'director' => 'ДИРЕКТОР', 'АДРЕС', 'address' => 'АДРЕС', - default => throw new exception("Неизвестный столбец: $name") + default => $name }; } @@ -65,16 +65,74 @@ function sync(Row &$row, string $city = 'Красноярск'): void { global $arangodb; - $_row = init($row->entries()->toArray()['row']); + // Инициализация строки в Google Sheet + $_row = init($row->toArray()['row']); - if ($_row['id'] !== null) - if (collection::init($arangodb->session, 'markets')) - if ($market = collection::search($arangodb->session, sprintf("FOR d IN markets FILTER d.id == '%s' RETURN d", $_row['id']))) - if ($_row === $new = array_diff_key($market->getAll(), ['_key' => true, 'created' => true, 'city' => true])); - else $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row')); - else if (collection::search($arangodb->session, sprintf("FOR d IN markets FILTER d._id == '%s' RETURN d", document::write($arangodb->session, 'markets', $_row + ['city' => $city])))); - else throw new exception('Не удалось создать или найти созданного магазина'); - else throw new exception('Не удалось инициализировать коллекцию'); + if (collection::init($arangodb->session, 'markets')) + if (!empty($_row['id']) && $market = collection::search($arangodb->session, sprintf("FOR d IN markets FILTER d.id == '%s' RETURN d", $_row['id']))) { + // Найдена запись магазина (строки) в базе данных и включен режим перезаписи (приоритет - google sheets) + + if ($market->transfer_to_sheets) { + // Запрошен форсированный перенос данных из базы данных в таблицу + + // Инициализация данных для записи в таблицу + $new = [ + 'id' => $market->id ?? '', + 'type' => $market->type ?? '', + 'director' => $market->director ?? '', + 'address' => $market->address ?? '', + ]; + + // Замена NULL на пустую строку + foreach ($new as $key => &$value) if ($value === null) $value = ''; + + // Реинициализация строки с новыми данными по ссылке (приоритет из базы данных) + if ($_row !== $new) $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row')); + + // Деактивация форсированного трансфера + $market->transfer_to_sheets = false; + } else { + // Перенос изменений из Google Sheet в инстанцию документа в базе данных + + // Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet + foreach ($market->getAll() as $key => $value) { + // Перебор всех записанных значений в инстанции документа в базе данных + + // Конвертация + $market->{$key} = $_row[$key] ?? $value; + } + } + + // Обновление инстанции документа в базе данных + document::update($arangodb->session, $market); + } else if ( + !empty($_row['id']) + && $market = collection::search( + $arangodb->session, + sprintf( + "FOR d IN markets FILTER d._id == '%s' RETURN d", + document::write($arangodb->session, 'markets', [ + 'id' => $_row['id'] ?? '', + 'type' => $_row['type'] ?? '', + 'director' => $_row['director'] ?? '', + 'address' => $_row['address'] ?? '', + 'city' => $city, + 'transfer_to_sheets' => false + ]) + ) + ) + ) { + // Не найдена запись магазина (строки) в базе данных и была создана + + /* // Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets) + $row = $row->set((new Flow())->read(From::array([init([ + 'id' => $_row['id'] ?? '', + 'type' => $_row['type'] ?? '', + 'director' => $_row['director'] ?? '', + 'address' => $_row['address'] ?? '', + ], true)]))->fetch(1)[0]->get('row')); */ + } else return; + else throw new exception('Не удалось инициализировать коллекцию'); } $settings = json_decode(require(__DIR__ . '/../settings/markets/google.php'), true); diff --git a/mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php b/mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php index 751833e..89b1d3a 100644 --- a/mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php +++ b/mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php @@ -32,23 +32,23 @@ $arangodb = new connection(require __DIR__ . '/../settings/arangodb.php'); function generateLabel(string $name): string { return match ($name) { - 'id', 'ID', '1', '11', '111', '1111', '11111', 'index', 'Index', 'код', 'Код', 'ключ', 'Ключ', 'айди', 'Айди', 'идентификатор', 'Идентификатор' => 'id', - 'name', 'ФИО', 'фио', 'ф.и.о.', 'ф. и. о.', 'Ф.И.О.', 'Ф. И. О.' => 'name', - 'phone', 'Номер', 'номер', 'телефон', 'Телефон' => 'phone', - 'birth', 'Дата рождения', 'дата рождения', 'Год рождения', 'год рождения', 'Год', 'год', 'День рождения', 'день рождения' => 'birth', - 'address', 'Адрес регистрации', 'адрес регистрации', 'Адрес', 'адрес', 'Регистрация', 'регистрация' => 'address', - 'commentary', 'Комментарий', 'ПРИМЕЧАНИЕ', 'Примечание', 'примечание' => 'commentary', - 'activity', 'Работа', 'работа', 'Вид Работы', 'Вид работы', 'вид работы' => 'activity', - 'passport', 'Паспорт', 'паспорт', 'серия и номер паспорта', 'Серия и номер паспорта' => 'passport', - 'issued', 'Выдан', 'выдан' => 'issued', - 'department', 'Код подразделения', 'код подразделения', 'Подразделение', 'подразделение' => 'department', - 'hiring', 'Дата присоединения', 'Когда устроили', 'когда устроили' => 'hiring', + 'id', 'ID' => 'id', + 'name', 'ФИО' => 'name', + 'phone', 'Номер' => 'phone', + 'birth', 'Дата рождения' => 'birth', + 'address', 'Регистрация' => 'address', + 'commentary', 'Комментарий' => 'commentary', + 'activity', 'Работа' => 'activity', + 'passport', 'Паспорт' => 'passport', + 'issued', 'Выдан' => 'issued', + 'department', 'Подразделение' => 'department', + 'hiring', 'Нанят' => 'hiring', 'district', 'Район', 'район' => 'district', 'requisites', 'Реквизиты', 'реквизиты' => 'requisites', - 'fired', 'Дата увольнения', 'дата увольнения', 'Уволен', 'уволен', 'Увольнение', 'увольнение' => 'fired', + 'fired', 'Уволен' => 'fired', 'payment', 'Оплата', 'оплата' => 'payment', 'tax', 'ИНН', 'инн' => 'tax', - default => throw new exception("Неизвестный столбец: $name") + default => $name }; } @@ -59,22 +59,34 @@ function degenerateLabel(string $name): string 'ФИО', 'name' => 'ФИО', 'Номер', 'phone' => 'Номер', 'Дата рождения', 'birth' => 'Дата рождения', - 'Адрес регистрации', 'address' => 'Адрес регистрации', + 'Регистрация', 'address' => 'Регистрация', 'Комментарий', 'commentary' => 'Комментарий', 'Работа', 'activity' => 'Работа', 'Паспорт', 'passport' => 'Паспорт', 'Выдан', 'issued' => 'Выдан', - 'Код подразделения', 'department' => 'Код подразделения', - 'Дата присоединения', 'hiring' => 'Дата присоединения', + 'Подразделение', 'department' => 'Подразделение', + 'Нанят', 'hiring' => 'Нанят', 'Район', 'district' => 'Район', 'Реквизиты', 'requisites' => 'Реквизиты', - 'Дата увольнения', 'fired' => 'Дата увольнения', + 'Уволен', 'fired' => 'Дата увольнения', 'Оплата', 'payment' => 'Оплата', 'ИНН', 'tax' => 'ИНН', - default => throw new exception("Неизвестный столбец: $name") + default => $name }; } +function convertNumber(string $number): string +{ + + // Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки) + preg_match('/^8(\d{10})/', preg_replace("/[^\d]/", "", $number), $matches); + + // Инициализация номера + $number = isset($matches[1]) ? 7 . $matches[1] : $number; + + return $number; +} + function init(array $row, bool $reverse = false): array { $buffer = []; @@ -140,23 +152,120 @@ function sync(Row &$row, string $city = 'Красноярск'): void { global $arangodb; - $_row = init($row->entries()->toArray()['row']); + // Инициализация строки в Google Sheet + $_row = init($row->toArray()['row']); - if ($_row['id'] !== null) - if (collection::init($arangodb->session, 'workers')) - if ($worker = collection::search($arangodb->session, sprintf("FOR d IN workers FILTER d.id == '%s' RETURN d", $_row['id'])) - ?? collection::search($arangodb->session, sprintf("FOR d IN workers FILTER d._id == '%s' RETURN d", document::write($arangodb->session, 'workers', $_row + ['city' => $city]))) - ) { - // Инициализирован работник + if (collection::init($arangodb->session, 'workers')) + if (!empty($_row['id']) && $worker = collection::search($arangodb->session, sprintf("FOR d IN workers FILTER d.id == '%s' RETURN d", $_row['id']))) { + // Найдена запись работника (строки) в базе данных и включен режим перезаписи (приоритет - google sheets) - // Реинициализация строки с актуальными записями (приоритет у базы данных) - if ($_row !== $new = array_diff_key($worker->getAll(), ['_key' => true, 'created' => true, 'city' => true])) - $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row')); + if ($worker->transfer_to_sheets) { + // Запрошен форсированный перенос данных из базы данных в таблицу - // Подключение к чат-роботам - connectAll($worker); - } else throw new exception('Не удалось создать или найти созданного работника'); - else throw new exception('Не удалось инициализировать коллекцию'); + // Инициализация данных для записи в таблицу + $new = [ + 'id' => $worker->id ?? '', + 'name' => $worker->name ?? '', + 'phone' => convertNumber($worker->phone ?? ''), + 'birth' => $worker->birth ?? '', + 'address' => $worker->address ?? '', + 'commentary' => $worker->commentary ?? '', + 'activity' => $worker->activity ?? '', + 'passport' => $worker->passport ?? '', + 'issued' => $worker->issued ?? '', + 'department' => $worker->department ?? '', + 'hiring' => $worker->hiring ?? '', + 'district' => $worker->district ?? '', + 'requisites' => $worker->requisites ?? '', + 'fired' => $worker->fired ?? '', + 'payment' => $worker->payment ?? '', + 'tax' => $worker->tax ?? '', + ]; + + // Замена NULL на пустую строку + foreach ($new as $key => &$value) if ($value === null) $value = ''; + + // Реинициализация строки с новыми данными по ссылке (приоритет из базы данных) + if ($_row !== $new) $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row')); + + // Деактивация форсированного трансфера + $worker->transfer_to_sheets = false; + } else { + // Перенос изменений из Google Sheet в инстанцию документа в базе данных + + // Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet + foreach ($worker->getAll() as $key => $value) { + // Перебор всех записанных значений в инстанции документа в базе данных + + // Конвертация + $worker->{$key} = $_row[$key] ?? $value; + } + } + + // Обновление инстанции документа в базе данных + document::update($arangodb->session, $worker); + + // Подключение к чат-роботам + connectAll($worker); + } else if ( + !empty($_row['id']) + && !empty($_row['phone']) + && $worker = collection::search( + $arangodb->session, + sprintf( + "FOR d IN workers FILTER d._id == '%s' RETURN d", + document::write($arangodb->session, 'workers', [ + 'id' => $_row['id'] ?? '', + 'name' => $_row['name'] ?? '', + 'phone' => convertNumber($_row['phone'] ?? ''), + 'birth' => $_row['birth'] ?? '', + 'address' => $_row['address'] ?? '', + 'commentary' => $_row['commentary'] ?? '', + 'activity' => $_row['activity'] ?? '', + 'passport' => $_row['passport'] ?? '', + 'issued' => $_row['issued'] ?? '', + 'department' => $_row['department'] ?? '', + 'hiring' => $_row['hiring'] ?? '', + 'district' => $_row['district'] ?? '', + 'requisites' => $_row['requisites'] ?? '', + 'fired' => $_row['fired'] ?? '', + 'payment' => $_row['payment'] ?? '', + 'tax' => $_row['tax'] ?? '', + 'city' => $city, + 'transfer_to_sheets' => false + ]) + ) + ) + ) { + // Не найдена запись работника (строки) в базе данных и была создана + + // Инициализация номера + $number = convertNumber($_row['phone'] ?? ''); + + // Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets) + $row = $row->set((new Flow())->read(From::array([init([ + 'id' => $_row['id'] ?? '', + 'name' => $_row['name'] ?? '', + 'phone' => "=HYPERLINK(\"https://call.ctrlq.org/+$number\"; \"$number\")", + 'birth' => $_row['birth'] ?? '', + 'address' => $_row['address'] ?? '', + 'commentary' => $_row['commentary'] ?? '', + 'activity' => $_row['activity'] ?? '', + 'passport' => $_row['passport'] ?? '', + 'issued' => $_row['issued'] ?? '', + 'department' => $_row['department'] ?? '', + 'hiring' => $_row['hiring'] ?? '', + 'district' => $_row['district'] ?? '', + 'requisites' => $_row['requisites'] ?? '', + 'fired' => $_row['fired'] ?? '', + 'payment' => $_row['payment'] ?? '', + 'tax' => $_row['tax'] ?? '', + ], true)]))->fetch(1)[0]->get('row')); + + // Подключение к чат-роботам + connectAll($worker); + } else return; + else throw new exception('Не удалось инициализировать коллекцию'); } $settings = json_decode(require(__DIR__ . '/../settings/workers/google.php'), true); diff --git a/mirzaev/spetsresurs/google_sheets/parser/system/public/works.php b/mirzaev/spetsresurs/google_sheets/parser/system/public/works.php index 42ea123..8f9ddb8 100644 --- a/mirzaev/spetsresurs/google_sheets/parser/system/public/works.php +++ b/mirzaev/spetsresurs/google_sheets/parser/system/public/works.php @@ -96,14 +96,14 @@ function filterWorker(?string $worker): string global $arangodb; return match ($worker) { - '', 0, 00, 000, 0000, 00000, 000000, 0000000, 00000000, 000000000, 0000000000 => '', + '', 'Отмена', 'отмена', 0, 00, 000, 0000, 00000, 000000, 0000000, 00000000, 000000000, 0000000000 => '', default => (function () use ($worker, $arangodb) { if ( collection::init($arangodb->session, 'workers') && collection::search( $arangodb->session, sprintf( - "FOR d IN workers FILTER d.id == d RETURN d", + "FOR d IN workers FILTER d.id == %s RETURN d", $worker ) ) @@ -127,16 +127,17 @@ function sync(int $_i, Row &$row, ?array $raw = null): void { global $arangodb; + // Инициализация строки в Google Sheet $_row = init($row->toArray()['row']); if (collection::init($arangodb->session, 'works')) if (!empty($_row['_id']) && $work = collection::search($arangodb->session, sprintf("FOR d IN works FILTER d._id == '%s' RETURN d", $_row['_id']))) { - // Найдена запись работы (строки) в базе данных и включен режим перезаписи (приоритет - google sheets) + // Найдена запись работы (строки) в базе данных if ($work->transfer_to_sheets) { // Запрошен форсированный перенос данных из базы данных в таблицу - // Очистка перед записью в таблицу + // Инициализация данных для записи в таблицу $new = [ 'imported_created_in_sheets' => $work->imported_created_in_sheets['converted'], 'imported_date' => $work->imported_date['converted'], @@ -164,7 +165,7 @@ function sync(int $_i, Row &$row, ?array $raw = null): void '_id' => $work->getId(), ]; - // Инициализация выбранного сотрудника + // Инициализация сотрудника if (collection::init($arangodb->session, 'readinesses', true) && collection::init($arangodb->session, 'workers')) $new['worker'] = collection::search( $arangodb->session, @@ -366,7 +367,7 @@ function sync(int $_i, Row &$row, ?array $raw = null): void // Запись идентификатора только что созданной инстанции документа в базе данных $_row['_id'] = $work->getId(); - // Реинициализация строки с новыми данными по ссылке (приоритет из базы данных) + // Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets) $row = $row->set((new Flow())->read(From::array([init([ 'imported_created_in_sheets' => $raw[0] ?? '', 'imported_date' => $raw[1] ?? '',