Update calculations for project duration

This commit is contained in:
David Bomba 2024-08-03 07:45:37 +10:00
parent dfff937031
commit 83fe0521ca
8 changed files with 80 additions and 120 deletions

View File

@ -15,7 +15,6 @@ use App\Jobs\Cron\AutoBillCron;
use App\Jobs\Cron\RecurringExpensesCron;
use App\Jobs\Cron\RecurringInvoicesCron;
use App\Jobs\Cron\SubscriptionCron;
use App\Jobs\Cron\UpdateCalculatedFields;
use App\Jobs\Invoice\InvoiceCheckLateWebhook;
use App\Jobs\Ninja\AdjustEmailQuota;
use App\Jobs\Ninja\BankTransactionSync;
@ -68,9 +67,6 @@ class Kernel extends ConsoleKernel
/* Stale Invoice Cleanup*/
$schedule->job(new CleanStaleInvoiceOrder())->hourlyAt(30)->withoutOverlapping()->name('stale-invoice-job')->onOneServer();
/* Stale Invoice Cleanup*/
$schedule->job(new UpdateCalculatedFields())->hourlyAt(40)->withoutOverlapping()->name('update-calculated-fields-job')->onOneServer();
/* Checks for large companies and marked them as is_large */
$schedule->job(new CompanySizeCheck())->dailyAt('23:20')->withoutOverlapping()->name('company-size-job')->onOneServer();

View File

@ -1,105 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Jobs\Cron;
use App\Libraries\MultiDB;
use App\Models\Project;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Auth;
class UpdateCalculatedFields
{
use Dispatchable;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle(): void
{
nlog("Updating calculated fields");
Auth::logout();
if (! config('ninja.db.multi_db_enabled')) {
Project::query()->with('tasks')->whereHas('tasks', function ($query) {
$query->where('updated_at', '>', now()->subHours(2));
})
->cursor()
->each(function ($project) {
$project->current_hours = $this->calculateDuration($project);
$project->save();
});
} else {
//multiDB environment, need to
foreach (MultiDB::$dbs as $db) {
MultiDB::setDB($db);
Project::query()->with('tasks')->whereHas('tasks', function ($query) {
$query->where('updated_at', '>', now()->subHours(2));
})
->cursor()
->each(function ($project) {
$project->current_hours = $this->calculateDuration($project);
$project->save();
});
//Clean password resets table
\DB::connection($db)->table('password_resets')->where('created_at', '<', now()->subHour())->delete();
}
}
}
private function calculateDuration($project): int
{
$duration = 0;
$project->tasks->each(function ($task) use (&$duration) {
if(is_iterable(json_decode($task->time_log))) {
foreach(json_decode($task->time_log) as $log) {
if(!is_array($log))
continue;
$start_time = $log[0];
$end_time = $log[1] == 0 ? time() : $log[1];
$duration += $end_time - $start_time;
}
}
});
return (int) round(($duration / 60 / 60), 0);
}
}

View File

@ -95,6 +95,8 @@ class CleanStaleInvoiceOrder implements ShouldQueue
->each(function ($invoice) {
$invoice->service()->removeUnpaidGatewayFees();
});
\DB::connection($db)->table('password_resets')->where('created_at', '<', now()->subHours(12))->delete();
}
}

View File

@ -137,7 +137,7 @@ class Task extends BaseModel
// 'project',
];
protected $touches = [];
protected $touches = ['project'];
public function getEntityType()
{

View File

@ -82,6 +82,7 @@ class TaskObserver
if ($subscriptions) {
WebhookHandler::dispatch(Webhook::EVENT_ARCHIVE_TASK, $task, $task->company)->delay(0);
}
}
/**

View File

@ -586,10 +586,6 @@ class BaseDriver extends AbstractPaymentDriver
$invoices = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->get();
// $invoices->each(function ($invoice) {
// $invoice->service()->deletePdf();
// });
$invoices->first()->invitations->each(function ($invitation) use ($nmo) {
if ((bool) $invitation->contact->send_email !== false && $invitation->contact->email) {
$nmo->to_user = $invitation->contact;

View File

@ -72,9 +72,9 @@ class Client extends HttpClient
$response = $this->httpClient->sendRequest( $this->requestFactory->createRequest($method, $uri, $headers, $body, $protocolVersion));
else $response = $this->httpClient->request($method, $uri, compact('body','headers'));
} catch (\Http\Client\Exception\NetworkException $networkException) {
throw new NetworkException($networkException->getMessage(), $request, $networkException);
throw new \Exception($networkException->getMessage());
} catch (\Exception $exception) {
throw new RequestException($exception->getMessage(), $request, $exception);
throw new \Exception($exception->getMessage());
}
return $response;

View File

@ -46,16 +46,16 @@ class TaskRepository extends BaseRepository
$this->new_task = false;
}
if(isset($data['assigned_user_id']) && $data['assigned_user_id'] != $task->assigned_user_id){
TaskAssigned::dispatch($task, $task->company->db)->delay(2);
}
if(!is_numeric($task->rate) && !isset($data['rate']))
$data['rate'] = 0;
$task->fill($data);
$task->saveQuietly();
if(isset($data['assigned_user_id']) && $data['assigned_user_id'] != $task->assigned_user_id) {
TaskAssigned::dispatch($task, $task->company->db)->delay(2);
}
$this->init($task);
if ($this->new_task && ! $task->status_id) {
@ -155,6 +155,8 @@ class TaskRepository extends BaseRepository
$this->saveDocuments($data['documents'], $task);
}
$this->calculateProjectDuration($task);
return $task;
}
@ -261,6 +263,8 @@ class TaskRepository extends BaseRepository
$task->saveQuietly();
}
$this->calculateProjectDuration($task);
return $task;
}
@ -302,7 +306,10 @@ class TaskRepository extends BaseRepository
$task->saveQuietly();
}
$this->calculateProjectDuration($task);
return $task;
}
public function triggeredActions($request, $task)
@ -348,4 +355,67 @@ class TaskRepository extends BaseRepository
return $task->number;
}
private function calculateProjectDuration(Task $task)
{
if($task->project) {
$duration = 0;
$task->project->tasks->each(function ($task) use (&$duration) {
if(is_iterable(json_decode($task->time_log))) {
foreach(json_decode($task->time_log) as $log) {
if(!is_array($log)) {
continue;
}
$start_time = $log[0];
$end_time = $log[1] == 0 ? time() : $log[1];
$duration += $end_time - $start_time;
}
}
});
$task->project->current_hours = (int) round(($duration / 60 / 60), 0);
$task->push();
}
}
/**
* @param $entity
*/
public function restore($task)
{
if (!$task->trashed()) {
return;
}
parent::restore($task);
$this->calculateProjectDuration($task);
}
/**
* @param $entity
*/
public function delete($task)
{
if ($task->is_deleted) {
return;
}
parent::delete($task);
$this->calculateProjectDuration($task);
}
}