-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1875 from bakaphp/development
[1.2] Version 1.2
- Loading branch information
Showing
91 changed files
with
1,655 additions
and
424 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 2 additions & 3 deletions
5
app/Console/Commands/AccessControl/UpdateAbilitiesCommand.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
app/Console/Commands/Connectors/Apollo/SyncAllPeopleInCompanyCommand.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Console\Commands\Connectors\Apollo; | ||
|
||
use Baka\Traits\KanvasJobsTrait; | ||
use Carbon\Carbon; | ||
use Illuminate\Console\Command; | ||
use Illuminate\Support\Facades\Cache; | ||
use Kanvas\Apps\Models\Apps; | ||
use Kanvas\Companies\Models\Companies; | ||
use Kanvas\Connectors\Apollo\Enums\ConfigurationEnum; | ||
use Kanvas\CustomFields\Models\AppsCustomFields; | ||
use Kanvas\Guild\Customers\Models\People; | ||
use Kanvas\Workflow\Enums\WorkflowEnum; | ||
|
||
class SyncAllPeopleInCompanyCommand extends Command | ||
{ | ||
use KanvasJobsTrait; | ||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'kanvas:guild-apollo-people-sync {app_id} {company_id} {total=400} {perPage=200}'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string|null | ||
*/ | ||
protected $description = 'Download all leads from Zoho to this branch'; | ||
|
||
/** | ||
* Execute the console command. | ||
* | ||
* @return mixed | ||
*/ | ||
public function handle() | ||
{ | ||
$app = Apps::getById((int) $this->argument('app_id')); | ||
$perPage = (int) $this->argument('perPage'); | ||
$total = (int) $this->argument('total'); | ||
$this->overwriteAppService($app); | ||
$company = Companies::getById((int) $this->argument('company_id')); | ||
|
||
$hourlyRateLimit = 400; // Maximum API calls per hour | ||
$dailyRateLimit = 2000; // Maximum API calls per day | ||
$batchSize = 100; // Number of people to process per batch | ||
$hourlyCacheKey = 'api_hourly_rate_limit_' . $app->getId(); | ||
$dailyCacheKey = 'api_daily_rate_limit_' . $app->getId(); | ||
$resetHourlyKey = 'api_hourly_rate_limit_reset_' . $app->getId(); | ||
$resetDailyKey = 'api_daily_rate_limit_reset_' . $app->getId(); | ||
$hourlyTimeWindow = 60 * 60; // 1 hour in seconds | ||
$dailyTimeWindow = 24 * 60 * 60; // 24 hours in seconds | ||
|
||
// Check the current count of API calls | ||
$currentHourlyCount = Cache::get($hourlyCacheKey, 0); | ||
$currentDailyCount = Cache::get($dailyCacheKey, 0); | ||
$resetHourlyTimestamp = Cache::get($resetHourlyKey); | ||
$resetDailyTimestamp = Cache::get($resetDailyKey); | ||
|
||
$this->line('Syncing ' . $currentHourlyCount . ' people in company ' . $company->name . ' from app ' . $app->name . ' total ' . $total . ' per page ' . $perPage); | ||
|
||
if ($resetHourlyTimestamp) { | ||
$resetHourlyTime = Carbon::parse($resetHourlyTimestamp); | ||
$currentTimestamp = now()->timestamp; | ||
$hourlyWaitTime = $resetHourlyTime->timestamp - $currentTimestamp; | ||
|
||
if ($currentHourlyCount >= $hourlyRateLimit && $hourlyWaitTime > 0) { | ||
$this->line("Hourly rate limit reached. Please wait $hourlyWaitTime seconds to run the process again."); | ||
|
||
return; | ||
} | ||
} | ||
|
||
if ($resetDailyTimestamp) { | ||
$resetDailyTime = Carbon::parse($resetDailyTimestamp); | ||
$currentTimestamp = now()->timestamp; | ||
$dailyWaitTime = $resetDailyTime->timestamp - $currentTimestamp; | ||
|
||
if ($currentDailyCount >= $dailyRateLimit && $dailyWaitTime > 0) { | ||
$this->line("Daily rate limit reached. Please wait $dailyWaitTime seconds to run the process again."); | ||
|
||
return; | ||
} | ||
} | ||
|
||
People::fromApp($app) | ||
->fromCompany($company) | ||
->leftJoinSub( | ||
AppsCustomFields::select('entity_id') | ||
->where('name', ConfigurationEnum::APOLLO_DATA_ENRICHMENT_CUSTOM_FIELDS->value), | ||
'acf', | ||
'peoples.id', | ||
'=', | ||
'acf.entity_id' | ||
) | ||
->whereNull('acf.entity_id') | ||
->orderBy('peoples.id', 'asc') | ||
->chunk($batchSize, function ($peoples) use (&$currentHourlyCount, &$currentDailyCount, $hourlyRateLimit, $dailyRateLimit, $hourlyCacheKey, $dailyCacheKey, $resetHourlyKey, $resetDailyKey, $hourlyTimeWindow, $dailyTimeWindow) { | ||
foreach ($peoples as $people) { | ||
if ($currentHourlyCount >= $hourlyRateLimit) { | ||
Cache::put($resetHourlyKey, now()->addSeconds($hourlyTimeWindow), $hourlyTimeWindow); | ||
$this->line("Hourly rate limit reached. Please wait $hourlyTimeWindow seconds to run the process again."); | ||
|
||
return false; | ||
} | ||
|
||
if ($currentDailyCount >= $dailyRateLimit) { | ||
Cache::put($resetDailyKey, now()->addSeconds($dailyTimeWindow), $dailyTimeWindow); | ||
$this->line("Daily rate limit reached. Please wait $dailyTimeWindow seconds to run the process again."); | ||
|
||
return false; | ||
} | ||
|
||
$this->line('Syncing people ' . $people->id . ' ' . $people->firstname . ' ' . $people->lastname); | ||
|
||
$people->fireWorkflow( | ||
WorkflowEnum::UPDATED->value, | ||
true, | ||
[ | ||
'app' => $people->app, | ||
] | ||
); | ||
$people->clearLightHouseCacheJob(); | ||
|
||
$currentHourlyCount++; | ||
$currentDailyCount++; | ||
Cache::put($hourlyCacheKey, $currentHourlyCount, $hourlyTimeWindow); | ||
Cache::put($dailyCacheKey, $currentDailyCount, $dailyTimeWindow); | ||
|
||
usleep(100000); // 100ms delay between each request | ||
} | ||
}); | ||
|
||
$this->line('All people in company ' . $company->name . ' from app ' . $app->name . ' synced'); | ||
|
||
return; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
app/Console/Commands/Ecosystem/Notifications/MailAllAppUsersCommand.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Console\Commands\Ecosystem\Notifications; | ||
|
||
use Baka\Enums\StateEnums; | ||
use Baka\Traits\KanvasJobsTrait; | ||
use Illuminate\Console\Command; | ||
use Illuminate\Support\Facades\Notification; | ||
use Kanvas\Apps\Models\Apps; | ||
use Kanvas\Enums\AppEnums; | ||
use Kanvas\Notifications\Templates\Blank; | ||
use Kanvas\Users\Models\UsersAssociatedApps; | ||
use Kanvas\Users\Models\Users; | ||
|
||
class MailAllAppUsersCommand extends Command | ||
{ | ||
use KanvasJobsTrait; | ||
|
||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'kanvas:mail-notification-to-all-app-users {apps_id} {email_template_name} {subject}'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'send specific email to all users of an app'; | ||
|
||
/** | ||
* Execute the console command. | ||
*/ | ||
public function handle() | ||
{ | ||
$app = Apps::getById((int) $this->argument('apps_id')); | ||
$this->overwriteAppService($app); | ||
|
||
$users = UsersAssociatedApps::fromApp($app) | ||
->where('is_delete', StateEnums::NO) | ||
->where('companies_id', AppEnums::GLOBAL_COMPANY_ID->getValue()) | ||
->chunk(100, function ($users) use ($app) { | ||
foreach ($users as $user) { | ||
$notification = new Blank( | ||
$this->argument('email_template_name'), | ||
['userFirstname' => $user->firstname], | ||
['mail'], | ||
$user | ||
); | ||
$notification->setSubject($this->argument('subject')); | ||
Notification::route('mail', $user->email)->notify($notification); | ||
$this->info('Email Successfully sent to: ' . $user->getId() . ' on app: ' . $app->getId()); | ||
$this->newLine(); | ||
} | ||
}); | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
app/Console/Commands/Ecosystem/Notifications/UserEngagementReminderCommand.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Console\Commands\Ecosystem\Notifications; | ||
|
||
use Baka\Enums\StateEnums; | ||
use Baka\Traits\KanvasJobsTrait; | ||
use Carbon\Carbon; | ||
use Illuminate\Console\Command; | ||
use Illuminate\Support\Facades\DB; | ||
use Illuminate\Support\Facades\Notification; | ||
use Kanvas\Apps\Models\Apps; | ||
use Kanvas\Enums\AppEnums; | ||
use Kanvas\Notifications\Templates\Blank; | ||
use Kanvas\Users\Models\UsersAssociatedApps; | ||
|
||
class UserEngagementReminderCommand extends Command | ||
{ | ||
use KanvasJobsTrait; | ||
|
||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'kanvas:users-engagement-reminder {app_id?} '; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string|null | ||
*/ | ||
protected $description = 'Simple daily email reminder to get users to engage with the app again'; | ||
|
||
public function handle(): void | ||
{ | ||
$app = Apps::getById($this->argument('app_id')); | ||
$this->overwriteAppService($app); | ||
|
||
$this->info('Sending User Engagement Reminder for app ' . $app->name . ' - ' . date('Y-m-d')); | ||
//get the list of user form UsersAssociatedApps chuck by 100 records | ||
DB::table('users_associated_apps') | ||
->where('apps_id', $app->id) // Assuming 'app_id' is the foreign key | ||
->where('is_deleted', StateEnums::NO->getValue()) | ||
->where('companies_id', AppEnums::GLOBAL_COMPANY_ID->getValue()) | ||
->orderBy('users_id') // Order by primary or unique key for consistency | ||
->chunk(100, function ($users) use ($app) { | ||
$users = UsersAssociatedApps::hydrate($users->toArray()); | ||
foreach ($users as $user) { | ||
$this->sendEmail($user, $app); | ||
} | ||
}); | ||
} | ||
|
||
public function sendEmail(UsersAssociatedApps $user, Apps $app): void | ||
{ | ||
//send email to user | ||
$this->info('Sending email to user ' . $user->email); | ||
|
||
$lastVisitInDays = Carbon::parse($user->lastvisit)->diffInDays(Carbon::now()); | ||
$this->info('Last visit in days ' . $lastVisitInDays); | ||
|
||
$engagementEmailTemplateConfiguration = $app->get('engagement_email_template') ?? []; | ||
|
||
if (empty($engagementEmailTemplateConfiguration)) { | ||
$this->info('No email template configuration found'); | ||
|
||
return; | ||
} | ||
|
||
if (empty($engagementEmailTemplateConfiguration[$lastVisitInDays])) { | ||
$this->info('No email template configuration found for ' . $lastVisitInDays . ' days'); | ||
|
||
return; | ||
} | ||
|
||
$emailTemplate = $engagementEmailTemplateConfiguration[$lastVisitInDays]; | ||
|
||
if (! isset($emailTemplate['template'])) { | ||
$this->info('No email template found for ' . $lastVisitInDays . ' days'); | ||
|
||
return; | ||
} | ||
|
||
$notification = new Blank( | ||
$emailTemplate['template'], | ||
[ | ||
'app' => $app, | ||
'user' => $user->user, | ||
'config' => $emailTemplate, | ||
], | ||
['mail'], | ||
$user | ||
); | ||
|
||
Notification::route('mail', $user->email)->notify($notification); | ||
//@todo save it in user activity log on social? | ||
$this->info('Email sent to ' . $user->email); | ||
} | ||
} |
Oops, something went wrong.