To implement the logic you've described, you should use both Laravel Jobs and Schedules. Here's why and how:
-
Laravel Jobs: Use jobs to handle the immediate actions that need to occur when an investment is approved, such as updating the status, setting the start and end dates, and sending an email to the user. Jobs are also useful for handling the profit addition at each interval because they can be dispatched at any time and can be delayed to run at a specific time in the future.
-
Laravel Schedules: Use the task scheduler to periodically check for investments that need to have their profits added based on their term. The scheduler can run a command every minute that checks for any investments that need updating and dispatches jobs accordingly.
Here's an example of how you might implement this:
First, create a new job to handle the profit addition:
php artisan make:job AddInvestmentProfit
In the AddInvestmentProfit job, you would have something like this:
public function handle()
{
// Logic to add the term profit to the user's balance
// Check if the investment end date has been reached
// If so, update the investment status to completed
}
Next, you would dispatch this job within your approve method at the appropriate intervals:
use Illuminate\Support\Facades\Bus;
public function approve(Investment $investment)
{
// ... existing code ...
// Dispatch the job to run at the investment's interval
switch ($investment->term) {
case 'hourly':
$delay = now()->addHour();
break;
case 'daily':
$delay = now()->addDay();
break;
// Add cases for 'weekly', 'monthly', 'yearly'
default:
throw new Exception("Invalid investment term!", 1);
}
Bus::chain([
new AddInvestmentProfit($investment),
// You can chain multiple jobs if needed
])->delay($delay)->dispatch();
return back()->with('success-form', 'Investment activated');
}
Finally, you would set up a scheduled task in app/Console/Kernel.php to dispatch jobs for investments that need their profits added:
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
// Get investments that need their profits added
$investments = Investment::where('status', InvestmentStatus::ACTIVE)
->where('end_date', '>', now())
->get();
foreach ($investments as $investment) {
// Calculate the next profit addition time based on the term
// Dispatch the AddInvestmentProfit job if it's time to add profit
}
})->everyMinute(); // Run every minute to check for due investments
}
This setup allows you to handle immediate actions with jobs and use the scheduler to periodically check and dispatch jobs for ongoing tasks like adding profits to investments. Remember to test thoroughly to ensure that the timing and intervals are working as expected.