1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 20:52:56 +01:00

Notify user on assignment of task

This commit is contained in:
David Bomba 2024-06-19 13:57:50 +10:00
parent cb9e40d442
commit 45b43094b0
10 changed files with 103 additions and 56 deletions

View File

@ -186,7 +186,7 @@ class TransactionTransformer implements BankRevenueInterface
}
try {
return Carbon::createFromFormat("d-m-Y", $input)->setTimezone($timezone_name)->format($date_format_default) ?? $input;
return Carbon::createFromFormat("d-m-Y", $input)->setTimezone($timezone_name)->format($date_format_default);
} catch (\Exception $e) {
return $input;
}

View File

@ -70,9 +70,9 @@ class ProRata
}
/** @var \App\Models\RecurringInvoice $recurring_invoice **/
$recurring_invoice = RecurringInvoice::find($invoice->recurring_id)->first();
$recurring_invoice = RecurringInvoice::find($invoice->recurring_id);
if (! $recurring_invoice) {
if (! $recurring_invoice) { // @phpstan-ignore-line
throw new \Exception("Invoice isn't attached to a recurring invoice");
}

View File

@ -24,7 +24,6 @@ class PreviewPurchaseOrderRequest extends Request
use CleanLineItems;
private ?Vendor $vendor = null;
private string $entity_plural = '';
/**
* Determine if the user is authorized to make this request.
@ -72,7 +71,7 @@ class PreviewPurchaseOrderRequest extends Request
{
$invitation = false;
if(! $this->entity_id ?? false) {
if(! isset($this->entity_id)) {
return $this->stubInvitation();
}
@ -130,12 +129,5 @@ class PreviewPurchaseOrderRequest extends Request
return $entity;
}
private function convertEntityPlural(string $entity): self
{
$this->entity_plural = 'purchase_orders';
return $this;
}
}

View File

@ -0,0 +1,71 @@
<?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\Task;
use App\Models\Task;
use App\Libraries\MultiDB;
use App\Services\Email\Email;
use Illuminate\Bus\Queueable;
use App\Services\Email\EmailObject;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Utils\Traits\Notifications\UserNotifies;
class TaskAssigned implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
use UserNotifies;
/**
* Create a new job instance.
*
*/
public function __construct(private Task $task, private string $db)
{
}
public function handle(): void
{
MultiDB::setDb($this->db);
$company_user = $this->task->assignedCompanyUser();
if($this->findEntityAssignedNotification($company_user, 'task'))
{
$mo = new EmailObject();
$mo->subject = ctrans('texts.task_assigned_subject', ['task' => $this->task->number, 'date' => now()->setTimeZone($this->task->company->timezone()->name)->format($this->task->company->date_format()) ]);
$mo->body = ctrans('texts.task_assigned_body',['task' => $this->task->number, 'description' => $this->task->description ?? '', 'client' => $this->task->client ? $this->task->client->present()->name() : ' ']);
$mo->text_body = ctrans('texts.task_assigned_body',['task' => $this->task->number, 'description' => $this->task->description ?? '', 'client' => $this->task->client ? $this->task->client->present()->name() : ' ']);
$mo->company_key = $this->task->company->company_key;
$mo->html_template = 'email.template.generic';
$mo->to = [new Address($this->task->assigned_user->email, $this->task->assigned_user->present()->name())];
$mo->email_template_body = 'task_assigned_body';
$mo->email_template_subject = 'task_assigned_subject';
(new Email($mo, $this->task->company))->handle();
}
}
public function failed($exception = null)
{
}
}

View File

@ -11,10 +11,11 @@
namespace App\Models;
use App\Utils\Traits\MakesHash;
use Carbon\CarbonInterval;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\CompanyUser;
use Illuminate\Support\Carbon;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* App\Models\Task
@ -332,4 +333,11 @@ class Task extends BaseModel
})->toArray();
}
public function assignedCompanyUser()
{
if(!$this->assigned_user_id)
return false;
return CompanyUser::where('company_id', $this->company_id)->where('user_id', $this->assigned_user_id)->first();
}
}

View File

@ -57,28 +57,29 @@ class ClientContactObserver
$clientContact->recurring_invoice_invitations()->delete();
//ensure entity state is preserved
InvoiceInvitation::withTrashed()->where('client_contact_id', $client_contact_id)->cursor()->each(function ($invite) {
if ($invite->invoice()->doesnthave('invitations')) {
/** @var \App\Models\InvoiceInvitation $invite */
if ($invite->invoice()->doesnthave('invitations')) { // @phpstan-ignore-line
$invite->invoice->service()->createInvitations();
}
});
QuoteInvitation::withTrashed()->where('client_contact_id', $client_contact_id)->cursor()->each(function ($invite) {
if ($invite->quote()->doesnthave('invitations')) {
if ($invite->quote()->doesnthave('invitations')) { // @phpstan-ignore-line
$invite->quote->service()->createInvitations();
}
});
RecurringInvoiceInvitation::withTrashed()->where('client_contact_id', $client_contact_id)->cursor()->each(function ($invite) {
if ($invite->recurring_invoice()->doesnthave('invitations')) {
if ($invite->recurring_invoice()->doesnthave('invitations')) {// @phpstan-ignore-line
$invite->recurring_invoice->service()->createInvitations();
}
});
CreditInvitation::withTrashed()->where('client_contact_id', $client_contact_id)->cursor()->each(function ($invite) {
if ($invite->credit()->doesnthave('invitations')) {
if ($invite->credit()->doesnthave('invitations')) {// @phpstan-ignore-line
$invite->credit->service()->createInvitations();
}
});

View File

@ -54,7 +54,6 @@ class TaskObserver
$event = Webhook::EVENT_DELETE_TASK;
}
$subscriptions = Webhook::where('company_id', $task->company_id)
->where('event_id', $event)
->exists();

View File

@ -12,6 +12,7 @@
namespace App\Repositories;
use App\Factory\TaskFactory;
use App\Jobs\Task\TaskAssigned;
use App\Models\Task;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Database\QueryException;
@ -45,6 +46,10 @@ 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);
}
$task->fill($data);
$task->saveQuietly();

View File

@ -164,4 +164,9 @@ trait UserNotifies
return count(array_intersect($required_notification, $company_user->notifications->email)) >= 1;
}
public function findEntityAssignedNotification(\App\Models\CompanyUser $company_user, string $entity)
{
return count(array_intersect(["{$entity}_assigned"], $company_user->notifications->email)) >= 1;
}
}

View File

@ -2880,19 +2880,6 @@ $lang = array(
'refunded' => 'Refunded',
'marked_quote_as_sent' => 'Successfully marked quote as sent',
'custom_module_settings' => 'Custom Module Settings',
'ticket' => 'Ticket',
'tickets' => 'Tickets',
'ticket_number' => 'Ticket #',
'new_ticket' => 'New Ticket',
'edit_ticket' => 'Edit Ticket',
'view_ticket' => 'View Ticket',
'archive_ticket' => 'Archive Ticket',
'restore_ticket' => 'Restore Ticket',
'delete_ticket' => 'Delete Ticket',
'archived_ticket' => 'Successfully archived ticket',
'archived_tickets' => 'Successfully archived tickets',
'restored_ticket' => 'Successfully restored ticket',
'deleted_ticket' => 'Successfully deleted ticket',
'open' => 'Open',
'new' => 'New',
'closed' => 'Closed',
@ -2909,14 +2896,6 @@ $lang = array(
'assigned_to' => 'Assigned to',
'reply' => 'Reply',
'awaiting_reply' => 'Awaiting reply',
'ticket_close' => 'Close Ticket',
'ticket_reopen' => 'Reopen Ticket',
'ticket_open' => 'Open Ticket',
'ticket_split' => 'Split Ticket',
'ticket_merge' => 'Merge Ticket',
'ticket_update' => 'Update Ticket',
'ticket_settings' => 'Ticket Settings',
'updated_ticket' => 'Ticket Updated',
'mark_spam' => 'Mark as Spam',
'local_part' => 'Local Part',
'local_part_unavailable' => 'Name taken',
@ -2936,29 +2915,14 @@ $lang = array(
'mime_types_help' => 'Comma separated list of allowed mime types, leave blank for all',
'default_priority' => 'Default priority',
'alert_new_comment_id' => 'New comment',
'alert_comment_ticket_help' => 'Selecting a template will send a notification (to agent) when a comment is made.',
'alert_comment_ticket_email_help' => 'Comma separated emails to bcc on new comment.',
'new_ticket_notification_list' => 'Additional new ticket notifications',
'update_ticket_notification_list' => 'Additional new comment notifications',
'comma_separated_values' => 'admin@example.com, supervisor@example.com',
'alert_ticket_assign_agent_id' => 'Ticket assignment',
'alert_ticket_assign_agent_id_hel' => 'Selecting a template will send a notification (to agent) when a ticket is assigned.',
'alert_ticket_assign_agent_id_notifications' => 'Additional ticket assigned notifications',
'alert_ticket_assign_agent_id_help' => 'Comma separated emails to bcc on ticket assignment.',
'alert_ticket_transfer_email_help' => 'Comma separated emails to bcc on ticket transfer.',
'alert_ticket_overdue_agent_id' => 'Ticket overdue',
'alert_ticket_overdue_email' => 'Additional overdue ticket notifications',
'alert_ticket_overdue_email_help' => 'Comma separated emails to bcc on ticket overdue.',
'alert_ticket_overdue_agent_id_help' => 'Selecting a template will send a notification (to agent) when a ticket becomes overdue.',
'default_agent' => 'Default Agent',
'default_agent_help' => 'If selected will automatically be assigned to all inbound tickets',
'show_agent_details' => 'Show agent details on responses',
'avatar' => 'Avatar',
'remove_avatar' => 'Remove avatar',
'ticket_not_found' => 'Ticket not found',
'add_template' => 'Add Template',
'updated_ticket_template' => 'Updated Ticket Template',
'created_ticket_template' => 'Created Ticket Template',
'archive_ticket_template' => 'Archive Template',
'restore_ticket_template' => 'Restore Template',
'archived_ticket_template' => 'Successfully archived template',
@ -5303,6 +5267,8 @@ $lang = array(
'currency_bhutan_ngultrum' => 'Bhutan Ngultrum',
'end_of_month' => 'End Of Month',
'merge_e_invoice_to_pdf' => 'Merge E-Invoice and PDF',
'task_assigned_subject' => 'New task assignment [Task :task] [ :date ]',
'task_assigned_body' => 'You have been assigned task :task <br><br> Description: :description <br><br> Client: :client',
);
return $lang;