diff --git a/kodorvan/constructor/system/localizations/russian.php b/kodorvan/constructor/system/localizations/russian.php index 39ee76b..a89191f 100644 --- a/kodorvan/constructor/system/localizations/russian.php +++ b/kodorvan/constructor/system/localizations/russian.php @@ -29,6 +29,7 @@ return [ 'project_create_time' => 'Время разработки', 'project_create_time_hours' => 'ч', 'project_create_time_hours_from' => 'от', + 'project_create_button_back' => 'Назад', 'project_create_button_request' => 'Заказать', 'project_create_architectures_title' => 'Выбор архитектуры проекта', @@ -42,7 +43,7 @@ return [ 'project_create_button_purpose_selected' => 'Назнач.', 'project_create_integrations_title' => 'Выбор интеграций', - 'project_create_integrations_description' => 'Синхронизация, скачивание, загрузка, запись...', + 'project_create_integrations_description' => "Синхронизация данных в реальном времени, скачивание, загрузка, перенос информации, админ\-панель, рассылка сообщений, подключение аккаунтов\.\.\.\n\n_Отправка запросов в *API*, генерация и перехват *HTTP\-сообщений*, *эмуляция* действий пользователя через *виртуальный браузер* с курсором мыши и клавиатурой, либо *нестандартные протоколы связи*_", 'project_create_button_integrations' => 'Интеграции', 'project_create_button_integrations_selected' => 'Интеграции', @@ -87,6 +88,15 @@ return [ 'project_purpose_events' => 'События', 'project_purpose_special' => 'Особенный', + // Проект: интеграции + 'project_integration_one_c' => '1C', + 'project_integration_bitrix24' => 'Битрикс 24', + 'project_integration_moy_sklad' => 'Мой Склад', + 'project_integration_telegram' => 'Телеграм', + 'project_integration_mail' => 'Почта', + 'project_integration_excel' => 'Excel', + /* 'project_integration_' => '', */ + // Настройки: язык 'settings_language_title' => 'Выбери язык', 'settings_language_description' => 'Выбранный язык будет использоваться для генерации системного отображения', diff --git a/kodorvan/constructor/system/models/project/enumerations/architecture.php b/kodorvan/constructor/system/models/project/enumerations/architecture.php index a92324a..aa4353d 100644 --- a/kodorvan/constructor/system/models/project/enumerations/architecture.php +++ b/kodorvan/constructor/system/models/project/enumerations/architecture.php @@ -5,7 +5,8 @@ declare(strict_types=1); namespace kodorvan\constructor\models\project\enumerations; // Files of the project -use kodorvan\constructor\models\project\enumerations\purpose; +use kodorvan\constructor\models\project\enumerations\purpose, + kodorvan\constructor\models\project\enumerations\integration; // The library for languages support use mirzaev\languages\language; @@ -169,6 +170,44 @@ enum architecture }; } + /** + * Integrations + * + * @return array Integrations + */ + /* public function integrations(): array + { + // Exit (success) + return match ($this) { + static::chat_robot => [ + integration::one_c, + integration::moy_sklad + ], + static::parser => [ + integration::one_c, + integration::moy_sklad + ], + static::script => [], + static::crm => [ + integration::one_c, + integration::moy_sklad + ], + static::site => [ + integration::one_c, + integration::moy_sklad + ], + static::program => [ + integration::one_c, + integration::moy_sklad + ], + static::complex => [ + integration::one_c, + integration::moy_sklad + ], + default => [] + }; + } */ + /** * Cost * diff --git a/kodorvan/constructor/system/models/project/enumerations/integration.php b/kodorvan/constructor/system/models/project/enumerations/integration.php new file mode 100644 index 0000000..9001f01 --- /dev/null +++ b/kodorvan/constructor/system/models/project/enumerations/integration.php @@ -0,0 +1,99 @@ + + */ +enum integration +{ + case one_c; + case bitrix24; + case moy_sklad; + case telegram; + case mail; + case excel; + + /** + * Label + * + * @param language $language The language + * + * @return string The project form label + */ + public function label(language $language = LANGUAGE_DEFAULT): string + { + // Exit (success) + return match ($this) { + static::one_c => '1C', + static::bitrix24 => match ($language) { + language::en => 'Bitrix 24', + language::ru => 'Битрикс 24' + }, + static::moy_sklad => match ($language) { + language::en => 'Moy Sklad', + language::ru => 'Мой Склад' + }, + static::telegram => match ($language) { + language::en => 'Telegram', + language::ru => 'Телеграм' + }, + static::mail => match ($language) { + language::en => 'Mail', + language::ru => 'Почта' + }, + static::excel => 'Excel' + }; + } + + /** + * Length + * + * @return int Amount of buttons cells length + */ + public function length(): int + { + // Exit (success) + return match ($this) { + static::one_c => 1, + static::bitrix24 => 2, + static::moy_sklad => 2, + static::telegram => 2, + static::mail => 1, + static::excel => 1, + }; + } + + /** + * Coefficient + * + * @return int|float Coefficient to the project development hours + */ + public function coefficient(): int|float + { + // Exit (success) + return match ($this) { + static::one_c => 5, + static::bitrix24 => 3.5, + static::moy_sklad => 3, + static::telegram => 2, + static::mail => 1.2, + static::excel => 1.5, + default => 2 + }; + } +} diff --git a/kodorvan/constructor/system/models/project/enumerations/purpose.php b/kodorvan/constructor/system/models/project/enumerations/purpose.php index 86615cb..9f64af6 100644 --- a/kodorvan/constructor/system/models/project/enumerations/purpose.php +++ b/kodorvan/constructor/system/models/project/enumerations/purpose.php @@ -126,6 +126,85 @@ enum purpose }; } + /** + * Integrations + * + * @return array Integrations + */ + public function integrations(): array + { + // Exit (success) + return match ($this) { + static::funnel => [ + integration::telegram, + integration::mail, + integration::bitrix24 + ], + static::contact => [ + integration::mail, + integration::bitrix24 + ], + static::neural_network => [ + integration::telegram + ], + static::game => [ + integration::telegram + ], + static::gallery => [], + static::crm => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::landing => [ + integration::telegram + ], + static::marketplace => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::charity => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::search => [], + static::calculate => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::logic => [], + static::tools => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::workers => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::objects => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::events => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + static::special => [ + integration::one_c, + integration::moy_sklad, + integration::excel + ], + default => [] + }; + } + /** * Length * diff --git a/kodorvan/constructor/system/models/telegram/conversations/project/create.php b/kodorvan/constructor/system/models/telegram/conversations/project/create.php index a1e2f01..3d428f6 100644 --- a/kodorvan/constructor/system/models/telegram/conversations/project/create.php +++ b/kodorvan/constructor/system/models/telegram/conversations/project/create.php @@ -11,6 +11,7 @@ use kodorvan\constructor\models\core, kodorvan\constructor\models\settings, kodorvan\constructor\models\project\enumerations\architecture as project_architecture, kodorvan\constructor\models\project\enumerations\purpose as project_purpose, + kodorvan\constructor\models\project\enumerations\integration as project_integration, kodorvan\constructor\models\telegram\processes\language\select as process_language_select; // Library for languages support @@ -63,6 +64,13 @@ final class create extends menu */ public project_purpose $purpose; + /** + * Integrations + * + * @var array $integrations The project integrations + */ + public array $integrations = []; + /** * Start * @@ -82,6 +90,9 @@ final class create extends menu $robot->endConversation(); } + // Deleting the message buttons + $this->clearButtons(); + // Initializing the account language $language = $robot->get('language') ?? LANGUAGE_DEFAULT; @@ -115,6 +126,12 @@ final class create extends menu ); } + // Initializing the row + $row = []; + + // Initializing the maximum amount of buttons in a row + $break = 3; + if (isset($this->architecture)) { // Initialized the project architecture @@ -139,29 +156,41 @@ final class create extends menu // Writing the project buttons first row $this->addButtonRow(...$first); - // Initializing the row - $row = []; + // Initializing the project integrations + $integrations = $this->purpose->integrations(); - // Initializing the maximum amount of buttons in a row - $break = 2; - - if (match ($this->architecture) { - project_architecture::chat_robot, - project_architecture::parser, - project_architecture::crm, - project_architecture::site, - project_architecture::program, - project_architecture::complex => true, - default => false - }) { + if (!empty($integrations)) { // Integrations - if (isset($this->integrations)) { - // Initialized the project integrations + // Initializing the button text + $text = unmarkdown( + trim( + implode( + ', ', + array_map( + fn(project_integration $integration) => $localization['project_integration_' . $integration?->name] ?? $integration?->label($language) ?? '', + $this->integrations, + ) + ), + ' ' + ) + ); - } else { - // Not initialized the project integrations + // Writing the project integrations button into the buffer of the first row + $row[] = button::make( + text: empty($text) ? $localization->project_create_button_integrations : $text, + callback_data: '@integrations' + ); + + if (count($row) >= $break) { + // The buttons row reach the limit + + // Writing the buttons row + $this->addButtonRow(...$row); + + // Deinitializing the buttons row + $row = []; } } @@ -474,6 +503,16 @@ final class create extends menu ); } + if (!empty($row)) { + // The buttons row has buttons + + // Writing the buttons row + $this->addButtonRow(...$row); + + // Deinitializing the buttons row + $row = []; + } + if (!$new) { // The project development hours was calculated @@ -490,6 +529,22 @@ final class create extends menu $this->text = $this->orNext('stop')->showMenu()->text; } + /** + * Continue + * + * Generate the project create menu and continue the process + * + * @param telegram $robot The robot + * + * @return void + */ + public function continue(telegram $robot): void + { + // Continuing the process + $this->start(robot: $robot, new: false); + } + + /** * Architectures * @@ -576,7 +631,6 @@ final class create extends menu $generated += $row; // Reinitializing the row buttons length - /* $length -= $break; */ $length = 0; // Reinitializing the row @@ -621,7 +675,7 @@ final class create extends menu } } - if (!empty($row) > 0) { + if (!empty($row)) { // The row was not writed // Writing the row into the menu @@ -636,7 +690,7 @@ final class create extends menu } /** - * architecture + * Architecture * * Write the project architecture * @@ -655,29 +709,8 @@ final class create extends menu // Initializing the project architecture $this->architecture = project_architecture::{$robot->callbackQuery()->data}; - // Initializing the project architecture purposes - $purposes = $this->architecture->purposes(); - - if (empty($purposes)) { - // The project architecture has no purposes - - // Initializing the project purpose - $this->purpose = project_purpose::special; - } else if (count($purposes) === 1) { - // The project architecture has only 1 purpose - - // Initializing the project purpose - $this->purpose = $purposes[0]; - } else if (isset($this->purpose) && array_search($this->purpose, $purposes) !== false) { - // The project architrcture purpose is the same from deprecated purpose - - // keep it - } else { - // - - // Deinitializing the project purpose - unset($this->purpose); - } + // Clearing from deprecated parameters + $this->clear(); // Sending the popup notification $robot->answerCallbackQuery( @@ -788,12 +821,9 @@ final class create extends menu // Addition to row buttons length $length += $purpose->length(); - // Initializing the coefficient - $coefficient = $purpose->coefficient(); - // Writing the purpose button into the row $row[] = button::make( - /* text: ($localization['project_purpose_' . $purpose->name] ?? $purpose->label(language: $language)) . (!empty($coefficient) ? ' x' . $coefficient : ''), */ + /* text: ($localization['project_purpose_' . $purpose->name] ?? $purpose->label(language: $language)) . (!empty($coefficient) ? ' x' . $coeffici🔹ent : ''), */ text: $localization['project_purpose_' . $purpose->name] ?? $purpose->label(language: $language), callback_data: "$purpose->name@purpose" ); @@ -816,9 +846,6 @@ final class create extends menu // Reinitializing the row buttons length $length = 0; - // Initializing the coefficient - $coefficient = $next->coefficient(); - // Writing the button into the menu $this->addButtonRow(button::make( /* text: ($localization['project_purpose_' . $next->name] ?? $next->label(language: $language)) . (!empty($coefficient) ? ' x' . $coefficient : ''), */ @@ -831,7 +858,7 @@ final class create extends menu } } - if (!empty($row) > 0) { + if (!empty($row)) { // The row was not writed // Writing the row into the menu @@ -872,6 +899,9 @@ final class create extends menu // Initializing the project purpose $this->purpose = project_purpose::{$robot->callbackQuery()->data}; + // Clearing from deprecated parameters + $this->clear(); + // Sending the popup notification $robot->answerCallbackQuery( text: $localization['project_purpose_' . $this->purpose?->name] ?? $this->purpose?->label(language: $language), @@ -885,6 +915,220 @@ final class create extends menu $this->start(robot: $robot, new: false); } + /** + * Integrations + * + * Generate the project integrations select menu + * + * @param telegram $robot The robot + * + * @return void + */ + public function integrations(telegram $robot): void + { + // Initializing the account language + $language = $robot->get('language') ?? LANGUAGE_DEFAULT; + + // Initializing the account localization + $localization = $robot->get('localization') ?? new localization($language); + + // Initializing the account + $account = $robot->get('account'); + + // Updating the message text + $this->menuText( + text: implode( + "\n\n", + [ + "📡 *$localization->project_create_integrations_title*", + $localization->project_create_integrations_description, + ] + ), + opt: [ + 'parse_mode' => mode::MARKDOWN + ] + ); + + // Deleting the message buttons + $this->clearButtons(); + + // Initializing the row + $row = []; + + // Declaring the buffer of the row buttons length + $length = 0; + + // Initializing the maximum amount of buttons in a row + $break = 4; + + // Initializing buffer of integrations + $integrations = $this->purpose->integrations(); + + // Declaring the generated buttons registry + $generated = []; + + foreach ($integrations as $index => $integration) { + // Iterating over integrations + + if ($length + $integration->length() > $break && !empty($row)) { + // Reached the limit of buttons in a row + + // Writing the row into the menu + $this->addButtonRow(...$row); + + // Writing buttons into the generated buttons registry + $generated += $row; + + // Reinitializing the row buttons length + $length = 0; + + // Reinitializing the row + $row = []; + } + + // Addition to row buttons length + $length += $integration->length(); + + // Initializing the target + $target = $this->integrations[$integration->name] ?? null; + + // Writing the integration button into the row + $row[] = button::make( + text: (isset($target) && $target ? '🔹' : '') . ($localization['project_integration_' . $integration->name] ?? $integration->label(language: $language)), + callback_data: "$integration->name@integration" + ); + + // Initializing the next integration + $next = $integrations[$index + 1] ?? null; + + if ($next?->length() >= $break) { + // The next integration is the full-length button + + // Writing the row into the menu + $this->addButtonRow(...$row); + + // Writing buttons into the generated buttons registry + $generated += $row; + + // Reinitializing the row + $row = []; + + // Reinitializing the row buttons length + $length = 0; + + // Initializing the target + $target = $this->integrations[$integration->name] ?? null; + + // Writing the button into the menu + $this->addButtonRow(button::make( + text: (isset($target) && $target ? '🔹' : '') . ($localization['project_integration_' . $integration->name] ?? $integration->label(language: $language)), + callback_data: "$integration->name@integration" + )); + + // Writing the button into the generated buttons registry + $generated[] = $next; + } + } + + if (!empty($row) > 0) { + // The row was not writed + + // Writing the row into the menu + $this->addButtonRow(...$row); + } + + // Writing the "back" button into the menu + $this->addButtonRow(button::make( + text: "🔏 $localization->project_create_button_back", + callback_data: '@continue' + )); + + // Deinitializing deprecated variables + unset($row, $limit, $length, $generated, $integrations, $integration); + + // Updating the message and saving its text + $this->text = $this->showMenu()->text; + } + + /** + * Integration + * + * Write the project integration + * + * @param telegram $robot The robot + * + * @return void + */ + public function integration(telegram $robot): void + { + // Initializing the account language + $language = $robot->get('language') ?? LANGUAGE_DEFAULT; + + // Initializing the account localization + $localization = $robot->get('localization') ?? new localization($language); + + // Initializing the integration + $integration = project_integration::{$robot->callbackQuery()->data}; + + if (isset($this->integrations[$integration->name])) { + // Enabled + + // Disabling + unset($this->integrations[$integration->name]); + } else { + // Disabled + + // Enabling + $this->integrations[$integration->name] = $integration; + }; + + // Sending the popup notification + $robot->answerCallbackQuery( + text: $localization['project_integrations_' . (isset($this->integrations[$integration->name]) ? 'enabled' : 'disabled')], + show_alert: false + ); + + // Deleting the message buttons + $this->integrations(robot: $robot); + } + + /** + * Clear + * + * Deinitialize all deprecated parameters + * + * @return void + */ + public function clear(): void + { + // Initializing the project architecture purposes + $purposes = $this->architecture->purposes(); + + if (empty($purposes)) { + // The project architecture has no purposes + + // Initializing the project purpose + $this->purpose = project_purpose::special; + } else if (count($purposes) === 1) { + // The project architecture has only 1 purpose + + // Initializing the project purpose + $this->purpose = $purposes[0]; + } else if (isset($this->purpose) && array_search($this->purpose, $purposes) !== false) { + // The project architrcture purpose is the same from deprecated purpose + + // keep it + } else { + // The project can have other purposes + + // Deinitializing the deprecated project purpose + unset($this->purpose); + } + + // Deinitializing integrations + $this->integrations = []; + } + /** * Hours * @@ -910,6 +1154,17 @@ final class create extends menu $coefficient += $this->purpose->coefficient(); } + if (!empty($this->integrations)) { + // Initialized the project integrations + + foreach ($this->integrations as $integration) { + // Iterating over the project integrations + + // Adding into the coefficient + $coefficient += $integration->coefficient(); + } + } + // Initializing start hours $start = PROJECT_CREATE_START_HOURS ?? 1; $start < 1 and $start = 1;