diff --git a/app/Http/Controllers/ClientPortal/RecurringInvoiceController.php b/app/Http/Controllers/ClientPortal/RecurringInvoiceController.php index d610d4515f82..037444c3e9e5 100644 --- a/app/Http/Controllers/ClientPortal/RecurringInvoiceController.php +++ b/app/Http/Controllers/ClientPortal/RecurringInvoiceController.php @@ -51,6 +51,7 @@ class RecurringInvoiceController extends Controller * * @param ShowRecurringInvoiceRequest $request * @param RecurringInvoice $recurring_invoice + * * @return Factory|View */ public function show(ShowRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice) @@ -60,20 +61,24 @@ class RecurringInvoiceController extends Controller ]); } + /** + * Handle the request cancellation notification + * + * @param RequestCancellationRequest $request [description] + * @param RecurringInvoice $recurring_invoice [description] + * + * @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse + */ public function requestCancellation(RequestCancellationRequest $request, RecurringInvoice $recurring_invoice) { - nlog('outside cancellation'); if ($recurring_invoice->subscription?->allow_cancellation) { - nlog('inside the cancellation'); $nmo = new NinjaMailerObject; - $nmo->mailable = (new NinjaMailer((new ClientContactRequestCancellationObject($recurring_invoice, auth()->user()))->build())); + $nmo->mailable = (new NinjaMailer((new ClientContactRequestCancellationObject($recurring_invoice, auth()->user(), false))->build())); $nmo->company = $recurring_invoice->company; $nmo->settings = $recurring_invoice->company->settings; - // $notifiable_users = $this->filterUsersByPermissions($recurring_invoice->company->company_users, $recurring_invoice, ['recurring_cancellation']); - $recurring_invoice->company->company_users->each(function ($company_user) use ($nmo) { $methods = $this->findCompanyUserNotificationType($company_user, ['recurring_cancellation', 'all_notifications']); @@ -86,15 +91,6 @@ class RecurringInvoiceController extends Controller } }); - // $notifiable_users->each(function ($company_user) use($nmo){ - - // $nmo->to_user = $company_user->user; - // NinjaMailerJob::dispatch($nmo); - - // }); - - //$recurring_invoice->user->notify(new ClientContactRequestCancellation($recurring_invoice, auth()->user())); - return $this->render('recurring_invoices.cancellation.index', [ 'invoice' => $recurring_invoice, ]); diff --git a/app/Jobs/Inventory/AdjustProductInventory.php b/app/Jobs/Inventory/AdjustProductInventory.php index 7846a5ffdc28..79b796398838 100644 --- a/app/Jobs/Inventory/AdjustProductInventory.php +++ b/app/Jobs/Inventory/AdjustProductInventory.php @@ -19,6 +19,7 @@ use App\Mail\Admin\InventoryNotificationObject; use App\Models\Company; use App\Models\Invoice; use App\Models\Product; +use App\Utils\Traits\Notifications\UserNotifies; use App\Utils\Traits\NumberFormatter; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; @@ -29,7 +30,7 @@ use Illuminate\Queue\SerializesModels; class AdjustProductInventory implements ShouldQueue { - use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies; public Company $company; @@ -146,8 +147,22 @@ class AdjustProductInventory implements ShouldQueue $nmo->mailable = new NinjaMailer((new InventoryNotificationObject($product, $notification_level))->build()); $nmo->company = $this->company; $nmo->settings = $this->company->settings; + + // $product->company_users->each(function ($cu) use($product, $nmo){ + + // if($this->checkNotificationExists($cu, $product, ['inventory_all', 'inventory_user'])) + // { + + // $nmo->to_user = $cu->user; + // (new NinjaMailerJob($nmo))->handle(); + + // } + + // }); + $nmo->to_user = $this->company->owner(); - NinjaMailerJob::dispatch($nmo); + (new NinjaMailerJob($nmo))->handle(); + } } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 0fcb71899d71..d3698908bd86 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -526,7 +526,7 @@ class InvoiceService $this->invoice->exchange_rate = $this->invoice->client->currency()->exchange_rate; } - if ($settings->auto_bill_standard_invoices) { + if ($this->invoice->client->getSetting('auto_bill_standard_invoices')) { $this->invoice->auto_bill_enabled = true; } diff --git a/app/Utils/Traits/Notifications/UserNotifies.php b/app/Utils/Traits/Notifications/UserNotifies.php index 1a4baabe7081..d4fd338971b1 100644 --- a/app/Utils/Traits/Notifications/UserNotifies.php +++ b/app/Utils/Traits/Notifications/UserNotifies.php @@ -15,6 +15,7 @@ use App\Models\Client; use App\Models\Credit; use App\Models\Invoice; use App\Models\Payment; +use App\Models\Product; use App\Models\PurchaseOrder; use App\Models\Quote; @@ -41,7 +42,7 @@ trait UserNotifies } //if a user owns this record or is assigned to it, they are attached the permission for notification. - if ($invitation->{$entity_name}->user_id == $company_user->_user_id || $invitation->{$entity_name}->assigned_user_id == $company_user->user_id) { + if ($invitation->{$entity_name}->user_id == $company_user->user_id || $invitation->{$entity_name}->assigned_user_id == $company_user->user_id) { $required_permissions = $this->addSpecialUserPermissionForEntity($invitation->{$entity_name}, $required_permissions); } else { $required_permissions = $this->removeSpecialUserPermissionForEntity($invitation->{$entity_name}, $required_permissions); @@ -67,7 +68,7 @@ trait UserNotifies return []; } - if ($entity->user_id == $company_user->_user_id || $entity->assigned_user_id == $company_user->user_id) { + if ($entity->user_id == $company_user->user_id || $entity->assigned_user_id == $company_user->user_id) { $required_permissions = $this->addSpecialUserPermissionForEntity($entity, $required_permissions); } else { $required_permissions = $this->removeSpecialUserPermissionForEntity($entity, $required_permissions); @@ -87,22 +88,18 @@ trait UserNotifies switch ($entity) { case $entity instanceof Payment || $entity instanceof Client: //we pass client also as this is the proxy for Payment Failures (ie, there is no payment) return array_merge($required_permissions, ['all_notifications', 'all_user_notifications', 'payment_failure_user', 'payment_success_user']); - break; case $entity instanceof Invoice: return array_merge($required_permissions, ['all_notifications', 'all_user_notifications', 'invoice_created_user', 'invoice_sent_user', 'invoice_viewed_user', 'invoice_late_user']); - break; case $entity instanceof Quote: return array_merge($required_permissions, ['all_notifications', 'all_user_notifications', 'quote_created_user', 'quote_sent_user', 'quote_viewed_user', 'quote_approved_user', 'quote_expired_user']); - break; case $entity instanceof Credit: return array_merge($required_permissions, ['all_notifications', 'all_user_notifications', 'credit_created_user', 'credit_sent_user', 'credit_viewed_user']); - break; case $entity instanceof PurchaseOrder: return array_merge($required_permissions, ['all_notifications', 'all_user_notifications', 'purchase_order_created_user', 'purchase_order_sent_user', 'purchase_order_viewed_user']); - break; + case $entity instanceof Product: + return array_merge($required_permissions, ['all_notifications', 'all_user_notifications', 'inventory_user', 'inventory_all']); default: return []; - break; } } @@ -113,19 +110,16 @@ trait UserNotifies switch ($entity) { case $entity instanceof Payment || $entity instanceof Client: //we pass client also as this is the proxy for Payment Failures (ie, there is no payment) return array_diff($required_permissions, ['all_user_notifications', 'payment_failure_user', 'payment_success_user']); - break; case $entity instanceof Invoice: return array_diff($required_permissions, ['all_user_notifications', 'invoice_created_user', 'invoice_sent_user', 'invoice_viewed_user', 'invoice_late_user']); - break; case $entity instanceof Quote: return array_diff($required_permissions, ['all_user_notifications', 'quote_created_user', 'quote_sent_user', 'quote_viewed_user', 'quote_approved_user', 'quote_expired_user']); - break; case $entity instanceof Credit: return array_diff($required_permissions, ['all_user_notifications', 'credit_created_user', 'credit_sent_user', 'credit_viewed_user']); - break; case $entity instanceof PurchaseOrder: return array_diff($required_permissions, ['all_user_notifications', 'purchase_order_created_user', 'purchase_order_sent_user', 'purchase_order_viewed_user']); - break; + case $entity instanceof Product: + return array_diff($required_permissions, ['all_user_notifications', 'inventory_user']); default: // code... break; @@ -165,13 +159,23 @@ trait UserNotifies }); } - private function checkNotificationExists($company_user, $entity, $required_notification) + /** + * Underrated method right here, last ones + * are always the best + * + * @param CompanyUser $company_user + * @param Invoice | Quote | Credit | PurchaseOrder | Product $entity + * @param array $required_notification + * + * @return bool + */ + private function checkNotificationExists($company_user, $entity, $required_notification): bool { /* Always make sure we push the `all_notificaitons` into the mix */ array_push($required_notification, 'all_notifications'); /* Selectively add the all_user if the user is associated with the entity */ - if ($entity->user_id == $company_user->_user_id || $entity->assigned_user_id == $company_user->user_id) { + if ($entity->user_id == $company_user->user_id || $entity->assigned_user_id == $company_user->user_id) { array_push($required_notification, 'all_user_notifications'); } diff --git a/tests/Feature/Notify/NotificationTest.php b/tests/Feature/Notify/NotificationTest.php new file mode 100644 index 000000000000..f82b105ad01e --- /dev/null +++ b/tests/Feature/Notify/NotificationTest.php @@ -0,0 +1,183 @@ +withoutMiddleware( + ThrottleRequests::class + ); + + $this->makeTestData(); + } + + public function testNotificationFound() + { + $notifications = new \stdClass; + $notifications->email = ["inventory_all"]; + + $this->user->company_users()->where('company_id', $this->company->id)->update(['notifications' => (array)$notifications]); + + $this->assertTrue(property_exists($this->cu->notifications,'email')); + + $p = Product::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id + ]); + + $notification_users = $this->filterUsersByPermissions($this->company->company_users, $p, ['inventory_all']); + $this->assertCount(1, $notification_users->toArray()); + + $notification_users = $this->filterUsersByPermissions($this->company->company_users, $p, ['inventory_user']); + $this->assertCount(0, $notification_users->toArray()); + + $notification_users = $this->filterUsersByPermissions($this->company->company_users, $p, ['inventory_user','invalid notification']); + $this->assertCount(0, $notification_users->toArray()); + + } + + public function testAllNotificationsFires() + { + $notifications = new \stdClass; + $notifications->email = ["all_notifications"]; + + $p = Product::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id + ]); + + $this->user->company_users()->where('company_id', $this->company->id)->update(['notifications' => (array)$notifications]); + + $notification_users = $this->filterUsersByPermissions($this->company->company_users, $p, ['inventory_all']); + $this->assertCount(1, $notification_users->toArray()); + + } + + public function testAllNotificationsFiresForUser() + { + $notifications = new \stdClass; + $notifications->email = ["all_user_notifications"]; + + $p = Product::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id + ]); + + $this->user->company_users()->where('company_id', $this->company->id)->update(['notifications' => (array)$notifications]); + + $notification_users = $this->filterUsersByPermissions($this->company->company_users, $p, ['all_user_notifications']); + $this->assertCount(1, $notification_users->toArray()); + + } + + + public function testAllNotificationsDoesNotFiresForUser() + { + $u = User::factory()->create([ + 'account_id' => $this->account->id, + 'email' => $this->faker->safeEmail(), + 'confirmation_code' => uniqid("st",true), + ]); + + $company_token = new CompanyToken; + $company_token->user_id = $u->id; + $company_token->company_id = $this->company->id; + $company_token->account_id = $this->account->id; + $company_token->name = 'test token'; + $company_token->token = Str::random(64); + $company_token->is_system = true; + $company_token->save(); + + $u->companies()->attach($this->company->id, [ + 'account_id' => $this->account->id, + 'is_owner' => 1, + 'is_admin' => 1, + 'is_locked' => 0, + 'notifications' => CompanySettings::notificationDefaults(), + 'settings' => null, + ]); + + $p = Product::factory()->create([ + 'user_id' => $u->id, + 'company_id' => $this->company->id + ]); + + + $notifications = new \stdClass; + $notifications->email = ["all_user_notifications"]; + $this->user->company_users()->where('company_id', $this->company->id)->update(['notifications' => (array)$notifications]); + + $methods = $this->findUserEntityNotificationType($p, $this->cu, ['all_user_notifications']); + $this->assertCount(0, $methods); + + $methods = $this->findUserEntityNotificationType($p, $this->cu, ['all_notifications']); + $this->assertCount(0, $methods); + + $notifications = []; + $notifications['email'] = ["all_notifications"]; + + $cu = CompanyUser::where('company_id', $this->company->id)->where('user_id', $this->user->id)->first(); + $cu->notifications = $notifications; + $cu->save(); + + $methods = $this->findUserEntityNotificationType($p, $cu, ["all_notifications"]); + + $this->assertCount(1, $methods); + + $notifications = []; + $notifications['email'] = ["inventory_user"]; + + $cu = CompanyUser::where('company_id', $this->company->id)->where('user_id', $this->user->id)->first(); + $cu->notifications = $notifications; + $cu->save(); + + $methods = $this->findUserEntityNotificationType($p, $cu, ["all_notifications"]); + $this->assertCount(0, $methods); + + $p = Product::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id + ]); + + $methods = $this->findUserEntityNotificationType($p, $cu, []); + + nlog($methods); + + $this->assertCount(1, $methods); + + + } + + +}