Compare commits
8 Commits
based_on_I
...
document_t
Author | SHA1 | Date | |
---|---|---|---|
Arsen Mirzaev Tatyano-Muradovich | d6506b0f2d | ||
Arsen Mirzaev Tatyano-Muradovich | 2732ee1c3a | ||
Arsen Mirzaev Tatyano-Muradovich | 88709765d9 | ||
Arsen Mirzaev Tatyano-Muradovich | af33a20c81 | ||
Arsen Mirzaev Tatyano-Muradovich | c5facf13b0 | ||
Arsen Mirzaev Tatyano-Muradovich | f3bd5872f5 | ||
Arsen Mirzaev Tatyano-Muradovich | 4e88505833 | ||
Arsen Mirzaev Tatyano-Muradovich | 0306f882c0 |
|
@ -1,5 +1,7 @@
|
||||||
# Google Sheets parser
|
# Google Sheets parser
|
||||||
|
|
||||||
Synchronizes Google Sheets with ArangoDB
|
Synchronizes Google Sheets with ArangoDB for [mirzaev/ebala](https://git.mirzaev.sexy/mirzaev/ebala)</br>
|
||||||
|
|
||||||
~~😼 Developed in 1 day for 100000 rubles ($1200)~~ shit happens
|
</br>
|
||||||
|
~~😼 Developed in 1 day for 100000 rubles ($1200)~~ shit happens</br>
|
||||||
|
**DEVELOPMENT COMPLETED. PROJECT CLOSED.**
|
|
@ -32,10 +32,11 @@ $arangodb = new connection(require __DIR__ . '/../settings/arangodb.php');
|
||||||
function generateLabel(string $name): string
|
function generateLabel(string $name): string
|
||||||
{
|
{
|
||||||
return match ($name) {
|
return match ($name) {
|
||||||
'id', 'ID', 'ТТ' => 'id',
|
'id', 'ID', 'ТТ', '№ТТ' => 'id',
|
||||||
'type', 'ТИП', 'Тип', 'тип' => 'type',
|
'type', 'ТИП', 'Тип', 'тип', 'ФОРМАТ' => 'type',
|
||||||
'director', 'ДИРЕКТОР', 'Директор', 'директор' => 'director',
|
'name', 'ДИРЕКТОР', 'Директор', 'директор', 'ДИРЕКТОР ТТ' => 'name',
|
||||||
'address', 'АДРЕС', 'Адрес', 'адрес' => 'address',
|
'address', 'АДРЕС', 'Адрес', 'адрес' => 'address',
|
||||||
|
'city', 'город', 'Город', 'Направление' => 'city',
|
||||||
default => $name
|
default => $name
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -45,12 +46,24 @@ function degenerateLabel(string $name): string
|
||||||
return match ($name) {
|
return match ($name) {
|
||||||
'ID', 'id' => 'ID',
|
'ID', 'id' => 'ID',
|
||||||
'ТИП', 'type' => 'ТИП',
|
'ТИП', 'type' => 'ТИП',
|
||||||
'ДИРЕКТОР', 'director' => 'ДИРЕКТОР',
|
'ДИРЕКТОР', 'name' => 'ДИРЕКТОР',
|
||||||
'АДРЕС', 'address' => 'АДРЕС',
|
'АДРЕС', 'address' => 'АДРЕС',
|
||||||
|
'city' => 'ГОРОД',
|
||||||
default => $name
|
default => $name
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertNumber(string $number): string
|
||||||
|
{
|
||||||
|
// Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки)
|
||||||
|
preg_match('/\d?(\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
|
function init(array $row, bool $reverse = false): array
|
||||||
{
|
{
|
||||||
$buffer = [];
|
$buffer = [];
|
||||||
|
@ -61,21 +74,27 @@ function init(array $row, bool $reverse = false): array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sync(Row &$row, string $city = 'Красноярск'): void
|
function sync(Row &$row): void
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
// Инициализация строки в Google Sheet
|
// Инициализация строки в Google Sheet
|
||||||
$_row = init($row->toArray()['row']);
|
$_row = init($row->toArray()['row']);
|
||||||
|
|
||||||
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']))) {
|
$name = explode(' ', $_row['name']);
|
||||||
|
|
||||||
|
// Инициализация идентификатора
|
||||||
|
if (empty($id = preg_replace('/([^^\d]?)(\d+).*/u', 'K$2', $_row['id']))) return;
|
||||||
|
|
||||||
|
if (collection::init($arangodb->session, 'market'))
|
||||||
|
if ($market = collection::search($arangodb->session, sprintf("FOR d IN market FILTER d.id == '%s' RETURN d", $id))) {
|
||||||
// Найдена запись магазина (строки) в базе данных и включен режим перезаписи (приоритет - google sheets)
|
// Найдена запись магазина (строки) в базе данных и включен режим перезаписи (приоритет - google sheets)
|
||||||
|
|
||||||
if ($market->transfer_to_sheets) {
|
if (false && $market->transfer_to_sheets) {
|
||||||
// Запрошен форсированный перенос данных из базы данных в таблицу
|
// Запрошен форсированный перенос данных из базы данных в таблицу
|
||||||
|
|
||||||
// Инициализация данных для записи в таблицу
|
/* // Инициализация данных для записи в таблицу
|
||||||
$new = [
|
$new = [
|
||||||
'id' => $market->id ?? '',
|
'id' => $market->id ?? '',
|
||||||
'type' => $market->type ?? '',
|
'type' => $market->type ?? '',
|
||||||
|
@ -90,39 +109,62 @@ function sync(Row &$row, string $city = 'Красноярск'): void
|
||||||
if ($_row !== $new) $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row'));
|
if ($_row !== $new) $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row'));
|
||||||
|
|
||||||
// Деактивация форсированного трансфера
|
// Деактивация форсированного трансфера
|
||||||
$market->transfer_to_sheets = false;
|
$market->transfer_to_sheets = false; */
|
||||||
} else {
|
} else {
|
||||||
// Перенос изменений из Google Sheet в инстанцию документа в базе данных
|
// Перенос изменений из Google Sheet в инстанцию документа в базе данных
|
||||||
|
|
||||||
// Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet
|
/* // Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet
|
||||||
foreach ($market->getAll() as $key => $value) {
|
foreach ($market->getAll() as $key => $value) {
|
||||||
// Перебор всех записанных значений в инстанции документа в базе данных
|
// Перебор всех записанных значений в инстанции документа в базе данных
|
||||||
|
|
||||||
// Конвертация
|
// Конвертация
|
||||||
$market->{$key} = $_row[$key] ?? $value;
|
$market->{$key} = $_row[$key] ?? $value;
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновление инстанции документа в базе данных
|
/* // Обновление инстанции документа в базе данных
|
||||||
document::update($arangodb->session, $market);
|
document::update($arangodb->session, $market); */
|
||||||
} else if (
|
} else if (
|
||||||
$market = collection::search(
|
$market = collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN markets FILTER d._id == '%s' RETURN d",
|
"FOR d IN market FILTER d._id == '%s' RETURN d",
|
||||||
document::write($arangodb->session, 'markets', [
|
document::write($arangodb->session, 'market', [
|
||||||
'id' => $_row['id'] ?? '',
|
'id' => $id,
|
||||||
'type' => $_row['type'] ?? '',
|
'type' => $_row['type'] ?? '',
|
||||||
'director' => $_row['director'] ?? '',
|
'name' => [
|
||||||
|
'first' => $name[1] ?? $_row['name'] ?? '',
|
||||||
|
'second' => $name[0] ?? '',
|
||||||
|
'last' => $name[2] ?? ''
|
||||||
|
],
|
||||||
'address' => $_row['address'] ?? '',
|
'address' => $_row['address'] ?? '',
|
||||||
'city' => $city,
|
'city' => $_row['city'] ?? '',
|
||||||
'transfer_to_sheets' => false
|
'active' => true
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// Не найдена запись магазина (строки) в базе данных и была создана
|
// Не найдена запись магазина (строки) в базе данных и была создана
|
||||||
|
|
||||||
|
// Создание аккаунта
|
||||||
|
$account = document::write($arangodb->session, 'account', [
|
||||||
|
'type' => 'market',
|
||||||
|
'name' => [
|
||||||
|
'first' => $name[1] ?? $_row['name'] ?? '',
|
||||||
|
'second' => $name[0] ?? '',
|
||||||
|
'last' => $name[2] ?? ''
|
||||||
|
],
|
||||||
|
'number' => convertNumber($_row['number'] ?? ''),
|
||||||
|
'active' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Подключение сотрудника к аккаунту. Создание ребра: account -> market
|
||||||
|
document::write(
|
||||||
|
$arangodb->session,
|
||||||
|
'account_edge_market',
|
||||||
|
['_from' => $account, '_to' => $market->getId()]
|
||||||
|
);
|
||||||
|
|
||||||
/* // Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
/* // Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
||||||
$row = $row->set((new Flow())->read(From::array([init([
|
$row = $row->set((new Flow())->read(From::array([init([
|
||||||
'id' => $_row['id'] ?? '',
|
'id' => $_row['id'] ?? '',
|
||||||
|
@ -144,15 +186,15 @@ $client->setAuthConfig($settings);
|
||||||
$api = new Sheets($client);
|
$api = new Sheets($client);
|
||||||
|
|
||||||
foreach ($sheets as $sheet) {
|
foreach ($sheets as $sheet) {
|
||||||
$rows = (new Flow())->read(new GoogleSheetExtractor($api, $document, new Columns($sheet, 'A', 'D'), true, 1000, 'row'));
|
$rows = (new Flow())->read(new GoogleSheetExtractor($api, $document, new Columns($sheet, 'B', 'F'), true, 1000, 'row'));
|
||||||
|
|
||||||
$i = 1;
|
$i = 1;
|
||||||
foreach ($rows->fetch(3000) as $row) {
|
foreach ($rows->fetch(5000) as $row) {
|
||||||
++$i;
|
if (++$i === 2) continue;
|
||||||
$buffer = $row;
|
$buffer = $row;
|
||||||
sync($row, $sheet);
|
sync($row);
|
||||||
if ($buffer !== $row) {
|
if ($buffer !== $row) {
|
||||||
$api->spreadsheets_values->update(
|
/* $api->spreadsheets_values->update(
|
||||||
$document,
|
$document,
|
||||||
"$sheet!A$i:D$i",
|
"$sheet!A$i:D$i",
|
||||||
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
||||||
|
@ -160,7 +202,7 @@ foreach ($sheets as $sheet) {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
||||||
sleep(3);
|
sleep(3); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
208
mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php
Normal file → Executable file
208
mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php
Normal file → Executable file
|
@ -9,10 +9,15 @@ use mirzaev\arangodb\connection,
|
||||||
use ArangoDBClient\Document as _document;
|
use ArangoDBClient\Document as _document;
|
||||||
|
|
||||||
// Фреймворк для Google Sheets
|
// Фреймворк для Google Sheets
|
||||||
use Flow\ETL\Adapter\GoogleSheet\GoogleSheetExtractor,
|
use Flow\ETL\Adapter\GoogleSheet\GoogleSheetRange,
|
||||||
|
Flow\ETL\Adapter\GoogleSheet\GoogleSheetExtractor,
|
||||||
Flow\ETL\Adapter\GoogleSheet\Columns,
|
Flow\ETL\Adapter\GoogleSheet\Columns,
|
||||||
Flow\ETL\Flow,
|
Flow\ETL\Flow,
|
||||||
|
Flow\ETL\Config,
|
||||||
|
Flow\ETL\FlowContext,
|
||||||
|
Flow\ETL\Row\Entry,
|
||||||
Flow\ETL\Row,
|
Flow\ETL\Row,
|
||||||
|
Flow\ETL\DSL\To,
|
||||||
Flow\ETL\DSL\From;
|
Flow\ETL\DSL\From;
|
||||||
|
|
||||||
// Фреймворк для Google API
|
// Фреймворк для Google API
|
||||||
|
@ -29,14 +34,14 @@ function generateLabel(string $name): string
|
||||||
return match ($name) {
|
return match ($name) {
|
||||||
'id', 'ID' => 'id',
|
'id', 'ID' => 'id',
|
||||||
'name', 'ФИО' => 'name',
|
'name', 'ФИО' => 'name',
|
||||||
'phone', 'Номер' => 'phone',
|
'number', 'Номер' => 'number',
|
||||||
'birth', 'Дата рождения' => 'birth',
|
'birth', 'Дата рождения' => 'birth',
|
||||||
'address', 'Регистрация' => 'address',
|
'address', 'Регистрация' => 'address',
|
||||||
'commentary', 'Комментарий' => 'commentary',
|
'commentary', 'Комментарий', 'примечание к звонкам' => 'commentary',
|
||||||
'activity', 'Работа' => 'activity',
|
'activity', 'Работа' => 'activity',
|
||||||
'passport', 'Паспорт' => 'passport',
|
'passport', 'Паспорт' => 'passport',
|
||||||
'issued', 'Выдан' => 'issued',
|
'issued', 'Выдан' => 'issued',
|
||||||
'department', 'Подразделение' => 'department',
|
'department', 'Подразделение', 'Код подразделения' => 'department',
|
||||||
'hiring', 'Нанят' => 'hiring',
|
'hiring', 'Нанят' => 'hiring',
|
||||||
'district', 'Район', 'район' => 'district',
|
'district', 'Район', 'район' => 'district',
|
||||||
'requisites', 'Реквизиты', 'реквизиты' => 'requisites',
|
'requisites', 'Реквизиты', 'реквизиты' => 'requisites',
|
||||||
|
@ -52,14 +57,14 @@ function degenerateLabel(string $name): string
|
||||||
return match ($name) {
|
return match ($name) {
|
||||||
'ID', 'id' => 'ID',
|
'ID', 'id' => 'ID',
|
||||||
'ФИО', 'name' => 'ФИО',
|
'ФИО', 'name' => 'ФИО',
|
||||||
'Номер', 'phone' => 'Номер',
|
'Номер', 'number' => 'Номер',
|
||||||
'Дата рождения', 'birth' => 'Дата рождения',
|
'Дата рождения', 'birth' => 'Дата рождения',
|
||||||
'Регистрация', 'address' => 'Регистрация',
|
'Регистрация', 'address' => 'Регистрация',
|
||||||
'Комментарий', 'commentary' => 'Комментарий',
|
'Комментарий', 'примечание к звонкам', 'commentary' => 'Комментарий',
|
||||||
'Работа', 'activity' => 'Работа',
|
'Работа', 'activity' => 'Работа',
|
||||||
'Паспорт', 'passport' => 'Паспорт',
|
'Паспорт', 'passport' => 'Паспорт',
|
||||||
'Выдан', 'issued' => 'Выдан',
|
'Выдан', 'issued' => 'Выдан',
|
||||||
'Подразделение', 'department' => 'Подразделение',
|
'Подразделение', 'Код подразделения', 'department' => 'Подразделение',
|
||||||
'Нанят', 'hiring' => 'Нанят',
|
'Нанят', 'hiring' => 'Нанят',
|
||||||
'Район', 'district' => 'Район',
|
'Район', 'district' => 'Район',
|
||||||
'Реквизиты', 'requisites' => 'Реквизиты',
|
'Реквизиты', 'requisites' => 'Реквизиты',
|
||||||
|
@ -72,9 +77,8 @@ function degenerateLabel(string $name): string
|
||||||
|
|
||||||
function convertNumber(string $number): string
|
function convertNumber(string $number): string
|
||||||
{
|
{
|
||||||
|
|
||||||
// Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки)
|
// Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки)
|
||||||
preg_match('/^8(\d{10})/', preg_replace("/[^\d]/", "", $number), $matches);
|
preg_match('/\d?(\d{10})/', preg_replace("/[^\d]/", "", $number), $matches);
|
||||||
|
|
||||||
// Инициализация номера
|
// Инициализация номера
|
||||||
$number = isset($matches[1]) ? 7 . $matches[1] : $number;
|
$number = isset($matches[1]) ? 7 . $matches[1] : $number;
|
||||||
|
@ -117,7 +121,7 @@ function connect(_document $worker, _document $robot): void
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
// Инициализировано ребро: workers -> robot (любой)
|
// Инициализировано ребро: worker -> robot (любой)
|
||||||
|
|
||||||
// Активация
|
// Активация
|
||||||
$robot->status = 'active';
|
$robot->status = 'active';
|
||||||
|
@ -129,39 +133,65 @@ function connectAll(_document $worker): void
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
// Инициализация ребра: workers -> viber
|
// Инициализация ребра: worker -> viber
|
||||||
if (
|
if (
|
||||||
collection::init($arangodb->session, 'viber')
|
collection::init($arangodb->session, 'viber')
|
||||||
&& $viber = collection::search(
|
&& $viber = collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN viber FILTER d.number == '%d' RETURN d",
|
"FOR d IN viber FILTER d.number == '%d' RETURN d",
|
||||||
$worker->phone
|
$worker->number
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) connect($worker, $viber);
|
||||||
|
|
||||||
|
// Инициализация ребра: worker -> telegram
|
||||||
|
if (
|
||||||
|
collection::init($arangodb->session, 'telegram')
|
||||||
|
&& $viber = collection::search(
|
||||||
|
$arangodb->session,
|
||||||
|
sprintf(
|
||||||
|
"FOR d IN telegram FILTER d.number == '%d' RETURN d",
|
||||||
|
$worker->number
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) connect($worker, $viber);
|
) connect($worker, $viber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sync(Row &$row, string $city = 'Красноярск', array $formulas = []): void
|
function id()
|
||||||
|
{
|
||||||
|
global $arangodb;
|
||||||
|
|
||||||
|
return collection::search(
|
||||||
|
$arangodb->session,
|
||||||
|
"RETURN MAX((FOR d in worker RETURN +d.id))",
|
||||||
|
) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function sync(Row &$row, string $city = 'Красноярск'): void
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
// Инициализация строки в Google Sheet
|
// Инициализация строки в Google Sheet
|
||||||
$_row = init($row->toArray()['row']);
|
$_row = init($row->toArray()['row']);
|
||||||
|
|
||||||
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']))) {
|
$name = explode(' ', $_row['name']);
|
||||||
|
|
||||||
|
if (collection::init($arangodb->session, 'worker'))
|
||||||
|
if (!empty($_row['id']) && $worker = collection::search($arangodb->session, sprintf("FOR d IN worker FILTER d.id == '%s' RETURN d", $_row['id']))) {
|
||||||
// Найдена запись работника (строки) в базе данных и включен режим перезаписи (приоритет - google sheets)
|
// Найдена запись работника (строки) в базе данных и включен режим перезаписи (приоритет - google sheets)
|
||||||
|
|
||||||
if ($worker->transfer_to_sheets) {
|
if (false && $worker->transfer_to_sheets) {
|
||||||
// Запрошен форсированный перенос данных из базы данных в таблицу
|
// Запрошен форсированный перенос данных из базы данных в таблицу
|
||||||
|
|
||||||
// Инициализация данных для записи в таблицу
|
// Инициализация данных для записи в таблицу
|
||||||
$new = [
|
/* $new = [
|
||||||
'id' => $worker->id ?? '',
|
'id' => $worker->id ?? id(),
|
||||||
'name' => $worker->name ?? '',
|
'name' => $worker->name ?? '',
|
||||||
'phone' => convertNumber($worker->phone ?? ''),
|
'number' => convertNumber($worker->number ?? ''),
|
||||||
'birth' => $worker->birth ?? '',
|
'birth' => $worker->birth ?? '',
|
||||||
'address' => $worker->address ?? '',
|
'address' => $worker->address ?? '',
|
||||||
'commentary' => $worker->commentary ?? '',
|
'commentary' => $worker->commentary ?? '',
|
||||||
|
@ -175,100 +205,100 @@ function sync(Row &$row, string $city = 'Красноярск', array $formulas
|
||||||
'fired' => $worker->fired ?? '',
|
'fired' => $worker->fired ?? '',
|
||||||
'payment' => $worker->payment ?? '',
|
'payment' => $worker->payment ?? '',
|
||||||
'tax' => $worker->tax ?? '',
|
'tax' => $worker->tax ?? '',
|
||||||
];
|
]; */
|
||||||
|
|
||||||
// Замена NULL на пустую строку
|
// Замена NULL на пустую строку
|
||||||
foreach ($new as $key => &$value) if ($value === null) $value = '';
|
/* 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'));
|
/* if ($_row !== $new) $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row')); */
|
||||||
|
|
||||||
// Деактивация форсированного трансфера
|
// Деактивация форсированного трансфера
|
||||||
$worker->transfer_to_sheets = false;
|
/* $worker->transfer_to_sheets = false; */
|
||||||
} else {
|
} else {
|
||||||
// Перенос изменений из Google Sheet в инстанцию документа в базе данных
|
// Перенос изменений из Google Sheet в инстанцию документа в базе данных
|
||||||
|
|
||||||
// Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet
|
// Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet
|
||||||
foreach ($worker->getAll() as $key => $value) {
|
/* foreach ($worker->getAll() as $key => $value) { */
|
||||||
// Перебор всех записанных значений в инстанции документа в базе данных
|
// Перебор всех записанных значений в инстанции документа в базе данных
|
||||||
|
|
||||||
// Конвертация
|
// Конвертация
|
||||||
$worker->{$key} = $_row[$key] ?? $value;
|
/* $worker->{$key} = $_row[$key] ?? $value; */
|
||||||
}
|
/* } */
|
||||||
|
|
||||||
if (strlen($formulas[2]) < 12) {
|
|
||||||
// Не конвертирован номер
|
|
||||||
|
|
||||||
// Инициализация номера
|
|
||||||
$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'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновление инстанции документа в базе данных
|
// Обновление инстанции документа в базе данных
|
||||||
document::update($arangodb->session, $worker);
|
/* document::update($arangodb->session, $worker); */
|
||||||
|
|
||||||
// Подключение к чат-роботам
|
// Подключение к чат-роботам
|
||||||
connectAll($worker);
|
/* connectAll($worker); */
|
||||||
} else if (
|
} else if (
|
||||||
!empty($_row['id'])
|
/* !empty($_row['id']) */
|
||||||
&& !empty($_row['phone'])
|
/* && !empty($_row['number']) */
|
||||||
&& $worker = collection::search(
|
/* && */
|
||||||
|
$worker = collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN workers FILTER d._id == '%s' RETURN d",
|
"FOR d IN worker FILTER d._id == '%s' RETURN d",
|
||||||
document::write($arangodb->session, 'workers', [
|
document::write($arangodb->session, 'worker', [
|
||||||
'id' => $_row['id'] ?? '',
|
'id' => $_row['id'] ?? id(),
|
||||||
'name' => $_row['name'] ?? '',
|
'name' => [
|
||||||
'phone' => convertNumber($_row['phone'] ?? ''),
|
'first' => $name[1] ?? $_row['name'] ?? '',
|
||||||
|
'second' => $name[0] ?? '',
|
||||||
|
'last' => $name[2] ?? ''
|
||||||
|
],
|
||||||
|
'number' => convertNumber($_row['number'] ?? ''),
|
||||||
'birth' => $_row['birth'] ?? '',
|
'birth' => $_row['birth'] ?? '',
|
||||||
'address' => $_row['address'] ?? '',
|
'address' => $_row['address'] ?? '',
|
||||||
'commentary' => $_row['commentary'] ?? '',
|
'commentary' => $_row['commentary'] ?? '',
|
||||||
'activity' => $_row['activity'] ?? '',
|
'activity' => $_row['activity'] ?? '',
|
||||||
'passport' => $_row['passport'] ?? '',
|
'passport' => $_row['passport'] ?? '',
|
||||||
'issued' => $_row['issued'] ?? '',
|
'issued' => '',
|
||||||
'department' => $_row['department'] ?? '',
|
'department' => [
|
||||||
|
'number' => $_row['department'] ?? '',
|
||||||
|
'address' => $_row['issued'] ?? ''
|
||||||
|
],
|
||||||
'hiring' => $_row['hiring'] ?? '',
|
'hiring' => $_row['hiring'] ?? '',
|
||||||
'district' => $_row['district'] ?? '',
|
'district' => $_row['district'] ?? '',
|
||||||
'requisites' => $_row['requisites'] ?? '',
|
'requisites' => $_row['requisites'] ?? '',
|
||||||
'fired' => $_row['fired'] ?? '',
|
'fired' => $_row['fired'] ?? '',
|
||||||
'payment' => $_row['payment'] ?? '',
|
'payment' => $_row['payment'] ?? '',
|
||||||
'tax' => $_row['tax'] ?? '',
|
'tax' => $_row['tax'] ?? '',
|
||||||
'city' => $city,
|
'city' => 'Красноярск' ?? $city,
|
||||||
'transfer_to_sheets' => false
|
'active' => true
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// Не найдена запись работника (строки) в базе данных и была создана
|
// Не найдена запись работника (строки) в базе данных и была создана
|
||||||
|
|
||||||
|
// Создание аккаунта
|
||||||
|
$account = document::write($arangodb->session, 'account', [
|
||||||
|
'type' => 'worker',
|
||||||
|
'name' => [
|
||||||
|
'first' => $name[1] ?? $_row['name'] ?? '',
|
||||||
|
'second' => $name[0] ?? '',
|
||||||
|
'last' => $name[2] ?? ''
|
||||||
|
],
|
||||||
|
'number' => convertNumber($_row['number'] ?? ''),
|
||||||
|
'active' => true
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Подключение сотрудника к аккаунту. Создание ребра: account -> worker
|
||||||
|
document::write(
|
||||||
|
$arangodb->session,
|
||||||
|
'account_edge_worker',
|
||||||
|
['_from' => $account, '_to' => $worker->getId()]
|
||||||
|
);
|
||||||
|
|
||||||
// Инициализация номера
|
// Инициализация номера
|
||||||
$number = convertNumber($_row['phone'] ?? '');
|
/* $number = convertNumber($_row['number'] ?? ''); */
|
||||||
|
|
||||||
// Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
// Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
||||||
$row = $row->set((new Flow())->read(From::array([init([
|
/* $row = $row->set((new Flow())->read(From::array([init([
|
||||||
'id' => $_row['id'] ?? '',
|
'id' => $_row['id'] ?? '',
|
||||||
'name' => $_row['name'] ?? '',
|
'name' => $_row['name'] ?? '',
|
||||||
'phone' => "=HYPERLINK(\"https://call.ctrlq.org/+$number\"; \"$number\")",
|
'number' => "=HYPERLINK(\"https://call.ctrlq.org/+$number\"; \"$number\")",
|
||||||
'birth' => $_row['birth'] ?? '',
|
'birth' => $_row['birth'] ?? '',
|
||||||
'address' => $_row['address'] ?? '',
|
'address' => $_row['address'] ?? '',
|
||||||
'commentary' => $_row['commentary'] ?? '',
|
'commentary' => $_row['commentary'] ?? '',
|
||||||
|
@ -282,10 +312,10 @@ function sync(Row &$row, string $city = 'Красноярск', array $formulas
|
||||||
'fired' => $_row['fired'] ?? '',
|
'fired' => $_row['fired'] ?? '',
|
||||||
'payment' => $_row['payment'] ?? '',
|
'payment' => $_row['payment'] ?? '',
|
||||||
'tax' => $_row['tax'] ?? '',
|
'tax' => $_row['tax'] ?? '',
|
||||||
], true)]))->fetch(1)[0]->get('row'));
|
], true)]))->fetch(1)[0]->get('row')); */
|
||||||
|
|
||||||
// Подключение к чат-роботам
|
// Подключение к чат-роботам
|
||||||
connectAll($worker);
|
/* connectAll($worker); */
|
||||||
} else return;
|
} else return;
|
||||||
else throw new exception('Не удалось инициализировать коллекцию');
|
else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
}
|
}
|
||||||
|
@ -297,46 +327,26 @@ $sheets = require(__DIR__ . '/../settings/workers/sheets.php');
|
||||||
$client = new Client();
|
$client = new Client();
|
||||||
$client->setScopes(Sheets::SPREADSHEETS);
|
$client->setScopes(Sheets::SPREADSHEETS);
|
||||||
$client->setAuthConfig($settings);
|
$client->setAuthConfig($settings);
|
||||||
|
$api = new Sheets($client);
|
||||||
|
|
||||||
foreach ($sheets as $sheet) {
|
foreach ($sheets as $sheet) {
|
||||||
// Перебор таблиц
|
$rows = (new Flow())->read(new GoogleSheetExtractor($api, $document, new Columns($sheet, 'A', 'W'), true, 1000, 'row'));
|
||||||
|
|
||||||
// Инициализация обработчика таблиц
|
|
||||||
$sheets = new Sheets($client);
|
|
||||||
|
|
||||||
// Инициализация инстанции Flow для Google Sheet API
|
|
||||||
$rows = (new Flow())->read(new GoogleSheetExtractor($sheets, $document, new Columns($sheet, 'A', 'P'), true, 1000, 'row'));
|
|
||||||
|
|
||||||
// Инициализация счётчика итераций
|
|
||||||
$i = 1;
|
$i = 1;
|
||||||
|
foreach ($rows->fetch(4183) as $row) {
|
||||||
$formulas = $sheets->spreadsheets_values->get($document, "$sheet!A:P", ['valueRenderOption' => 'FORMULA']) ?? null;
|
|
||||||
|
|
||||||
if ($formulas === null) continue;
|
|
||||||
|
|
||||||
foreach ($rows->fetch(5000) as $row) {
|
|
||||||
// Перебор строк
|
|
||||||
|
|
||||||
// Запись счётчика
|
|
||||||
++$i;
|
++$i;
|
||||||
|
|
||||||
// Инициализация буфера строки
|
|
||||||
$buffer = $row;
|
$buffer = $row;
|
||||||
|
sync($row, $sheet);
|
||||||
// Синхронизация с базой данных
|
|
||||||
sync($row, $sheet, $formulas[$i - 1]);
|
|
||||||
|
|
||||||
// Запись изменений строки в Google Sheet
|
|
||||||
if ($buffer !== $row) {
|
if ($buffer !== $row) {
|
||||||
$sheets->spreadsheets_values->update(
|
/* $api->spreadsheets_values->update(
|
||||||
$document,
|
$document,
|
||||||
"$sheet!A$i:P$i",
|
"$sheet!A$i:P$i",
|
||||||
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
||||||
['valueInputOption' => 'USER_ENTERED']
|
['valueInputOption' => 'USER_ENTERED']
|
||||||
);
|
); */
|
||||||
|
|
||||||
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
||||||
sleep(3);
|
/* sleep(3); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,29 +32,22 @@ $arangodb = new connection(require __DIR__ . '/../settings/arangodb.php');
|
||||||
function generateLabel(string $name): string
|
function generateLabel(string $name): string
|
||||||
{
|
{
|
||||||
return match ($name) {
|
return match ($name) {
|
||||||
'imported_created_in_sheets', 'Отметка времени' => 'imported_created_in_sheets',
|
'created_in_sheets', 'Отметка времени' => 'created_in_sheets',
|
||||||
'imported_date', 'Дата заявки' => 'imported_date',
|
'updated_in_sheets', 'время последнего изменения' => 'updated_in_sheets',
|
||||||
'imported_market', 'Ваш магазин' => 'imported_market',
|
'date', 'дата заявки' => 'date',
|
||||||
'imported_worker', 'Требуемый сотрудник' => 'imported_worker',
|
'market', '№ магазина' => 'market',
|
||||||
'imported_work', 'Вид работы' => 'imported_work',
|
'type', 'формат' => 'type',
|
||||||
'imported_start', 'Начало работы' => 'imported_start',
|
'address', 'адрес' => 'address',
|
||||||
'imported_end', 'Конец работы' => 'imported_end',
|
'worker', 'Код сотрудника (000000)' => 'worker',
|
||||||
'imported_hours', 'Часы работы' => 'imported_hours',
|
|
||||||
'created_in_sheets', 'Создано' => 'created_in_sheets',
|
|
||||||
'date', 'Дата' => 'date',
|
|
||||||
'market', 'Магазин' => 'market',
|
|
||||||
'type', 'Тип' => 'type',
|
|
||||||
'address', 'Адрес' => 'address',
|
|
||||||
'worker', 'Сотрудник' => 'worker',
|
|
||||||
'name', 'ФИО' => 'name',
|
'name', 'ФИО' => 'name',
|
||||||
'work', 'Работа' => 'work',
|
'work', 'Вид работ' => 'work',
|
||||||
'start', 'Начало' => 'start',
|
'start', 'Время начала заявки' => 'start',
|
||||||
'end', 'Конец' => 'end',
|
'end', 'Время окончания заявки' => 'end',
|
||||||
'hours', 'Часы' => 'hours',
|
'hours', 'Количество часов по заявке' => 'hours',
|
||||||
'tax', 'ИНН' => 'tax',
|
'tax', 'ИНН' => 'tax',
|
||||||
'confirmed', 'Подтверждено' => 'confirmed',
|
'confirmed', 'подтверждение' => 'confirmed',
|
||||||
'commentary', 'Комментарий' => 'commentary',
|
'commentary', 'примечание от ТТ' => 'commentary',
|
||||||
'response', 'Ответ' => 'response',
|
'response', 'ответ от контрагента' => 'response',
|
||||||
'_id', 'ID' => '_id',
|
'_id', 'ID' => '_id',
|
||||||
default => $name
|
default => $name
|
||||||
};
|
};
|
||||||
|
@ -63,29 +56,22 @@ function generateLabel(string $name): string
|
||||||
function degenerateLabel(string $name): string
|
function degenerateLabel(string $name): string
|
||||||
{
|
{
|
||||||
return match ($name) {
|
return match ($name) {
|
||||||
'Отметка времени', 'imported_created_in_sheets' => 'Отметка времени',
|
'Отметка времени', 'created_in_sheets' => 'Отметка времени',
|
||||||
'Дата заявки', 'imported_date' => 'Дата заявки',
|
'время последнего изменения', 'updated_in_sheets' => 'время последнего изменения',
|
||||||
'Ваш магазин', 'imported_market' => 'Ваш магазин',
|
'дата заявки', 'date' => 'дата заявки',
|
||||||
'Требуемый сотрудник', 'imported_worker' => 'Требуемый сотрудник',
|
'№ магазина', 'market' => '№ магазина',
|
||||||
'Вид работы', 'imported_work' => 'Вид работы',
|
'формат', 'type' => 'формат',
|
||||||
'Начало работы', 'imported_start' => 'Начало работы',
|
'адрес', 'address' => 'адрес',
|
||||||
'Конец работы', 'imported_end' => 'Конец работы',
|
'Код сотрудника (000000)', 'worker' => 'Код сотрудника (000000)',
|
||||||
'Часы работы', 'imported_hours' => 'Часы работы',
|
|
||||||
'Создано', 'created_in_sheets' => 'Создано',
|
|
||||||
'Дата', 'date' => 'Дата',
|
|
||||||
'Магазин', 'market' => 'Магазин',
|
|
||||||
'Тип', 'type' => 'Тип',
|
|
||||||
'Адрес', 'address' => 'Адрес',
|
|
||||||
'Сотрудник', 'worker' => 'Сотрудник',
|
|
||||||
'ФИО', 'name' => 'ФИО',
|
'ФИО', 'name' => 'ФИО',
|
||||||
'Работа', 'work' => 'Работа',
|
'Вид работ', 'work' => 'Вид работ',
|
||||||
'Начало', 'start' => 'Начало',
|
'Время начала заявки', 'start' => 'Время начала заявки',
|
||||||
'Конец', 'end' => 'Конец',
|
'Время окончания заявки', 'end' => 'Время окончания заявки',
|
||||||
'Часы', 'hours' => 'Часы',
|
'Количество часов по заявке', 'hours' => 'Количество часов по заявке',
|
||||||
'ИНН', 'tax' => 'ИНН',
|
'ИНН', 'tax' => 'ИНН',
|
||||||
'Подтверждено', 'confirmed' => 'Подтверждено',
|
'подтверждение', 'confirmed' => 'подтверждение',
|
||||||
'Комментарий', 'commentary' => 'Комментарий',
|
'примечание от ТТ', 'commentary' => 'примечание от ТТ',
|
||||||
'Ответ', 'response' => 'Ответ',
|
'ответ от контрагента', 'response' => 'ответ от контрагента',
|
||||||
'ID', '_id' => 'ID',
|
'ID', '_id' => 'ID',
|
||||||
default => $name
|
default => $name
|
||||||
};
|
};
|
||||||
|
@ -95,11 +81,12 @@ function filterWorker(?string $worker): string
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
return match ((int) $worker) {
|
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) {
|
default => (function () use ($worker, $arangodb) {
|
||||||
if (
|
return $worker;
|
||||||
|
/* if (
|
||||||
collection::init($arangodb->session, 'workers')
|
collection::init($arangodb->session, 'workers')
|
||||||
&& collection::search(
|
&& collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
|
@ -109,7 +96,7 @@ function filterWorker(?string $worker): string
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) return $worker;
|
) return $worker;
|
||||||
else return '';
|
else return $worker; */
|
||||||
})()
|
})()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -124,7 +111,7 @@ function init(array $row, bool $reverse = false): array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sync(int $_i, Row &$row, array $raw = []): void
|
function sync(int $_i, Row &$row, ?array $raw = null): void
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
|
@ -144,29 +131,22 @@ function sync(int $_i, Row &$row, array $raw = []): void
|
||||||
|
|
||||||
// Инициализация данных для записи в таблицу
|
// Инициализация данных для записи в таблицу
|
||||||
$new = [
|
$new = [
|
||||||
'imported_created_in_sheets' => $work->imported_created_in_sheets,
|
|
||||||
'imported_date' => $work->imported_date,
|
|
||||||
'imported_market' => $work->imported_market,
|
|
||||||
'imported_worker' => $work->imported_worker,
|
|
||||||
'imported_work' => $work->imported_work,
|
|
||||||
'imported_start' => $work->imported_start,
|
|
||||||
'imported_end' => $work->imported_end,
|
|
||||||
'imported_hours' => $work->imported_hours,
|
|
||||||
'created_in_sheets' => $work->created_in_sheets,
|
'created_in_sheets' => $work->created_in_sheets,
|
||||||
'date' => $work->date,
|
'date' => $work->date,
|
||||||
'market' => $work->market,
|
|
||||||
'type' => $work->type,
|
|
||||||
'address' => $work->address,
|
|
||||||
'worker' => $work->worker,
|
'worker' => $work->worker,
|
||||||
'name' => $work->name,
|
'name' => $work->name,
|
||||||
'work' => $work->work,
|
'work' => $work->work,
|
||||||
'start' => $work->start,
|
'start' => $work->start,
|
||||||
'end' => $work->end,
|
'end' => $work->end,
|
||||||
'hours' => $work->hours,
|
'hours' => $work->hours,
|
||||||
'tax' => $work->tax,
|
'market' => $work->market,
|
||||||
|
'type' => $work->type,
|
||||||
|
'address' => $work->address,
|
||||||
'confirmed' => $work->confirmed,
|
'confirmed' => $work->confirmed,
|
||||||
'commentary' => $work->commentary,
|
'commentary' => $work->commentary,
|
||||||
'response' => $work->response,
|
'response' => $work->response,
|
||||||
|
'updated_in_sheets' => $work->updated_in_sheets,
|
||||||
|
'tax' => $work->tax,
|
||||||
'_id' => $work->getId(),
|
'_id' => $work->getId(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -275,7 +255,7 @@ function sync(int $_i, Row &$row, array $raw = []): void
|
||||||
$_row['market']
|
$_row['market']
|
||||||
)
|
)
|
||||||
)) {
|
)) {
|
||||||
// Инициализирована инстанция документа в базе данных нового магазина
|
// Инициализирована инстанция документа в базе данных нового мазагина
|
||||||
|
|
||||||
// Реинициализация магазина
|
// Реинициализация магазина
|
||||||
$request->_from = $_market->getId();
|
$request->_from = $_market->getId();
|
||||||
|
@ -306,35 +286,28 @@ function sync(int $_i, Row &$row, array $raw = []): void
|
||||||
} else if (
|
} else if (
|
||||||
(!empty($_row['imported_market']) || !empty($_row['market']))
|
(!empty($_row['imported_market']) || !empty($_row['market']))
|
||||||
&& collection::init($arangodb->session, 'requests', true) && collection::init($arangodb->session, 'markets')
|
&& collection::init($arangodb->session, 'requests', true) && collection::init($arangodb->session, 'markets')
|
||||||
&& ($market = collection::search($arangodb->session, sprintf("FOR d IN markets FILTER d.id == '%s' RETURN d", $raw[2] ?? $_row[10])))
|
&& ($market = collection::search($arangodb->session, sprintf("FOR d IN markets FILTER d.id == '%s' RETURN d", $_row['imported_market'] ?? $_row['market'])))
|
||||||
&& $work = collection::search(
|
&& $work = collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN works FILTER d._id == '%s' RETURN d",
|
"FOR d IN works FILTER d._id == '%s' RETURN d",
|
||||||
document::write($arangodb->session, 'works', [
|
document::write($arangodb->session, 'works', [
|
||||||
'imported_created_in_sheets' => $raw[0],
|
'created_in_sheets' => $raw[0] ?? '',
|
||||||
'imported_date' => $raw[1],
|
'date' => $raw[1] ?? '',
|
||||||
'imported_market' => $raw[2],
|
'worker' => filterWorker($_row['worker'] ?? ''),
|
||||||
'imported_worker' => $raw[3],
|
'name' => "=ЕСЛИ(СОВПАД(\$A$_i;\"\");\"\"; ЕСЛИ( НЕ(СОВПАД(IFNA(ВПР(\$C$_i;part_import_KRSK!\$R$2:\$R$4999;1;);\"\");\$C$_i)); ЕСЛИ((СОВПАД(IFNA(ВПР(\$C$_i;part_import_KRSK!\$I\$2:\$L\$4999;4);\"\");\"\")); IFNA(ВПР(\$C$_i;part_import_KRSK!\$I\$2:\$J\$4999;2;); \"Сотрудник не назначен\"); \"УВОЛЕН (В списке работающих)\"); \"УВОЛЕН (В списке уволенных)\"))",
|
||||||
'imported_work' => $raw[4],
|
'work' => $_row['work'] ?? '',
|
||||||
'imported_start' => $raw[5],
|
'start' => $raw[5] ?? '',
|
||||||
'imported_end' => $raw[6],
|
'end' => $raw[6] ?? '',
|
||||||
'imported_hours' => $raw[7],
|
'hours' => $_row['hours'] ?? '',
|
||||||
'created_in_sheets' => $raw[0] ?? $raw[8],
|
'market' => $_row['market'] ?? '',
|
||||||
'date' => $raw[1] ?? $raw[9],
|
'type' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;2;);\"Нет в базе\"))",
|
||||||
'market' => $raw[2] ?? $raw[10],
|
'address' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;4;);\"Нет в базе\"))",
|
||||||
'type' => "=ЕСЛИ(СОВПАД(I$_i;\"\");\"\"; IFNA(ВПР(K$_i;part_import_KRSK!\$B\$2:\$E\$15603;2;);\"Нет в базе\"))",
|
|
||||||
'address' => "=ЕСЛИ(СОВПАД(I$_i;\"\");\"\"; IFNA(ВПР(K$_i;part_import_KRSK!\$B\$2:\$E\$15603;4;);\"Нет в базе\"))",
|
|
||||||
'worker' => filterWorker($raw[13] ?? $raw[3]),
|
|
||||||
'name' => "=ЕСЛИ(СОВПАД(\$I$_i;\"\");\"\"; ЕСЛИ( НЕ(СОВПАД(IFNA(ВПР(\$N$_i;part_import_KRSK!\$R$2:\$R$4999;1;);\"\");\$N$_i)); ЕСЛИ((СОВПАД(IFNA(ВПР(\$N$_i;part_import_KRSK!\$I\$2:\$L\$4999;4);\"\");\"\")); IFNA(ВПР(\$N$_i;part_import_KRSK!\$I\$2:\$J\$4999;2;); \"Сотрудник не назначен\"); \"УВОЛЕН (В списке работающих)\"); \"УВОЛЕН (В списке уволенных)\"))",
|
|
||||||
'work' => $raw[4] ?? $raw[15],
|
|
||||||
'start' => $raw[5] ?? $raw[16],
|
|
||||||
'end' => $raw[6] ?? $raw[17],
|
|
||||||
'hours' => $raw[7] ?? $raw[18],
|
|
||||||
'tax' => "=ЕСЛИ(СОВПАД(\$I$_i;\"\");\"\"; IFNA(ВПР(\$N$_i;part_import_KRSK!\$I\$2:\$K\$5000;3;); IFNA(ВПР(\$N$_i;part_import_KRSK!\$R\$2:\$T\$5000;3;);\"000000000000\")))",
|
|
||||||
'confirmed' => $_row['confirmed'] ?? '',
|
'confirmed' => $_row['confirmed'] ?? '',
|
||||||
'commentary' => $_row['commentary'] ?? '',
|
'commentary' => $_row['commentary'] ?? '',
|
||||||
'response' => $_row['response'] ?? '',
|
'response' => $_row['response'] ?? '',
|
||||||
|
'updated_in_sheets' => $raw[14] ?? '',
|
||||||
|
'tax' => "=ЕСЛИ(СОВПАД(\$A$_i;\"\");\"\"; IFNA(ВПР(\$C$_i;part_import_KRSK!\$I\$2:\$K\$5000;3;); IFNA(ВПР(\$C$_i;part_import_KRSK!\$R\$2:\$T\$5000;3;);\"000000000000\")))",
|
||||||
'transfer_to_sheets' => false
|
'transfer_to_sheets' => false
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
@ -373,30 +346,23 @@ function sync(int $_i, Row &$row, array $raw = []): void
|
||||||
|
|
||||||
// Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
// Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
||||||
$row = $row->set((new Flow())->read(From::array([init([
|
$row = $row->set((new Flow())->read(From::array([init([
|
||||||
'imported_created_in_sheets' => $raw[0] ?? '',
|
'created_in_sheets' => $raw[0] ?? '',
|
||||||
'imported_date' => $raw[1] ?? '',
|
'date' => $raw[1] ?? '',
|
||||||
'imported_market' => $_row['imported_market'] ?? '',
|
'worker' => filterWorker($_row['worker'] ?? ''),
|
||||||
'imported_worker' => $_row['imported_worker'] ?? '',
|
'name' => "=ЕСЛИ(СОВПАД(\$A$_i;\"\");\"\"; ЕСЛИ( НЕ(СОВПАД(IFNA(ВПР(\$C$_i;part_import_KRSK!\$R$2:\$R$4999;1;);\"\");\$C$_i)); ЕСЛИ((СОВПАД(IFNA(ВПР(\$C$_i;part_import_KRSK!\$I\$2:\$L\$4999;4);\"\");\"\")); IFNA(ВПР(\$C$_i;part_import_KRSK!\$I\$2:\$J\$4999;2;); \"Сотрудник не назначен\"); \"УВОЛЕН (В списке работающих)\"); \"УВОЛЕН (В списке уволенных)\"))",
|
||||||
'imported_work' => $_row['imported_work'] ?? '',
|
'work' => $_row['work'] ?? '',
|
||||||
'imported_start' => $raw[5] ?? '',
|
'start' => $raw[5] ?? '',
|
||||||
'imported_end' => $raw[6] ?? '',
|
'end' => $raw[6] ?? '',
|
||||||
'imported_hours' => $_row['imported_hours'] ?? '',
|
'hours' => $_row['hours'] ?? '',
|
||||||
'created_in_sheets' => $raw[0] ?? $raw[8],
|
'market' => $_row['market'] ?? '',
|
||||||
'date' => $raw[1] ?? $raw[9],
|
'type' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;2;);\"Нет в базе\"))",
|
||||||
'market' => $raw[2] ?? $raw[10],
|
'address' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;4;);\"Нет в базе\"))",
|
||||||
'type' => "=ЕСЛИ(СОВПАД(I$_i;\"\");\"\"; IFNA(ВПР(K$_i;part_import_KRSK!\$B\$2:\$E\$15603;2;);\"Нет в базе\"))",
|
|
||||||
'address' => "=ЕСЛИ(СОВПАД(I$_i;\"\");\"\"; IFNA(ВПР(K$_i;part_import_KRSK!\$B\$2:\$E\$15603;4;);\"Нет в базе\"))",
|
|
||||||
'worker' => filterWorker($raw[13] ?? $raw[3]),
|
|
||||||
'name' => "=ЕСЛИ(СОВПАД(\$I$_i;\"\");\"\"; ЕСЛИ( НЕ(СОВПАД(IFNA(ВПР(\$N$_i;part_import_KRSK!\$R$2:\$R$4999;1;);\"\");\$N$_i)); ЕСЛИ((СОВПАД(IFNA(ВПР(\$N$_i;part_import_KRSK!\$I\$2:\$L\$4999;4);\"\");\"\")); IFNA(ВПР(\$N$_i;part_import_KRSK!\$I\$2:\$J\$4999;2;); \"Сотрудник не назначен\"); \"УВОЛЕН (В списке работающих)\"); \"УВОЛЕН (В списке уволенных)\"))",
|
|
||||||
'work' => $raw[4] ?? $raw[15],
|
|
||||||
'start' => $raw[5] ?? $raw[16],
|
|
||||||
'end' => $raw[6] ?? $raw[17],
|
|
||||||
'hours' => $raw[7] ?? $raw[18],
|
|
||||||
'tax' => "=ЕСЛИ(СОВПАД(\$I$_i;\"\");\"\"; IFNA(ВПР(\$N$_i;part_import_KRSK!\$I\$2:\$K\$5000;3;); IFNA(ВПР(\$N$_i;part_import_KRSK!\$R\$2:\$T\$5000;3;);\"000000000000\")))",
|
|
||||||
'confirmed' => $_row['confirmed'] ?? '',
|
'confirmed' => $_row['confirmed'] ?? '',
|
||||||
'commentary' => $_row['commentary'] ?? '',
|
'commentary' => $_row['commentary'] ?? '',
|
||||||
'response' => $_row['response'] ?? '',
|
'response' => $_row['response'] ?? '',
|
||||||
'_id' => $_row['_id'] ?? '',
|
'updated_in_sheets' => $raw[14] ?? '',
|
||||||
|
'tax' => "=ЕСЛИ(СОВПАД(\$A$_i;\"\");\"\"; IFNA(ВПР(\$C$_i;part_import_KRSK!\$I\$2:\$K\$5000;3;); IFNA(ВПР(\$C$_i;part_import_KRSK!\$R\$2:\$T\$5000;3;);\"000000000000\")))",
|
||||||
|
'_id' => $_row['_id'] ?? ''
|
||||||
], true)]))->fetch(1)[0]->get('row'));
|
], true)]))->fetch(1)[0]->get('row'));
|
||||||
} else return;
|
} else return;
|
||||||
else throw new exception('Не удалось инициализировать коллекцию');
|
else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
|
@ -416,53 +382,32 @@ foreach ($sheets as $sheet) {
|
||||||
// Инициализация обработчика таблиц
|
// Инициализация обработчика таблиц
|
||||||
$sheets = new Sheets($client);
|
$sheets = new Sheets($client);
|
||||||
|
|
||||||
// Инициализация инстанции Flow для Google Sheet API
|
// Инициализация инстанций Flow для Google Sheet API
|
||||||
$rows = (new Flow())->read(new GoogleSheetExtractor($sheets, $document, new Columns($sheet, 'A', 'X'), true, 1000, 'row'));
|
$formulas = (new Flow())->read(new GoogleSheetExtractor($sheets, $document, new Columns($sheet, 'A', 'Q'), true, 1000, 'row', ['valueRenderOption' => 'FORMULA']));
|
||||||
|
$rows = $sheets->spreadsheets_values->get($document, "$sheet!A:Q");
|
||||||
|
|
||||||
// Инициализация счётчика итераций
|
// Инициализация счётчика итераций
|
||||||
$i = 1;
|
$i = 1;
|
||||||
|
|
||||||
$raws = $sheets->spreadsheets_values->get($document, "$sheet!A:X") ?? null;
|
foreach ($formulas->fetch(50000) as $formula) {
|
||||||
|
|
||||||
if ($raws === null) continue;
|
|
||||||
|
|
||||||
foreach ($rows->fetch(10000) as $row) {
|
|
||||||
// Перебор строк
|
// Перебор строк
|
||||||
|
|
||||||
// Запись счётчика
|
// Запись счётчика
|
||||||
++$i;
|
++$i;
|
||||||
|
|
||||||
// Инициализация буфера строки
|
// Инициализация буфера строки
|
||||||
$buffer = $row;
|
$buffer = $formula;
|
||||||
|
|
||||||
// Синхронизация с базой данных
|
// Синхронизация с базой данных
|
||||||
sync($i, $row, $raws[$i - 1]);
|
sync($i, $formula, $rows[$i - 1] ?? null);
|
||||||
|
|
||||||
// Запись изменений строки в Google Sheet
|
// Запись изменений строки в Google Sheet
|
||||||
if ($buffer !== $row) {
|
if ($buffer !== $formula) {
|
||||||
$row = init($row->toArray()['row']);
|
|
||||||
|
|
||||||
$sheets->spreadsheets_values->update(
|
$sheets->spreadsheets_values->update(
|
||||||
$document,
|
$document,
|
||||||
"$sheet!I$i:X$i",
|
"$sheet!A$i:Q$i",
|
||||||
new ValueRange(['values' => [array_values(init([
|
new ValueRange(['values' => [array_values($formula->entries()->toArray()['row'])]]),
|
||||||
'created_in_sheets' => $row['created_in_sheets'] ?? '',
|
|
||||||
'date' => $row['date'] ?? '',
|
|
||||||
'market' => $row['market'] ?? '',
|
|
||||||
'type' => $row['type'] ?? '',
|
|
||||||
'address' => $row['address'] ?? '',
|
|
||||||
'worker' => $row['worker'] ?? '',
|
|
||||||
'name' => $row['name'] ?? '',
|
|
||||||
'work' => $row['work'] ?? '',
|
|
||||||
'start' => $row['start'] ?? '',
|
|
||||||
'end' => $row['end'] ?? '',
|
|
||||||
'hours' => $row['hours'] ?? '',
|
|
||||||
'tax' => $row['tax'] ?? '',
|
|
||||||
'confirmed' => $row['confirmed'] ?? '',
|
|
||||||
'commentary' => $row['commentary'] ?? '',
|
|
||||||
'response' => $row['response'] ?? '',
|
|
||||||
'_id' => $row['_id'] ?? '',
|
|
||||||
], true))]]),
|
|
||||||
['valueInputOption' => 'USER_ENTERED']
|
['valueInputOption' => 'USER_ENTERED']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/arangodb.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/arangodb.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/document.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/document.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/google.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/google.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/sheets.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/markets/sheets.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/document.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/document.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/google.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/google.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/sheets.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/workers/sheets.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/document.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/document.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/google.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/google.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/sheets.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/google_sheets/parser/system/settings/works/sheets.php.sample
Normal file → Executable file
Reference in New Issue