Skip to content

Commit

Permalink
Merge pull request #1875 from bakaphp/development
Browse files Browse the repository at this point in the history
[1.2] Version 1.2
  • Loading branch information
kaioken authored Sep 6, 2024
2 parents c1cdc56 + 833f641 commit f9cf1de
Show file tree
Hide file tree
Showing 91 changed files with 1,655 additions and 424 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ RABBITMQ_HOST=rabbitmq
LIGHTHOUSE_CACHE_ENABLE=false
LIGHTHOUSE_SCHEMA_CACHE_ENABLE=false
LIGHTHOUSE_CACHE_VERSION=2
LIGHTHOUSE_SUBSCRIPTION_STORAGE_TTL=3600

#SEACH CONFIGURATION
SCOUT_DRIVER=meilisearch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Console\Commands;
namespace App\Console\Commands\AccessControl;

use Illuminate\Console\Command;
use Kanvas\AccessControlList\Actions\CreateRoleAction;
Expand Down
5 changes: 2 additions & 3 deletions app/Console/Commands/AccessControl/UpdateAbilitiesCommand.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<?php

declare(strict_types=1);

namespace App\Console\Commands\AccessControl;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
use Kanvas\AccessControlList\Actions\CreateAbilitiesByModule;
use Kanvas\Apps\Models\Apps;
use Kanvas\AccessControlList\Enums\ModuleEnum;
use Kanvas\AccessControlList\Repositories\RolesRepository;

class UpdateAbilitiesCommand extends Command
{
Expand Down
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Console\Commands;
namespace App\Console\Commands\Ecosystem\Companies;

use Illuminate\Console\Command;
use Kanvas\Companies\Actions\DeleteCompaniesAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Console\Commands;
namespace App\Console\Commands\Ecosystem;

use Illuminate\Console\Command;
use Kanvas\Apps\Actions\CreateAppKeyAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Console\Commands;
namespace App\Console\Commands\Ecosystem;

use Baka\Users\Contracts\UserInterface;
use Illuminate\Console\Command;
Expand Down
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();
}
});
}
}
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);
}
}
Loading

0 comments on commit f9cf1de

Please sign in to comment.