Compare commits
13 Commits
9a23715012
...
1.3.0
Author | SHA1 | Date | |
---|---|---|---|
af33a20c81 | |||
c5facf13b0 | |||
f3bd5872f5 | |||
4e88505833 | |||
0306f882c0 | |||
5387637e35 | |||
e7705a4fa1 | |||
542817f9f1 | |||
![]() |
ccec5ca031 | ||
aa5b3a2337 | |||
3ed5c98d56 | |||
b1329cc3a8 | |||
a0426fad60 |
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
2
README.md
Normal file → Executable file
2
README.md
Normal file → Executable file
@@ -2,4 +2,4 @@
|
||||
|
||||
Synchronizes Google Sheets with ArangoDB
|
||||
|
||||
😼 Developed in 1 days for 100000 rubles ($1200)
|
||||
~~😼 Developed in 1 day for 100000 rubles ($1200)~~ shit happens
|
||||
|
0
composer.json
Normal file → Executable file
0
composer.json
Normal file → Executable file
96
composer.lock
generated
Normal file → Executable file
96
composer.lock
generated
Normal file → Executable file
@@ -4,20 +4,20 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "11076f3d90ec7beb78f179975cadfba0",
|
||||
"content-hash": "a68510590091701e9c9d83f85929c2ca",
|
||||
"packages": [
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.5.0",
|
||||
"version": "v6.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2"
|
||||
"reference": "71278f20b0a623389beefe87a641d03948a38870"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/e94e7353302b0c11ec3cfff7180cd0b1743975d2",
|
||||
"reference": "e94e7353302b0c11ec3cfff7180cd0b1743975d2",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/71278f20b0a623389beefe87a641d03948a38870",
|
||||
"reference": "71278f20b0a623389beefe87a641d03948a38870",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -65,9 +65,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.5.0"
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.7.0"
|
||||
},
|
||||
"time": "2023-05-12T15:47:07+00:00"
|
||||
"time": "2023-06-14T15:29:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "flow-php/array-dot",
|
||||
@@ -299,16 +299,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/apiclient-services",
|
||||
"version": "v0.303.0",
|
||||
"version": "v0.304.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||
"reference": "b9c143453a94d5e6ed7257d065dcc5662619eaf4"
|
||||
"reference": "6731fd0d3e2f1ff2794f36108b55c0a3480edf3d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/b9c143453a94d5e6ed7257d065dcc5662619eaf4",
|
||||
"reference": "b9c143453a94d5e6ed7257d065dcc5662619eaf4",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/6731fd0d3e2f1ff2794f36108b55c0a3480edf3d",
|
||||
"reference": "6731fd0d3e2f1ff2794f36108b55c0a3480edf3d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -337,9 +337,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.303.0"
|
||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.304.0"
|
||||
},
|
||||
"time": "2023-06-04T01:12:12+00:00"
|
||||
"time": "2023-06-07T02:11:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "google/auth",
|
||||
@@ -1199,16 +1199,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpseclib/phpseclib",
|
||||
"version": "3.0.19",
|
||||
"version": "3.0.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpseclib/phpseclib.git",
|
||||
"reference": "cc181005cf548bfd8a4896383bb825d859259f95"
|
||||
"reference": "543a1da81111a0bfd6ae7bbc2865c5e89ed3fc67"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/cc181005cf548bfd8a4896383bb825d859259f95",
|
||||
"reference": "cc181005cf548bfd8a4896383bb825d859259f95",
|
||||
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/543a1da81111a0bfd6ae7bbc2865c5e89ed3fc67",
|
||||
"reference": "543a1da81111a0bfd6ae7bbc2865c5e89ed3fc67",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1289,7 +1289,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpseclib/phpseclib/issues",
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.19"
|
||||
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.20"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1305,7 +1305,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-05T17:13:09+00:00"
|
||||
"time": "2023-06-13T06:30:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@@ -1788,64 +1788,6 @@
|
||||
"source": "https://github.com/arangodb/arangodb-php/tree/v3.8.0"
|
||||
},
|
||||
"time": "2021-06-18T12:06:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<0.12.20",
|
||||
"vimeo/psalm": "<4.6.1 || 4.6.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.10-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Assertions to validate method input/output with nice error messages.",
|
||||
"keywords": [
|
||||
"assert",
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/assert/issues",
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||
},
|
||||
"time": "2022-06-03T18:03:27+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
@@ -1,2 +0,0 @@
|
||||
storage/*
|
||||
!storage
|
152
mirzaev/spetsresurs/google_sheets/parser/system/public/markets.php
Normal file → Executable file
152
mirzaev/spetsresurs/google_sheets/parser/system/public/markets.php
Normal file → Executable file
@@ -27,16 +27,17 @@ use Google\Client,
|
||||
|
||||
require __DIR__ . '/../../../../../../vendor/autoload.php';
|
||||
|
||||
$arangodb = new connection(require '../settings/arangodb.php');
|
||||
$arangodb = new connection(require __DIR__ . '/../settings/arangodb.php');
|
||||
|
||||
function generateLabel(string $name): string
|
||||
{
|
||||
return match ($name) {
|
||||
'id', 'ID', 'ТТ' => 'id',
|
||||
'type', 'ТИП', 'Тип', 'тип' => 'type',
|
||||
'director', 'ДИРЕКТОР', 'Директор', 'директор' => 'director',
|
||||
'id', 'ID', 'ТТ', '№ТТ' => 'id',
|
||||
'type', 'ТИП', 'Тип', 'тип', 'ФОРМАТ' => 'type',
|
||||
'name', 'ДИРЕКТОР', 'Директор', 'директор', 'ДИРЕКТОР ТТ' => 'name',
|
||||
'address', 'АДРЕС', 'Адрес', 'адрес' => 'address',
|
||||
default => throw new exception("Неизвестный столбец: $name")
|
||||
'city', 'город', 'Город', 'Направление' => 'city',
|
||||
default => $name
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,12 +46,24 @@ function degenerateLabel(string $name): string
|
||||
return match ($name) {
|
||||
'ID', 'id' => 'ID',
|
||||
'ТИП', 'type' => 'ТИП',
|
||||
'ДИРЕКТОР', 'director' => 'ДИРЕКТОР',
|
||||
'ДИРЕКТОР', 'name' => 'ДИРЕКТОР',
|
||||
'АДРЕС', 'address' => 'АДРЕС',
|
||||
default => throw new exception("Неизвестный столбец: $name")
|
||||
'city' => 'ГОРОД',
|
||||
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
|
||||
{
|
||||
$buffer = [];
|
||||
@@ -61,25 +74,108 @@ function init(array $row, bool $reverse = false): array
|
||||
}
|
||||
|
||||
|
||||
function sync(Row &$row, string $city = 'Красноярск'): void
|
||||
function sync(Row &$row): 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('Не удалось инициализировать коллекцию');
|
||||
// Инициализация ФИО
|
||||
$name = explode(' ', $_row['name']);
|
||||
|
||||
if (collection::init($arangodb->session, 'market'))
|
||||
if (!empty($_row['id']) && $market = collection::search($arangodb->session, sprintf("FOR d IN market FILTER d.id == '%s' RETURN d", $_row['id']))) {
|
||||
// Найдена запись магазина (строки) в базе данных и включен режим перезаписи (приоритет - google sheets)
|
||||
|
||||
if (false && $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 (
|
||||
$market = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN market FILTER d._id == '%s' RETURN d",
|
||||
document::write($arangodb->session, 'market', [
|
||||
'id' => $_row['id'] ?? '',
|
||||
'type' => $_row['type'] ?? '',
|
||||
'name' => [
|
||||
'first' => $name[1] ?? $_row['name'] ?? '',
|
||||
'second' => $name[0] ?? '',
|
||||
'last' => $name[2] ?? ''
|
||||
],
|
||||
'address' => $_row['address'] ?? '',
|
||||
'city' => $_row['city'] ?? '',
|
||||
'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)
|
||||
$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('../settings/markets/google.php'), true);
|
||||
$document = require('../settings/markets/document.php');
|
||||
$sheets = require('../settings/markets/sheets.php');
|
||||
$settings = json_decode(require(__DIR__ . '/../settings/markets/google.php'), true);
|
||||
$document = require(__DIR__ . '/../settings/markets/document.php');
|
||||
$sheets = require(__DIR__ . '/../settings/markets/sheets.php');
|
||||
|
||||
$client = new Client();
|
||||
$client->setScopes(Sheets::SPREADSHEETS);
|
||||
@@ -87,19 +183,23 @@ $client->setAuthConfig($settings);
|
||||
$api = new Sheets($client);
|
||||
|
||||
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;
|
||||
foreach ($rows->fetch(100) as $row) {
|
||||
++$i;
|
||||
foreach ($rows->fetch(5000) as $row) {
|
||||
if (++$i === 2) continue;
|
||||
$buffer = $row;
|
||||
sync($row, $sheet);
|
||||
if ($buffer !== $row)
|
||||
$api->spreadsheets_values->update(
|
||||
sync($row);
|
||||
if ($buffer !== $row) {
|
||||
/* $api->spreadsheets_values->update(
|
||||
$document,
|
||||
"$sheet!A$i:D$i",
|
||||
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
||||
['valueInputOption' => 'USER_ENTERED']
|
||||
);
|
||||
|
||||
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
||||
sleep(3); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
254
mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php
Normal file → Executable file
254
mirzaev/spetsresurs/google_sheets/parser/system/public/workers.php
Normal file → Executable file
@@ -27,28 +27,28 @@ use Google\Client,
|
||||
|
||||
require __DIR__ . '/../../../../../../vendor/autoload.php';
|
||||
|
||||
$arangodb = new connection(require '../settings/arangodb.php');
|
||||
$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',
|
||||
'number', 'Номер' => 'number',
|
||||
'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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -57,24 +57,35 @@ function degenerateLabel(string $name): string
|
||||
return match ($name) {
|
||||
'ID', 'id' => 'ID',
|
||||
'ФИО', 'name' => 'ФИО',
|
||||
'Номер', 'phone' => 'Номер',
|
||||
'Номер', 'number' => 'Номер',
|
||||
'Дата рождения', 'birth' => 'Дата рождения',
|
||||
'Адрес регистрации', 'address' => 'Адрес регистрации',
|
||||
'Комментарий', 'commentary' => 'Комментарий',
|
||||
'Регистрация', '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('/\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
|
||||
{
|
||||
$buffer = [];
|
||||
@@ -110,7 +121,7 @@ function connect(_document $worker, _document $robot): void
|
||||
)
|
||||
))
|
||||
) {
|
||||
// Инициализировано ребро: workers -> robot (любой)
|
||||
// Инициализировано ребро: worker -> robot (любой)
|
||||
|
||||
// Активация
|
||||
$robot->status = 'active';
|
||||
@@ -122,17 +133,40 @@ function connectAll(_document $worker): void
|
||||
{
|
||||
global $arangodb;
|
||||
|
||||
// Инициализация ребра: workers -> viber
|
||||
// Инициализация ребра: worker -> viber
|
||||
if (
|
||||
collection::init($arangodb->session, 'viber')
|
||||
&& $viber = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"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);
|
||||
}
|
||||
|
||||
|
||||
function id()
|
||||
{
|
||||
global $arangodb;
|
||||
|
||||
return collection::search(
|
||||
$arangodb->session,
|
||||
"RETURN MAX((FOR d in worker RETURN +d.id))",
|
||||
) + 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,28 +174,155 @@ 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])))
|
||||
) {
|
||||
// Инициализирован работник
|
||||
// Инициализация ФИО
|
||||
$name = explode(' ', $_row['name']);
|
||||
|
||||
// Реинициализация строки с актуальными записями (приоритет у базы данных)
|
||||
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 (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)
|
||||
|
||||
// Подключение к чат-роботам
|
||||
connectAll($worker);
|
||||
} else throw new exception('Не удалось создать или найти созданного работника');
|
||||
else throw new exception('Не удалось инициализировать коллекцию');
|
||||
if (false && $worker->transfer_to_sheets) {
|
||||
// Запрошен форсированный перенос данных из базы данных в таблицу
|
||||
|
||||
// Инициализация данных для записи в таблицу
|
||||
/* $new = [
|
||||
'id' => $worker->id ?? id(),
|
||||
'name' => $worker->name ?? '',
|
||||
'number' => convertNumber($worker->number ?? ''),
|
||||
'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['number']) */
|
||||
/* && */
|
||||
$worker = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN worker FILTER d._id == '%s' RETURN d",
|
||||
document::write($arangodb->session, 'worker', [
|
||||
'id' => $_row['id'] ?? id(),
|
||||
'name' => [
|
||||
'first' => $name[1] ?? $_row['name'] ?? '',
|
||||
'second' => $name[0] ?? '',
|
||||
'last' => $name[2] ?? ''
|
||||
],
|
||||
'number' => convertNumber($_row['number'] ?? ''),
|
||||
'birth' => $_row['birth'] ?? '',
|
||||
'address' => $_row['address'] ?? '',
|
||||
'commentary' => $_row['commentary'] ?? '',
|
||||
'activity' => $_row['activity'] ?? '',
|
||||
'passport' => $_row['passport'] ?? '',
|
||||
'issued' => '',
|
||||
'department' => [
|
||||
'number' => $_row['department'] ?? '',
|
||||
'address' => $_row['issued'] ?? ''
|
||||
],
|
||||
'hiring' => $_row['hiring'] ?? '',
|
||||
'district' => $_row['district'] ?? '',
|
||||
'requisites' => $_row['requisites'] ?? '',
|
||||
'fired' => $_row['fired'] ?? '',
|
||||
'payment' => $_row['payment'] ?? '',
|
||||
'tax' => $_row['tax'] ?? '',
|
||||
'city' => 'Красноярск' ?? $city,
|
||||
'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['number'] ?? ''); */
|
||||
|
||||
// Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
||||
/* $row = $row->set((new Flow())->read(From::array([init([
|
||||
'id' => $_row['id'] ?? '',
|
||||
'name' => $_row['name'] ?? '',
|
||||
'number' => "=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('../settings/workers/google.php'), true);
|
||||
$document = require('../settings/workers/document.php');
|
||||
$sheets = require('../settings/workers/sheets.php');
|
||||
$settings = json_decode(require(__DIR__ . '/../settings/workers/google.php'), true);
|
||||
$document = require(__DIR__ . '/../settings/workers/document.php');
|
||||
$sheets = require(__DIR__ . '/../settings/workers/sheets.php');
|
||||
|
||||
$client = new Client();
|
||||
$client->setScopes(Sheets::SPREADSHEETS);
|
||||
@@ -169,20 +330,23 @@ $client->setAuthConfig($settings);
|
||||
$api = new Sheets($client);
|
||||
|
||||
foreach ($sheets as $sheet) {
|
||||
$rows = (new Flow())->read(new GoogleSheetExtractor($api, $document, new Columns($sheet, 'A', 'P'), true, 1000, 'row'));
|
||||
$rows = (new Flow())->read(new GoogleSheetExtractor($api, $document, new Columns($sheet, 'A', 'W'), true, 1000, 'row'));
|
||||
|
||||
$i = 1;
|
||||
foreach ($rows->fetch(5000) as $row) {
|
||||
foreach ($rows->fetch(4183) as $row) {
|
||||
++$i;
|
||||
$buffer = $row;
|
||||
sync($row, $sheet);
|
||||
if ($buffer !== $row) {
|
||||
$api->spreadsheets_values->update(
|
||||
/* $api->spreadsheets_values->update(
|
||||
$document,
|
||||
"$sheet!A$i:P$i",
|
||||
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
||||
['valueInputOption' => 'USER_ENTERED']
|
||||
);
|
||||
); */
|
||||
|
||||
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
||||
/* sleep(3); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
360
mirzaev/spetsresurs/google_sheets/parser/system/public/works.php
Normal file → Executable file
360
mirzaev/spetsresurs/google_sheets/parser/system/public/works.php
Normal file → Executable file
@@ -27,39 +27,77 @@ use Google\Client,
|
||||
|
||||
require __DIR__ . '/../../../../../../vendor/autoload.php';
|
||||
|
||||
$arangodb = new connection(require '../settings/arangodb.php');
|
||||
$arangodb = new connection(require __DIR__ . '/../settings/arangodb.php');
|
||||
|
||||
function generateLabel(string $name): string
|
||||
{
|
||||
return match ($name) {
|
||||
'created_in_sheets', 'Отметка времени' => 'created_in_sheets',
|
||||
'updated_in_sheets', 'время последнего изменения' => 'updated_in_sheets',
|
||||
'date', 'дата заявки' => 'date',
|
||||
'market', '№ магазина' => 'market',
|
||||
'type', 'формат' => 'type',
|
||||
'address', 'адрес' => 'address',
|
||||
'worker', 'Код сотрудника (000000)' => 'worker',
|
||||
'name', 'ФИО' => 'name',
|
||||
'work', 'Вид работ' => 'work',
|
||||
'start', 'Время начала заявки' => 'start',
|
||||
'end', 'Время окончания заявки' => 'end',
|
||||
'hours', 'Количество часов по заявке' => 'hours',
|
||||
'tax', 'ИНН' => 'tax',
|
||||
'confirmed', 'подтверждение' => 'confirmed',
|
||||
'commentary', 'примечание от ТТ' => 'commentary',
|
||||
'response', 'ответ от контрагента' => 'response',
|
||||
'_id', 'ID' => '_id',
|
||||
'market', 'Магазин' => 'market',
|
||||
'worker', 'Сотрудник' => 'worker',
|
||||
'work', 'Работа' => 'work',
|
||||
'date', 'Дата' => 'date',
|
||||
'start', 'Начало' => 'start',
|
||||
'end', 'Конец' => 'end',
|
||||
'confirmed', 'Подтверждено' => 'confirmed',
|
||||
'commentary', 'Комментарий' => 'commentary',
|
||||
'response', 'Ответ' => 'response',
|
||||
default => throw new exception("Неизвестный столбец: $name")
|
||||
default => $name
|
||||
};
|
||||
}
|
||||
|
||||
function degenerateLabel(string $name): string
|
||||
{
|
||||
return match ($name) {
|
||||
'Отметка времени', 'created_in_sheets' => 'Отметка времени',
|
||||
'время последнего изменения', 'updated_in_sheets' => 'время последнего изменения',
|
||||
'дата заявки', 'date' => 'дата заявки',
|
||||
'№ магазина', 'market' => '№ магазина',
|
||||
'формат', 'type' => 'формат',
|
||||
'адрес', 'address' => 'адрес',
|
||||
'Код сотрудника (000000)', 'worker' => 'Код сотрудника (000000)',
|
||||
'ФИО', 'name' => 'ФИО',
|
||||
'Вид работ', 'work' => 'Вид работ',
|
||||
'Время начала заявки', 'start' => 'Время начала заявки',
|
||||
'Время окончания заявки', 'end' => 'Время окончания заявки',
|
||||
'Количество часов по заявке', 'hours' => 'Количество часов по заявке',
|
||||
'ИНН', 'tax' => 'ИНН',
|
||||
'подтверждение', 'confirmed' => 'подтверждение',
|
||||
'примечание от ТТ', 'commentary' => 'примечание от ТТ',
|
||||
'ответ от контрагента', 'response' => 'ответ от контрагента',
|
||||
'ID', '_id' => 'ID',
|
||||
'Магазин', 'market' => 'Магазин',
|
||||
'Сотрудник', 'worker' => 'Сотрудник',
|
||||
'Работа', 'work' => 'Работа',
|
||||
'Дата', 'date' => 'Дата',
|
||||
'Начало', 'start' => 'Начало',
|
||||
'Конец', 'end' => 'Конец',
|
||||
'Подтверждено', 'confirmed' => 'Подтверждено',
|
||||
'Комментарий', 'commentary' => 'Комментарий',
|
||||
'Ответ', 'response' => 'Ответ',
|
||||
default => throw new exception("Неизвестный столбец: $name")
|
||||
default => $name
|
||||
};
|
||||
}
|
||||
|
||||
function filterWorker(?string $worker): string
|
||||
{
|
||||
global $arangodb;
|
||||
|
||||
return match ($worker) {
|
||||
'Отмена', 'отмена', 'ОТМЕНА' => 'Отмена',
|
||||
'', 0, 00, 000, 0000, 00000, 000000, 0000000, 00000000, 000000000, 0000000000 => '',
|
||||
default => (function () use ($worker, $arangodb) {
|
||||
return $worker;
|
||||
/* if (
|
||||
collection::init($arangodb->session, 'workers')
|
||||
&& collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN workers FILTER d.id == '%s' RETURN d",
|
||||
$worker
|
||||
)
|
||||
)
|
||||
) return $worker;
|
||||
else return $worker; */
|
||||
})()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -73,56 +111,205 @@ function init(array $row, bool $reverse = false): array
|
||||
}
|
||||
|
||||
|
||||
function sync(Row &$row): void
|
||||
function sync(int $_i, Row &$row, ?array $raw = null): void
|
||||
{
|
||||
global $arangodb;
|
||||
|
||||
$_row = init($row->entries()->toArray()['row']);
|
||||
// Инициализация строки в Google Sheet
|
||||
$_row = init($row->toArray()['row']);
|
||||
|
||||
// Замена пустой строки на NULL (для логических операций)
|
||||
foreach ($_row as $key => &$value) if ($value === '') $value = null;
|
||||
foreach ($raw as $key => &$value) if ($value === '') $value = null;
|
||||
|
||||
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']))) {
|
||||
// Найдена запись работы (строки) в базе данных
|
||||
// Найдена запись работы (строки) в базе данных
|
||||
|
||||
// Очистка перед записью в таблицу
|
||||
$new = array_diff_key($work->getAll(), ['_key' => true, 'created' => true]);
|
||||
if ($work->transfer_to_sheets) {
|
||||
// Запрошен форсированный перенос данных из базы данных в таблицу
|
||||
|
||||
// Инициализация выбранного сотрудника
|
||||
if (collection::init($arangodb->session, 'readinesses', true) && collection::init($arangodb->session, 'workers'))
|
||||
$new = ['worker' => collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN workers LET e = (FOR e IN readinesses FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
||||
$_row['_id']
|
||||
)
|
||||
)->id ?? ''] + $new;
|
||||
else throw new exception('Не удалось инициализировать коллекции');
|
||||
// Инициализация данных для записи в таблицу
|
||||
$new = [
|
||||
'created_in_sheets' => $work->created_in_sheets,
|
||||
'date' => $work->date,
|
||||
'worker' => $work->worker,
|
||||
'name' => $work->name,
|
||||
'work' => $work->work,
|
||||
'start' => $work->start,
|
||||
'end' => $work->end,
|
||||
'hours' => $work->hours,
|
||||
'market' => $work->market,
|
||||
'type' => $work->type,
|
||||
'address' => $work->address,
|
||||
'confirmed' => $work->confirmed,
|
||||
'commentary' => $work->commentary,
|
||||
'response' => $work->response,
|
||||
'updated_in_sheets' => $work->updated_in_sheets,
|
||||
'tax' => $work->tax,
|
||||
'_id' => $work->getId(),
|
||||
];
|
||||
|
||||
// Инициализация магазина
|
||||
if (collection::init($arangodb->session, 'requests', true) && collection::init($arangodb->session, 'markets'))
|
||||
if ($market = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN markets LET e = (FOR e IN requests FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
||||
$_row['_id']
|
||||
)
|
||||
)) $new = ['market' => $market->id] + $new;
|
||||
else throw new exception('Не удалось найти магазин');
|
||||
else throw new exception('Не удалось инициализировать коллекции');
|
||||
// Инициализация сотрудника
|
||||
if (collection::init($arangodb->session, 'readinesses', true) && collection::init($arangodb->session, 'workers'))
|
||||
$new['worker'] = collection::search(
|
||||
$arangodb->session,
|
||||
$worker = sprintf(
|
||||
"FOR d IN workers LET e = (FOR e IN readinesses FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
||||
$_row['_id']
|
||||
)
|
||||
)?->id;
|
||||
else throw new exception('Не удалось инициализировать коллекции');
|
||||
|
||||
// Запись идентификатора только что созданной записи в базе данных для записи в таблицу
|
||||
$new = ['_id' => $work->getId()] + $new;
|
||||
// Инициализация магазина
|
||||
if (collection::init($arangodb->session, 'requests', true) && collection::init($arangodb->session, 'markets'))
|
||||
if ($new['market'] = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN markets LET e = (FOR e IN requests FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
||||
$_row['_id']
|
||||
)
|
||||
)?->id);
|
||||
else throw new exception('Не удалось найти магазин');
|
||||
else throw new exception('Не удалось инициализировать коллекции');
|
||||
|
||||
// Реинициализация строки с новыми данными по ссылке (приоритет из базы данных)
|
||||
if ($_row !== $new) $row = $row->set((new Flow())->read(From::array([init($new, true)]))->fetch(1)[0]->get('row'));
|
||||
// Замена 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'));
|
||||
|
||||
// Деактивация форсированного трансфера
|
||||
$work->transfer_to_sheets = false;
|
||||
} else {
|
||||
// Перенос изменений из Google Sheet в инстанцию документа в базе данных
|
||||
|
||||
if (
|
||||
collection::init($arangodb->session, 'readinesses', true) && collection::init($arangodb->session, 'workers')
|
||||
&& ($worker = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN workers LET e = (FOR e IN readinesses FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
||||
$_row['_id']
|
||||
)
|
||||
))
|
||||
&& $_row['worker'] !== $work->worker
|
||||
) {
|
||||
// Изменён сотрудник (подразумевается, что внутри google sheet)
|
||||
|
||||
if ($readiness = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR e IN readinesses FILTER e._from == '%s' && e._to == '%s' LIMIT 1 RETURN e",
|
||||
$worker->getId(),
|
||||
$_row['_id']
|
||||
)
|
||||
)) {
|
||||
// Инициализировано ребро: worker => work
|
||||
|
||||
if ($_worker = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN workers FILTER d.id == '%s' LIMIT 1 RETURN d",
|
||||
$_row['worker']
|
||||
)
|
||||
)) {
|
||||
// Инициализирована инстанция документа в базе данных нового работника
|
||||
|
||||
// Реинициализация работника
|
||||
$readiness->_from = $_worker->getId();
|
||||
|
||||
// Обновление в базе данных
|
||||
document::update($arangodb->session, $readiness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
collection::init($arangodb->session, 'requests', true) && collection::init($arangodb->session, 'markets')
|
||||
&& ($market = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN markets LET e = (FOR e IN requests FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
||||
$_row['_id']
|
||||
)
|
||||
))
|
||||
&& $_row['market'] !== $work->market
|
||||
) {
|
||||
// Изменён магазин (подразумевается, что внутри google sheet)
|
||||
|
||||
if ($request = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR e IN requests FILTER e._from == '%s' && e._to == '%s' LIMIT 1 RETURN e",
|
||||
$market->getId(),
|
||||
$_row['_id']
|
||||
)
|
||||
)) {
|
||||
// Инициализировано ребро: market => work
|
||||
|
||||
if ($_market = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN markets FILTER d.id == '%s' LIMIT 1 RETURN d",
|
||||
$_row['market']
|
||||
)
|
||||
)) {
|
||||
// Инициализирована инстанция документа в базе данных нового мазагина
|
||||
|
||||
// Реинициализация магазина
|
||||
$request->_from = $_market->getId();
|
||||
|
||||
// Обновление в базе данных
|
||||
document::update($arangodb->session, $request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация счётчика итераций
|
||||
$i = 0;
|
||||
|
||||
// Реинициализация данных в инстанции документа в базе данных с данными из Google Sheet
|
||||
foreach (array_diff_key($work->getAll(), ['_key' => true, 'created' => true]) as $key => $value) {
|
||||
// Перебор всех записанных значений в инстанции документа в базе данных
|
||||
|
||||
// Конвертация
|
||||
$work->{$key} = is_array($value) ? ['number' => $_row[$key] ?? $value, 'converted' => $raw[$i]] : $_row[$key] ?? $value;
|
||||
|
||||
// Запись в счётчик итераций
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
|
||||
// Обновление инстанции документа в базе данных
|
||||
document::update($arangodb->session, $work);
|
||||
} else if (
|
||||
!empty($_row['market'])
|
||||
(!empty($_row['imported_market']) || !empty($_row['market']))
|
||||
&& 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", $_row['market'])))
|
||||
&& ($market = collection::search($arangodb->session, sprintf("FOR d IN markets FILTER d.id == '%s' RETURN d", $_row['imported_market'] ?? $_row['market'])))
|
||||
&& $work = collection::search(
|
||||
$arangodb->session,
|
||||
sprintf(
|
||||
"FOR d IN works FILTER d._id == '%s' RETURN d",
|
||||
document::write($arangodb->session, 'works', array_diff_key($_row, ['_id' => true, 'market' => true, 'worker' => true]))
|
||||
document::write($arangodb->session, 'works', [
|
||||
'created_in_sheets' => $raw[0] ?? '',
|
||||
'date' => $raw[1] ?? '',
|
||||
'worker' => filterWorker($_row['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;); \"Сотрудник не назначен\"); \"УВОЛЕН (В списке работающих)\"); \"УВОЛЕН (В списке уволенных)\"))",
|
||||
'work' => $_row['work'] ?? '',
|
||||
'start' => $raw[5] ?? '',
|
||||
'end' => $raw[6] ?? '',
|
||||
'hours' => $_row['hours'] ?? '',
|
||||
'market' => $_row['market'] ?? '',
|
||||
'type' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;2;);\"Нет в базе\"))",
|
||||
'address' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;4;);\"Нет в базе\"))",
|
||||
'confirmed' => $_row['confirmed'] ?? '',
|
||||
'commentary' => $_row['commentary'] ?? '',
|
||||
'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
|
||||
])
|
||||
)
|
||||
)
|
||||
) {
|
||||
@@ -154,37 +341,78 @@ function sync(Row &$row): void
|
||||
else throw new exception('Не удалось создать готовность сотрудника');
|
||||
}
|
||||
|
||||
// Реинициализация строки с новыми данными по ссылке (приоритет из базы данных)
|
||||
$row = $row->set((new Flow())->read(From::array([init(['_id' => $work->getId()] + $_row, true)]))->fetch(1)[0]->get('row'));
|
||||
// Запись идентификатора только что созданной инстанции документа в базе данных
|
||||
$_row['_id'] = $work->getId();
|
||||
|
||||
// Реинициализация строки с новыми данными по ссылке (приоритет из Google Sheets)
|
||||
$row = $row->set((new Flow())->read(From::array([init([
|
||||
'created_in_sheets' => $raw[0] ?? '',
|
||||
'date' => $raw[1] ?? '',
|
||||
'worker' => filterWorker($_row['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;); \"Сотрудник не назначен\"); \"УВОЛЕН (В списке работающих)\"); \"УВОЛЕН (В списке уволенных)\"))",
|
||||
'work' => $_row['work'] ?? '',
|
||||
'start' => $raw[5] ?? '',
|
||||
'end' => $raw[6] ?? '',
|
||||
'hours' => $_row['hours'] ?? '',
|
||||
'market' => $_row['market'] ?? '',
|
||||
'type' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;2;);\"Нет в базе\"))",
|
||||
'address' => "=ЕСЛИ(СОВПАД(A$_i;\"\");\"\"; IFNA(ВПР(I$_i;part_import_KRSK!\$B\$2:\$E\$15603;4;);\"Нет в базе\"))",
|
||||
'confirmed' => $_row['confirmed'] ?? '',
|
||||
'commentary' => $_row['commentary'] ?? '',
|
||||
'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\")))",
|
||||
'_id' => $_row['_id'] ?? ''
|
||||
], true)]))->fetch(1)[0]->get('row'));
|
||||
} else return;
|
||||
else throw new exception('Не удалось инициализировать коллекцию');
|
||||
}
|
||||
|
||||
$settings = json_decode(require('../settings/works/google.php'), true);
|
||||
$document = require('../settings/works/document.php');
|
||||
$sheets = require('../settings/works/sheets.php');
|
||||
$settings = json_decode(require(__DIR__ . '/../settings/works/google.php'), true);
|
||||
$document = require(__DIR__ . '/../settings/works/document.php');
|
||||
$sheets = require(__DIR__ . '/../settings/works/sheets.php');
|
||||
|
||||
$client = new Client();
|
||||
$client->setScopes(Sheets::SPREADSHEETS);
|
||||
$client->setAuthConfig($settings);
|
||||
|
||||
foreach ($sheets as $sheet) {
|
||||
// Перебор таблиц
|
||||
|
||||
// Инициализация обработчика таблиц
|
||||
$sheets = new Sheets($client);
|
||||
|
||||
$rows = (new Flow())->read(new GoogleSheetExtractor($sheets, $document, new Columns($sheet, 'A', 'J'), true, 1000, 'row'));
|
||||
// Инициализация инстанций Flow для Google Sheet API
|
||||
$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;
|
||||
|
||||
foreach ($rows->fetch(10000) as $row) {
|
||||
foreach ($formulas->fetch(50000) as $formula) {
|
||||
|
||||
// Перебор строк
|
||||
|
||||
// Запись счётчика
|
||||
++$i;
|
||||
$buffer = $row;
|
||||
sync($row);
|
||||
if ($buffer !== $row)
|
||||
|
||||
// Инициализация буфера строки
|
||||
$buffer = $formula;
|
||||
|
||||
// Синхронизация с базой данных
|
||||
sync($i, $formula, $rows[$i - 1] ?? null);
|
||||
|
||||
// Запись изменений строки в Google Sheet
|
||||
if ($buffer !== $formula) {
|
||||
$sheets->spreadsheets_values->update(
|
||||
$document,
|
||||
"$sheet!A$i:J$i",
|
||||
new ValueRange(['values' => [array_values($row->entries()->toArray()['row'])]]),
|
||||
"$sheet!A$i:Q$i",
|
||||
new ValueRange(['values' => [array_values($formula->entries()->toArray()['row'])]]),
|
||||
['valueInputOption' => 'USER_ENTERED']
|
||||
);
|
||||
|
||||
// Ожидание для того, чтобы снизить шанс блокировки от Google
|
||||
sleep(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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
0
sheets/markets.xlsx
Normal file → Executable file
0
sheets/markets.xlsx
Normal file → Executable file
0
sheets/workers.xlsx
Normal file → Executable file
0
sheets/workers.xlsx
Normal file → Executable file
BIN
sheets/works.xlsx
Executable file
BIN
sheets/works.xlsx
Executable file
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user