Merge pull request #4257 from turbo124/v5-develop

Event Tests
This commit is contained in:
David Bomba 2020-11-03 23:45:04 +11:00 committed by GitHub
commit 552ac4ee8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 1927 additions and 62 deletions

View File

@ -41,8 +41,7 @@ jobs:
- name: Cleanup Builds
run: |
sudo rm -rf bootstrap/cache/*
sudo rm public/index.html
- name: Build project # This would actually build your project, using zip for an example artifact
run: |
zip -r ./invoiceninja.zip ./

View File

@ -12,6 +12,7 @@
namespace App\Events\Client;
use App\Models\Client;
use App\Models\Company;
use Illuminate\Queue\SerializesModels;
/**

View File

@ -12,6 +12,7 @@
namespace App\Events\Client;
use App\Models\Client;
use App\Models\Company;
use Illuminate\Queue\SerializesModels;
/**
@ -26,6 +27,8 @@ class ClientWasRestored
*/
public $client;
public $fromDeleted;
public $company;
public $event_vars;
@ -37,9 +40,10 @@ class ClientWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Client $client, Company $company, array $event_vars)
public function __construct(Client $client, $fromDeleted, Company $company, array $event_vars)
{
$this->client = $client;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -12,6 +12,7 @@
namespace App\Events\Client;
use App\Models\Client;
use App\Models\Company;
use Illuminate\Queue\SerializesModels;
/**

View File

@ -11,6 +11,7 @@
namespace App\Events\Credit;
use App\Models\Company;
use App\Models\Credit;
use Illuminate\Queue\SerializesModels;
@ -30,6 +31,7 @@ class CreditWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -37,9 +39,10 @@ class CreditWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Credit $credit, Company $company, array $event_vars)
public function __construct(Credit $credit, $fromDeleted, Company $company, array $event_vars)
{
$this->credit = $credit;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -32,6 +32,7 @@ class DesignWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -39,10 +40,12 @@ class DesignWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Design $design, Company $company, array $event_vars)
public function __construct(Design $design, $fromDeleted, Company $company, array $event_vars)
{
$this->design = $design;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;

View File

@ -31,6 +31,7 @@ class DocumentWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -38,9 +39,10 @@ class DocumentWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Document $document, Company $company, array $event_vars)
public function __construct(Document $document, $fromDeleted, Company $company, array $event_vars)
{
$this->document = $document;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -31,6 +31,7 @@ class ExpenseWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -38,9 +39,10 @@ class ExpenseWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Expense $expense, Company $company, array $event_vars)
public function __construct(Expense $expense, $fromDeleted, Company $company, array $event_vars)
{
$this->expense = $expense;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -32,7 +32,7 @@ class InvoiceWasRestored
public $company;
public $event_vars;
/**
* Create a new event instance.
*

View File

@ -0,0 +1,49 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Events\Product;
use App\Models\Company;
use App\Models\Invoice;
use Illuminate\Queue\SerializesModels;
/**
* Class ProductWasRestored.
*/
class ProductWasRestored
{
use SerializesModels;
/**
* @var Product
*/
public $invoice;
public $company;
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
* @param Product $invoice
* @param Company $company
* @param array $event_vars
*/
public function __construct(Product $product, $fromDeleted, Company $company, array $event_vars)
{
$this->product = $product;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}
}

View File

@ -12,6 +12,7 @@
namespace App\Events\Quote;
use App\Models\Company;
use App\Models\Quote;
use Illuminate\Queue\SerializesModels;
class QuoteWasArchived

View File

@ -12,6 +12,7 @@
namespace App\Events\Quote;
use App\Models\Company;
use App\Models\Quote;
use Illuminate\Queue\SerializesModels;
/**

View File

@ -12,6 +12,7 @@
namespace App\Events\Quote;
use App\Models\Company;
use App\Models\Quote;
use Illuminate\Queue\SerializesModels;
/**

View File

@ -12,6 +12,7 @@
namespace App\Events\Quote;
use App\Models\Company;
use App\Models\Quote;
use Illuminate\Queue\SerializesModels;
/**
@ -27,6 +28,7 @@ class QuoteWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -34,9 +36,10 @@ class QuoteWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Quote $quote, Company $company, array $event_vars)
public function __construct(Quote $quote, $fromDeleted, Company $company, array $event_vars)
{
$this->quote = $quote;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -31,6 +31,7 @@ class TaskWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -38,9 +39,10 @@ class TaskWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Task $task, Company $company, array $event_vars)
public function __construct(Task $task, $fromDeleted, Company $company, array $event_vars)
{
$this->task = $task;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -31,6 +31,7 @@ class VendorWasRestored
public $event_vars;
public $fromDeleted;
/**
* Create a new event instance.
*
@ -38,9 +39,10 @@ class VendorWasRestored
* @param Company $company
* @param array $event_vars
*/
public function __construct(Vendor $vendor, Company $company, array $event_vars)
public function __construct(Vendor $vendor, $fromDeleted, Company $company, array $event_vars)
{
$this->vendor = $vendor;
$this->fromDeleted = $fromDeleted;
$this->company = $company;
$this->event_vars = $event_vars;
}

View File

@ -27,6 +27,7 @@ class CloneQuoteToInvoiceFactory
unset($quote_array['hashed_id']);
unset($quote_array['invoice_id']);
unset($quote_array['id']);
unset($quote_array['invitations']);
foreach ($quote_array as $key => $value) {
$invoice->{$key} = $value;

View File

@ -13,6 +13,7 @@ namespace App\Http\Controllers;
use App\DataMapper\ClientSettings;
use App\Events\Client\ClientWasCreated;
use App\Events\Client\ClientWasUpdated;
use App\Factory\ClientFactory;
use App\Filters\ClientFilters;
use App\Http\Requests\Client\BulkClientRequest;
@ -288,6 +289,8 @@ class ClientController extends BaseController
$this->uploadLogo($request->file('company_logo'), $client->company, $client);
event(new ClientWasUpdated($client, $client->company, Ninja::eventVars()));
return $this->itemResponse($client->fresh());
}

View File

@ -109,8 +109,8 @@ class QuoteController extends Controller
if ($process) {
foreach ($quotes as $quote) {
$quote->service()->approve()->save();
event(new QuoteWasApproved(auth()->user(), $quote, $quote->company, Ninja::eventVars()));
$quote->service()->approve(auth()->user())->save();
event(new QuoteWasApproved($quote, $quote->company, Ninja::eventVars()));
}
return redirect()

View File

@ -11,6 +11,8 @@
namespace App\Http\Controllers;
use App\Events\Expense\ExpenseWasCreated;
use App\Events\Expense\ExpenseWasUpdated;
use App\Factory\ExpenseFactory;
use App\Filters\ExpenseFilters;
use App\Http\Requests\Expense\CreateExpenseRequest;
@ -29,6 +31,7 @@ use App\Models\Size;
use App\Repositories\BaseRepository;
use App\Repositories\ExpenseRepository;
use App\Transformers\ExpenseTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\BulkOptions;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\Uploadable;
@ -281,6 +284,8 @@ class ExpenseController extends BaseController
$this->uploadLogo($request->file('company_logo'), $expense->company, $expense);
event(new ExpenseWasUpdated($expense, $expense->company, Ninja::eventVars()));
return $this->itemResponse($expense->fresh());
}
@ -373,6 +378,8 @@ class ExpenseController extends BaseController
{
$expense = $this->expense_repo->save($request->all(), ExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id));
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars()));
return $this->itemResponse($expense);
}

View File

@ -29,8 +29,10 @@ use App\Repositories\BaseRepository;
use App\Repositories\PaymentRepository;
use App\Transformers\PaymentTransformer;
use App\Utils\Traits\MakesHash;
use App\Events\Payment\PaymentWasUpdated;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Utils\Ninja;
/**
* Class PaymentController.
@ -379,6 +381,7 @@ class PaymentController extends BaseController
$payment = $this->payment_repo->save($request->all(), $payment);
event(new PaymentWasUpdated($payment, $payment->company, Ninja::eventVars()));
return $this->itemResponse($payment);
}
@ -506,7 +509,8 @@ class PaymentController extends BaseController
$payments->each(function ($payment, $key) use ($action) {
if (auth()->user()->can('edit', $payment)) {
$this->payment_repo->{$action}($payment);
$this->performAction($payment, $action, true);
// $this->payment_repo->{$action}($payment);
}
});
@ -584,30 +588,31 @@ class PaymentController extends BaseController
* @param Payment $payment
* @param $action
*/
public function action(ActionPaymentRequest $request, Payment $payment, $action)
public function performAction(Payment $payment, $action, $bulk = false)
{
switch ($action) {
case 'clone_to_invoice':
//$payment = CloneInvoiceFactory::create($payment, auth()->user()->id);
//return $this->itemResponse($payment);
break;
case 'clone_to_quote':
//$quote = CloneInvoiceToQuoteFactory::create($payment, auth()->user()->id);
// todo build the quote transformer and return response here
break;
case 'history':
// code...
break;
case 'delivery_note':
// code...
break;
case 'mark_paid':
// code...
case 'restore':
$this->payment_repo->restore($payment);
if (! $bulk) {
return $this->listResponse($payment);
}
break;
case 'archive':
$this->payment_repo->archive($payment);
if (! $bulk) {
return $this->listResponse($payment);
}
// code...
break;
case 'delete':
$this->payment_repo->delete($payment);
if (! $bulk) {
return $this->listResponse($payment);
}
// code...
break;
case 'email':

View File

@ -11,6 +11,8 @@
namespace App\Http\Controllers;
use App\Events\Quote\QuoteWasCreated;
use App\Events\Quote\QuoteWasUpdated;
use App\Factory\CloneInvoiceFactory;
use App\Factory\CloneInvoiceToQuoteFactory;
use App\Factory\CloneQuoteFactory;
@ -31,6 +33,7 @@ use App\Models\Quote;
use App\Repositories\QuoteRepository;
use App\Transformers\InvoiceTransformer;
use App\Transformers\QuoteTransformer;
use App\Utils\Ninja;
use App\Utils\TempFile;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
@ -204,6 +207,8 @@ class QuoteController extends BaseController
$quote = $this->quote_repo->save($request->all(), QuoteFactory::create(auth()->user()->company()->id, auth()->user()->id));
event(new QuoteWasCreated($quote, $quote->company, Ninja::eventVars()));
return $this->itemResponse($quote);
}
@ -378,6 +383,8 @@ class QuoteController extends BaseController
$quote = $this->quote_repo->save($request->all(), $quote);
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars()));
return $this->itemResponse($quote);
}
@ -658,15 +665,26 @@ class QuoteController extends BaseController
}, basename($quote->pdf_file_path()));
//return response()->download(TempFile::path($quote->pdf_file_path()), basename($quote->pdf_file_path()));
break;
case 'restore':
$this->quote_repo->restore($quote);
if (!$bulk)
return $this->listResponse($quote);
break;
case 'archive':
$this->quote_repo->archive($quote);
return $this->listResponse($quote);
if (!$bulk)
return $this->listResponse($quote);
break;
case 'delete':
$this->quote_repo->delete($quote);
return $this->listResponse($quote);
if (!$bulk)
return $this->listResponse($quote);
break;
case 'email':
$quote->service()->sendEmail();
@ -679,6 +697,7 @@ class QuoteController extends BaseController
if (! $bulk) {
return $this->itemResponse($quote);
}
break;
// no break
default:
return response()->json(['message' => "The requested action `{$action}` is not available."], 400);

View File

@ -11,6 +11,8 @@
namespace App\Http\Controllers;
use App\Events\Task\TaskWasCreated;
use App\Events\Task\TaskWasUpdated;
use App\Factory\TaskFactory;
use App\Filters\TaskFilters;
use App\Http\Requests\Task\CreateTaskRequest;
@ -24,11 +26,12 @@ use App\Jobs\Util\ProcessBulk;
use App\Jobs\Util\UploadAvatar;
use App\Models\Country;
use App\Models\Currency;
use App\Models\Task;
use App\Models\Size;
use App\Models\Task;
use App\Repositories\BaseRepository;
use App\Repositories\TaskRepository;
use App\Transformers\TaskTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\BulkOptions;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\Uploadable;
@ -278,6 +281,8 @@ class TaskController extends BaseController
$task = $this->task_repo->save($request->all(), $task);
event(new TaskWasUpdated($task, $task->company, Ninja::eventVars()));
return $this->itemResponse($task->fresh());
}
@ -370,6 +375,8 @@ class TaskController extends BaseController
{
$task = $this->task_repo->save($request->all(), TaskFactory::create(auth()->user()->company()->id, auth()->user()->id));
event(new TaskWasCreated($task, $task->company, Ninja::eventVars()));
return $this->itemResponse($task);
}

View File

@ -11,6 +11,8 @@
namespace App\Http\Controllers;
use App\Events\Vendor\VendorWasCreated;
use App\Events\Vendor\VendorWasUpdated;
use App\Factory\VendorFactory;
use App\Filters\VendorFilters;
use App\Http\Requests\Vendor\CreateVendorRequest;
@ -29,6 +31,7 @@ use App\Models\Vendor;
use App\Repositories\BaseRepository;
use App\Repositories\VendorRepository;
use App\Transformers\VendorTransformer;
use App\Utils\Ninja;
use App\Utils\Traits\BulkOptions;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\Uploadable;
@ -280,6 +283,8 @@ class VendorController extends BaseController
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
event(new VendorWasUpdated($vendor, $vendor->company, Ninja::eventVars()));
return $this->itemResponse($vendor->fresh());
}
@ -376,6 +381,8 @@ class VendorController extends BaseController
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
event(new VendorWasCreated($vendor, $vendor->company, Ninja::eventVars()));
return $this->itemResponse($vendor);
}

View File

@ -13,6 +13,7 @@ namespace App\Http\Requests\Payment;
use App\Http\Requests\Request;
use App\Http\ValidationRules\Credit\ValidCreditsRules;
use App\Http\ValidationRules\Credit\CreditsSumRule;
use App\Http\ValidationRules\Payment\ValidInvoicesRules;
use App\Http\ValidationRules\PaymentAmountsBalanceRule;
use App\Http\ValidationRules\ValidCreditsPresentRule;
@ -76,7 +77,6 @@ class StorePaymentRequest extends Request
}
if (! isset($input['amount']) || $input['amount'] == 0) {
//$input['amount'] = $invoices_total - $credits_total;
$input['amount'] = $invoices_total - $credits_total; //todo the payment amount is always less the credit amount applied
}
@ -100,7 +100,7 @@ class StorePaymentRequest extends Request
'invoices.*.amount' => 'required',
'credits.*.credit_id' => 'bail|required|exists:credits,id',
'credits.*.credit_id' => new ValidCreditsRules($this->all()),
'credits.*.amount' => 'required',
'credits.*.amount' => ['required', new CreditsSumRule($this->all())],
'invoices' => new ValidPayableInvoicesRule(),
'number' => 'bail|nullable|unique:payments,number,'.$this->id.',id,company_id,'.$this->company_id,
];

View File

@ -0,0 +1,59 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\ValidationRules\Credit;
use App\Libraries\MultiDB;
use App\Models\Credit;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\User;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Validation\Rule;
/**
* Class CreditsSumRule.
*/
class CreditsSumRule implements Rule
{
use MakesHash;
private $input;
public function __construct($input)
{
$this->input = $input;
}
public function passes($attribute, $value)
{
return $this->checkCreditTotals();
}
private function checkCreditTotals()
{
if( array_sum(array_column($this->input['credits'],'amount')) > array_sum(array_column($this->input['invoices'], 'amount')))
return false;
return true;
}
/**
* @return string
*/
public function message()
{
return "Total credits applied cannot be MORE than total of invoices";
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class ClientUpdatedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$client = $event->client;
$fields = new stdClass;
$fields->client_id = $client->id;
$fields->user_id = $client->user_id;
$fields->company_id = $client->company_id;
$fields->activity_type_id = Activity::UPDATE_CLIENT;
$this->activity_repo->save($fields, $client, $event->event_vars);
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class CreatedExpenseActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->expense_id = $event->expense->id;
$fields->user_id = $event->expense->user_id;
$fields->company_id = $event->expense->company_id;
$fields->activity_type_id = Activity::CREATE_EXPENSE;
$this->activity_repo->save($fields, $event->expense, $event->event_vars);
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class CreatedTaskActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->task_id = $event->task->id;
$fields->user_id = $event->task->user_id;
$fields->company_id = $event->task->company_id;
$fields->activity_type_id = Activity::CREATE_TASK;
$this->activity_repo->save($fields, $event->task, $event->event_vars);
}
}

View File

@ -0,0 +1,54 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class CreatedVendorActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->vendor_id = $event->vendor->id;
$fields->user_id = $event->vendor->user_id;
$fields->company_id = $event->vendor->company_id;
$fields->activity_type_id = Activity::CREATE_VENDOR;
$this->activity_repo->save($fields, $event->vendor, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class ExpenseArchivedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$expense = $event->expense;
$fields = new stdClass;
$fields->expense_id = $expense->id;
$fields->user_id = $expense->user_id;
$fields->company_id = $expense->company_id;
$fields->activity_type_id = Activity::ARCHIVE_EXPENSE;
$this->activity_repo->save($fields, $expense, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use stdClass;
class ExpenseDeletedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->expense_id = $event->expense->id;
$fields->user_id = $event->expense->user_id;
$fields->company_id = $event->expense->company_id;
$fields->activity_type_id = Activity::DELETE_VENDOR;
$this->activity_repo->save($fields, $event->expense, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use stdClass;
class ExpenseRestoredActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->expense_id = $event->expense->id;
$fields->user_id = $event->expense->user_id;
$fields->company_id = $event->expense->company_id;
$fields->activity_type_id = Activity::RESTORE_EXPENSE;
$this->activity_repo->save($fields, $event->expense, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class ExpenseUpdatedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$expense = $event->expense;
$fields = new stdClass;
$fields->expense_id = $expense->id;
$fields->user_id = $expense->user_id;
$fields->company_id = $expense->company_id;
$fields->activity_type_id = Activity::UPDATE_EXPENSE;
$this->activity_repo->save($fields, $expense, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class TaskArchivedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$task = $event->task;
$fields = new stdClass;
$fields->task_id = $task->id;
$fields->user_id = $task->user_id;
$fields->company_id = $task->company_id;
$fields->activity_type_id = Activity::ARCHIVE_TASK;
$this->activity_repo->save($fields, $task, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use stdClass;
class TaskDeletedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->task_id = $event->task->id;
$fields->user_id = $event->task->user_id;
$fields->company_id = $event->task->company_id;
$fields->activity_type_id = Activity::DELETE_TASK;
$this->activity_repo->save($fields, $event->task, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use stdClass;
class TaskRestoredActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->task_id = $event->task->id;
$fields->user_id = $event->task->user_id;
$fields->company_id = $event->task->company_id;
$fields->activity_type_id = Activity::RESTORE_TASK;
$this->activity_repo->save($fields, $event->task, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class TaskUpdatedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$task = $event->task;
$fields = new stdClass;
$fields->task_id = $task->id;
$fields->user_id = $task->user_id;
$fields->company_id = $task->company_id;
$fields->activity_type_id = Activity::UPDATE_TASK;
$this->activity_repo->save($fields, $task, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class VendorArchivedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$vendor = $event->vendor;
$fields = new stdClass;
$fields->vendor_id = $vendor->id;
$fields->user_id = $vendor->user_id;
$fields->company_id = $vendor->company_id;
$fields->activity_type_id = Activity::ARCHIVE_VENDOR;
$this->activity_repo->save($fields, $vendor, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use stdClass;
class VendorDeletedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->vendor_id = $event->vendor->id;
$fields->user_id = $event->vendor->user_id;
$fields->company_id = $event->vendor->company_id;
$fields->activity_type_id = Activity::DELETE_VENDOR;
$this->activity_repo->save($fields, $event->vendor, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\ClientContact;
use App\Models\InvoiceInvitation;
use App\Repositories\ActivityRepository;
use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use stdClass;
class VendorRestoredActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$fields = new stdClass;
$fields->vendor_id = $event->vendor->id;
$fields->user_id = $event->vendor->user_id;
$fields->company_id = $event->vendor->company_id;
$fields->activity_type_id = Activity::RESTORE_VENDOR;
$this->activity_repo->save($fields, $event->vendor, $event->event_vars);
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Listeners\Activity;
use App\Libraries\MultiDB;
use App\Models\Activity;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use stdClass;
class VendorUpdatedActivity implements ShouldQueue
{
protected $activity_repo;
/**
* Create the event listener.
*
* @param ActivityRepository $activity_repo
*/
public function __construct(ActivityRepository $activity_repo)
{
$this->activity_repo = $activity_repo;
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
MultiDB::setDb($event->company->db);
$vendor = $event->vendor;
$fields = new stdClass;
$fields->vendor_id = $vendor->id;
$fields->user_id = $vendor->user_id;
$fields->company_id = $vendor->company_id;
$fields->activity_type_id = Activity::UPDATE_VENDOR;
$this->activity_repo->save($fields, $vendor, $event->event_vars);
}
}

View File

@ -47,24 +47,24 @@ class Activity extends StaticModel
const RESTORE_PAYMENT = 27; //
const RESTORE_CREDIT = 28; //
const APPROVE_QUOTE = 29; //
const CREATE_VENDOR = 30;
const ARCHIVE_VENDOR = 31;
const DELETE_VENDOR = 32;
const RESTORE_VENDOR = 33;
const CREATE_EXPENSE = 34;
const ARCHIVE_EXPENSE = 35;
const DELETE_EXPENSE = 36;
const RESTORE_EXPENSE = 37;
const CREATE_VENDOR = 30; //
const ARCHIVE_VENDOR = 31;//
const DELETE_VENDOR = 32;//
const RESTORE_VENDOR = 33;//
const CREATE_EXPENSE = 34;//
const ARCHIVE_EXPENSE = 35;//
const DELETE_EXPENSE = 36;//
const RESTORE_EXPENSE = 37;//
const VOIDED_PAYMENT = 39; //
const REFUNDED_PAYMENT = 40; //
const FAILED_PAYMENT = 41;
const CREATE_TASK = 42;
const UPDATE_TASK = 43;
const ARCHIVE_TASK = 44;
const DELETE_TASK = 45;
const RESTORE_TASK = 46;
const UPDATE_EXPENSE = 47;
const CREATE_TASK = 42; //
const UPDATE_TASK = 43; //
const ARCHIVE_TASK = 44; //
const DELETE_TASK = 45; //
const RESTORE_TASK = 46; //
const UPDATE_EXPENSE = 47;//
const CREATE_USER = 48; // only used in CreateUser::job
const UPDATE_USER = 49; // not needed?
@ -77,6 +77,8 @@ class Activity extends StaticModel
const REVERSED_INVOICE = 58; //
const CANCELLED_INVOICE = 59; //
const VIEW_CREDIT = 60; //
const UPDATE_CLIENT = 61; //
const UPDATE_VENDOR = 62; //
protected $casts = [
'is_system' => 'boolean',

View File

@ -30,6 +30,11 @@ use App\Events\Credit\CreditWasRestored;
use App\Events\Credit\CreditWasUpdated;
use App\Events\Credit\CreditWasViewed;
use App\Events\Design\DesignWasArchived;
use App\Events\Expense\ExpenseWasArchived;
use App\Events\Expense\ExpenseWasCreated;
use App\Events\Expense\ExpenseWasDeleted;
use App\Events\Expense\ExpenseWasRestored;
use App\Events\Expense\ExpenseWasUpdated;
use App\Events\Invoice\InvoiceWasArchived;
use App\Events\Invoice\InvoiceWasCancelled;
use App\Events\Invoice\InvoiceWasCreated;
@ -57,16 +62,34 @@ use App\Events\Quote\QuoteWasEmailed;
use App\Events\Quote\QuoteWasRestored;
use App\Events\Quote\QuoteWasUpdated;
use App\Events\Quote\QuoteWasViewed;
use App\Events\Task\TaskWasArchived;
use App\Events\Task\TaskWasCreated;
use App\Events\Task\TaskWasDeleted;
use App\Events\Task\TaskWasRestored;
use App\Events\Task\TaskWasUpdated;
use App\Events\User\UserLoggedIn;
use App\Events\User\UserWasCreated;
use App\Events\User\UserWasDeleted;
use App\Events\Vendor\VendorWasArchived;
use App\Events\Vendor\VendorWasCreated;
use App\Events\Vendor\VendorWasDeleted;
use App\Events\Vendor\VendorWasRestored;
use App\Events\Vendor\VendorWasUpdated;
use App\Listeners\Activity\ArchivedClientActivity;
use App\Listeners\Activity\ClientUpdatedActivity;
use App\Listeners\Activity\CreatedClientActivity;
use App\Listeners\Activity\CreatedCreditActivity;
use App\Listeners\Activity\CreatedExpenseActivity;
use App\Listeners\Activity\CreatedQuoteActivity;
use App\Listeners\Activity\CreatedTaskActivity;
use App\Listeners\Activity\CreatedVendorActivity;
use App\Listeners\Activity\CreditArchivedActivity;
use App\Listeners\Activity\DeleteClientActivity;
use App\Listeners\Activity\DeleteCreditActivity;
use App\Listeners\Activity\ExpenseArchivedActivity;
use App\Listeners\Activity\ExpenseDeletedActivity;
use App\Listeners\Activity\ExpenseRestoredActivity;
use App\Listeners\Activity\ExpenseUpdatedActivity;
use App\Listeners\Activity\PaymentCreatedActivity;
use App\Listeners\Activity\PaymentDeletedActivity;
use App\Listeners\Activity\PaymentRefundedActivity;
@ -74,7 +97,15 @@ use App\Listeners\Activity\PaymentUpdatedActivity;
use App\Listeners\Activity\PaymentVoidedActivity;
use App\Listeners\Activity\QuoteUpdatedActivity;
use App\Listeners\Activity\RestoreClientActivity;
use App\Listeners\Activity\TaskArchivedActivity;
use App\Listeners\Activity\TaskDeletedActivity;
use App\Listeners\Activity\TaskRestoredActivity;
use App\Listeners\Activity\TaskUpdatedActivity;
use App\Listeners\Activity\UpdatedCreditActivity;
use App\Listeners\Activity\VendorArchivedActivity;
use App\Listeners\Activity\VendorDeletedActivity;
use App\Listeners\Activity\VendorRestoredActivity;
use App\Listeners\Activity\VendorUpdatedActivity;
use App\Listeners\Contact\UpdateContactLastLogin;
use App\Listeners\Credit\CreditRestoredActivity;
use App\Listeners\Credit\CreditViewedActivity;
@ -161,6 +192,7 @@ class EventServiceProvider extends ServiceProvider
ArchivedClientActivity::class,
],
ClientWasUpdated::class =>[
ClientUpdatedActivity::class,
],
ClientWasDeleted::class =>[
DeleteClientActivity::class,
@ -204,14 +236,29 @@ class EventServiceProvider extends ServiceProvider
CreditViewedActivity::class,
],
//Designs
DesignWasArchived::class => [
],
DesignWasUpdated::class => [
],
DesignWasArchived::class => [
],
DesignWasDeleted::class => [
],
DesignWasRestored::class => [
],
ExpenseWasCreated::class => [
CreatedExpenseActivity::class,
],
ExpenseWasUpdated::class => [
ExpenseUpdatedActivity::class,
],
ExpenseWasArchived::class => [
ExpenseArchivedActivity::class,
],
ExpenseWasDeleted::class => [
ExpenseDeletedActivity::class,
],
ExpenseWasRestored::class => [
ExpenseRestoredActivity::class
],
//Invoices
InvoiceWasMarkedSent::class => [
CreateInvoiceHtmlBackup::class,
@ -286,6 +333,37 @@ class EventServiceProvider extends ServiceProvider
QuoteWasRestored::class => [
QuoteRestoredActivity::class,
],
TaskWasCreated::class => [
CreatedTaskActivity::class,
],
TaskWasUpdated::class => [
TaskUpdatedActivity::class,
],
TaskWasArchived::class => [
TaskArchivedActivity::class,
],
TaskWasDeleted::class => [
TaskDeletedActivity::class,
],
TaskWasRestored::class => [
TaskRestoredActivity::class,
],
VendorWasCreated::class => [
CreatedVendorActivity::class,
],
VendorWasArchived::class => [
VendorArchivedActivity::class,
],
VendorWasDeleted::class => [
VendorDeletedActivity::class,
],
VendorWasRestored::class => [
VendorRestoredActivity::class,
],
VendorWasUpdated::class => [
VendorUpdatedActivity::class,
],
];
/**

View File

@ -60,7 +60,7 @@ class BaseRepository
*/
private function getEventClass($entity, $type)
{
return 'App\Events\\'.ucfirst(class_basename($entity)).'Was'.$type;
return 'App\Events\\'.ucfirst(class_basename($entity)).'\\'.ucfirst(class_basename($entity)).'Was'.$type;
}
/**

View File

@ -51,7 +51,7 @@ class TaskRepository extends BaseRepository
$task->fill($data);
$task->save();
$task->number = empty($task->number) ? $this->getNextTaskNumber($task) : $data['number'];
$task->number = empty($task->number) || !array_key_exists('number', $data) ? $this->getNextTaskNumber($task) : $data['number'];
if (isset($data['description'])) {
$task->description = trim($data['description']);

View File

@ -34,6 +34,7 @@ class ConvertQuote
public function run($quote)
{
$invoice = CloneQuoteToInvoiceFactory::create($quote, $quote->user_id);
$invoice = $this->invoice_repo->save([], $invoice);
$invoice->fresh();

View File

@ -11,12 +11,14 @@
namespace App\Services\Quote;
use App\Events\Quote\QuoteWasApproved;
use App\Factory\CloneQuoteToInvoiceFactory;
use App\Models\Invoice;
use App\Models\Quote;
use App\Repositories\QuoteRepository;
use App\Services\Quote\CreateInvitations;
use App\Services\Quote\GetQuotePdf;
use App\Utils\Ninja;
class QuoteService
{
@ -108,10 +110,15 @@ class QuoteService
return $this;
}
public function approve() :self
public function approve($contact = null) :self
{
$this->setStatus(Quote::STATUS_APPROVED)->save();
if(!$contact)
$contact = $this->quote->invitations->first()->contact;
event(new QuoteWasApproved($contact, $this->quote, $this->quote->company, Ninja::eventVars()));
$invoice = null;
if ($this->quote->client->getSetting('auto_convert_quote')) {

View File

@ -127,8 +127,8 @@ class InvoiceTransformer extends EntityTransformer
'custom_value2' => (string) $invoice->custom_value2 ?: '',
'custom_value3' => (string) $invoice->custom_value3 ?: '',
'custom_value4' => (string) $invoice->custom_value4 ?: '',
'has_tasks' => (bool) $invoice->has_tasks,
'has_expenses' => (bool) $invoice->has_expenses,
'has_tasks' => (bool) false, //@deprecated v5.0.23
'has_expenses' => (bool) false, //@deprecated v5.0.23
'custom_surcharge1' => (float) $invoice->custom_surcharge1,
'custom_surcharge2' => (float) $invoice->custom_surcharge2,
'custom_surcharge3' => (float) $invoice->custom_surcharge3,

View File

@ -105,11 +105,11 @@ class HtmlEngine
$data['$total_tax_values'] = ['value' => $this->totalTaxValues(), 'label' => ctrans('texts.taxes')];
$data['$line_tax_labels'] = ['value' => $this->lineTaxLabels(), 'label' => ctrans('texts.taxes')];
$data['$line_tax_values'] = ['value' => $this->lineTaxValues(), 'label' => ctrans('texts.taxes')];
$data['$date'] = ['value' => $this->formatDate($this->entity->date, $this->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.date')];
$data['$date'] = ['value' => $this->formatDate($this->entity->date, $this->entity->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.date')];
//$data['$invoice_date'] = ['value' => $this->date ?: '&nbsp;', 'label' => ctrans('texts.invoice_date')];
$data['$invoice.date'] = &$data['$date'];
$data['$due_date'] = ['value' => $this->formatDate($this->entity->due_date, $this->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
$data['$payment_due'] = ['value' => $this->formatDate($this->entity->due_date, $this->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.payment_due')];
$data['$due_date'] = ['value' => $this->formatDate($this->entity->due_date, $this->entity->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
$data['$payment_due'] = ['value' => $this->formatDate($this->entity->due_date, $this->entity->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.payment_due')];
$data['$invoice.due_date'] = &$data['$due_date'];
$data['$invoice.number'] = ['value' => $this->entity->number ?: '&nbsp;', 'label' => ctrans('texts.invoice_number')];
$data['$invoice.po_number'] = ['value' => $this->entity->po_number ?: '&nbsp;', 'label' => ctrans('texts.po_number')];
@ -169,7 +169,7 @@ class HtmlEngine
$data['$credit.number'] = ['value' => $this->entity->number ?: '&nbsp;', 'label' => ctrans('texts.credit_number')];
$data['$credit.total'] = &$data['$credit.total'];
$data['$credit.po_number'] = &$data['$invoice.po_number'];
$data['$credit.date'] = ['value' => $this->formatDate($this->entity->date, $this->client->date_format()), 'label' => ctrans('texts.credit_date')];
$data['$credit.date'] = ['value' => $this->formatDate($this->entity->date, $this->entity->client->date_format()), 'label' => ctrans('texts.credit_date')];
$data['$balance'] = ['value' => Number::formatMoney($this->entity_calc->getBalance(), $this->client) ?: '&nbsp;', 'label' => ctrans('texts.balance')];
$data['$credit.balance'] = &$data['$balance'];
@ -187,7 +187,7 @@ class HtmlEngine
$data['$entity_issued_to'] = ['value' => '', 'label' => ctrans("texts.{$this->entity_string}_issued_to")];
$data['$your_entity'] = ['value' => '', 'label' => ctrans("texts.your_{$this->entity_string}")];
$data['$quote.date'] = ['value' => $this->formatDate($this->entity->date, $this->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.quote_date')];
$data['$quote.date'] = ['value' => $this->formatDate($this->entity->date, $this->entity->client->date_format()) ?: '&nbsp;', 'label' => ctrans('texts.quote_date')];
$data['$quote.number'] = ['value' => $this->entity->number ?: '&nbsp;', 'label' => ctrans('texts.quote_number')];
$data['$quote.po_number'] = &$data['$invoice.po_number'];
$data['$quote.quote_number'] = &$data['$quote.number'];

View File

@ -1302,4 +1302,87 @@ $contact = ClientContact::factory()->create([
$this->assertEquals(1, $payment->invoices()->count());
}
}
public function testPaymentActionArchive()
{
$this->invoice = null;
$client = ClientFactory::create($this->company->id, $this->user->id);
$client->save();
$this->invoice = InvoiceFactory::create($this->company->id, $this->user->id); //stub the company and user_id
$this->invoice->client_id = $client->id;
$this->invoice->line_items = $this->buildLineItems();
$this->invoice->uses_inclusive_taxes = false;
$this->invoice->save();
$this->invoice_calc = new InvoiceSum($this->invoice);
$this->invoice_calc->build();
$this->invoice = $this->invoice_calc->getInvoice();
$this->invoice->save();
$this->invoice->service()->markSent()->save();
$data = [
'amount' => 20.0,
'client_id' => $this->encodePrimaryKey($client->id),
'invoices' => [
[
'invoice_id' => $this->encodePrimaryKey($this->invoice->id),
'amount' => 10,
],
],
'date' => '2019/12/12',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/', $data);
$response->assertStatus(200);
$arr = $response->json();
$payment_id = $arr['data']['id'];
$payment = Payment::whereId($this->decodePrimaryKey($payment_id))->first();
$data = [
'ids' => [$this->encodePrimaryKey($payment->id)],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/bulk?action=archive', $data);
$arr = $response->json();
$this->assertGreaterThan(0, $arr['data'][0]['archived_at']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/bulk?action=restore', $data);
$arr = $response->json();
$this->assertEquals(0, $arr['data'][0]['archived_at']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/bulk?action=delete', $data);
$arr = $response->json();
$this->assertEquals(1, $arr['data'][0]['is_deleted']);
}
}

View File

@ -0,0 +1,596 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace Tests\Integration;
use App\Designs\Bold;
use App\Designs\Designer;
use App\Events\Client\ClientWasArchived;
use App\Events\Client\ClientWasCreated;
use App\Events\Client\ClientWasDeleted;
use App\Events\Client\ClientWasRestored;
use App\Events\Client\ClientWasUpdated;
use App\Events\Credit\CreditWasArchived;
use App\Events\Credit\CreditWasCreated;
use App\Events\Credit\CreditWasDeleted;
use App\Events\Credit\CreditWasRestored;
use App\Events\Credit\CreditWasUpdated;
use App\Events\Expense\ExpenseWasArchived;
use App\Events\Expense\ExpenseWasCreated;
use App\Events\Expense\ExpenseWasDeleted;
use App\Events\Expense\ExpenseWasRestored;
use App\Events\Expense\ExpenseWasUpdated;
use App\Events\Invoice\InvoiceWasArchived;
use App\Events\Invoice\InvoiceWasCreated;
use App\Events\Invoice\InvoiceWasDeleted;
use App\Events\Invoice\InvoiceWasRestored;
use App\Events\Invoice\InvoiceWasUpdated;
use App\Events\Payment\PaymentWasArchived;
use App\Events\Payment\PaymentWasCreated;
use App\Events\Payment\PaymentWasDeleted;
use App\Events\Payment\PaymentWasRestored;
use App\Events\Payment\PaymentWasUpdated;
use App\Events\Quote\QuoteWasApproved;
use App\Events\Quote\QuoteWasArchived;
use App\Events\Quote\QuoteWasCreated;
use App\Events\Quote\QuoteWasDeleted;
use App\Events\Quote\QuoteWasRestored;
use App\Events\Quote\QuoteWasUpdated;
use App\Events\Task\TaskWasArchived;
use App\Events\Task\TaskWasCreated;
use App\Events\Task\TaskWasDeleted;
use App\Events\Task\TaskWasRestored;
use App\Events\Task\TaskWasUpdated;
use App\Events\Vendor\VendorWasArchived;
use App\Events\Vendor\VendorWasCreated;
use App\Events\Vendor\VendorWasDeleted;
use App\Events\Vendor\VendorWasRestored;
use App\Events\Vendor\VendorWasUpdated;
use App\Models\Credit;
use App\Models\Design;
use App\Models\Invoice;
use App\Models\Quote;
use App\Models\RecurringInvoice;
use App\Services\PdfMaker\Design as PdfDesignModel;
use App\Services\PdfMaker\Design as PdfMakerDesign;
use App\Services\PdfMaker\PdfMaker as PdfMakerService;
use App\Utils\HtmlEngine;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml;
use Faker\Factory;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test
*/
class EventTest extends TestCase
{
use MockAccountData;
use MakesHash;
public function setUp() :void
{
parent::setUp();
$this->faker = \Faker\Factory::create();
$this->makeTestData();
}
public function testExpenseEvents()
{
$this->expectsEvents([
ExpenseWasCreated::class,
ExpenseWasUpdated::class,
ExpenseWasArchived::class,
ExpenseWasRestored::class,
ExpenseWasDeleted::class,
]);
$data = [
'public_notes' => $this->faker->firstName,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/expenses/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'public_notes' => $this->faker->firstName,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/expenses/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/expenses/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/expenses/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/expenses/bulk?action=delete', $data)
->assertStatus(200);
}
public function testVendorEvents()
{
$this->expectsEvents([
VendorWasCreated::class,
VendorWasUpdated::class,
VendorWasArchived::class,
VendorWasRestored::class,
VendorWasDeleted::class,
]);
$data = [
'name' => $this->faker->firstName,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/vendors/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'name' => $this->faker->firstName,
'id_number' => 'Coolio',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/vendors/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/vendors/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/vendors/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/vendors/bulk?action=delete', $data)
->assertStatus(200);
}
public function testTaskEvents()
{
/* Test fire new invoice */
$data = [
'client_id' => $this->client->hashed_id,
'description' => 'dude',
];
$this->expectsEvents([
TaskWasCreated::class,
TaskWasUpdated::class,
TaskWasArchived::class,
TaskWasRestored::class,
TaskWasDeleted::class,
]);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/tasks/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'client_id' => $this->client->hashed_id,
'description' => 'dude2',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/tasks/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/tasks/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/tasks/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/tasks/bulk?action=delete', $data)
->assertStatus(200);
}
public function testCreditEvents()
{
/* Test fire new invoice */
$data = [
'client_id' => $this->client->hashed_id,
'number' => 'dude',
];
$this->expectsEvents([
CreditWasCreated::class,
CreditWasUpdated::class,
CreditWasArchived::class,
CreditWasRestored::class,
CreditWasDeleted::class,
]);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/credits/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'client_id' => $this->client->hashed_id,
'number' => 'dude2',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/credits/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/credits/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/credits/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/credits/bulk?action=delete', $data)
->assertStatus(200);
}
public function testQuoteEvents()
{
/* Test fire new invoice */
$data = [
'client_id' => $this->client->hashed_id,
'number' => 'dude',
];
$this->expectsEvents([
QuoteWasCreated::class,
QuoteWasUpdated::class,
QuoteWasArchived::class,
QuoteWasRestored::class,
QuoteWasDeleted::class,
QuoteWasApproved::class,
]);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/quotes/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'client_id' => $this->client->hashed_id,
'number' => 'dude2',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/quotes/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$quote = Quote::find($this->decodePrimaryKey($arr['data']['id']));
$quote->status_id = Quote::STATUS_SENT;
$quote->save();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/quotes/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/quotes/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/quotes/bulk?action=approve', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/quotes/bulk?action=delete', $data)
->assertStatus(200);
}
//@TODO paymentwasvoided
//@TODO paymentwasrefunded
public function testPaymentEvents()
{
$this->expectsEvents([
PaymentWasCreated::class,
PaymentWasUpdated::class,
PaymentWasArchived::class,
PaymentWasRestored::class,
PaymentWasDeleted::class,
]);
$data = [
'amount' => $this->invoice->amount,
'client_id' => $this->client->hashed_id,
'invoices' => [
[
'invoice_id' => $this->invoice->hashed_id,
'amount' => $this->invoice->amount,
],
],
'date' => '2020/12/12',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments?include=invoices', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'transaction_reference' => 'testing'
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/payments/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/payments/bulk?action=delete', $data)
->assertStatus(200);
}
public function testInvoiceEvents()
{
/* Test fire new invoice */
$data = [
'client_id' => $this->client->hashed_id,
'number' => 'dude',
];
$this->expectsEvents([
InvoiceWasCreated::class,
InvoiceWasUpdated::class,
InvoiceWasArchived::class,
InvoiceWasRestored::class,
InvoiceWasDeleted::class,
]);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/invoices/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'client_id' => $this->client->hashed_id,
'number' => 'dude2',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/invoices/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/invoices/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/invoices/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/invoices/bulk?action=delete', $data)
->assertStatus(200);
}
public function testClientEvents()
{
$this->expectsEvents([
ClientWasCreated::class,
ClientWasUpdated::class,
ClientWasArchived::class,
ClientWasRestored::class,
ClientWasDeleted::class,
]);
$data = [
'name' => $this->faker->firstName,
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/clients/', $data)
->assertStatus(200);
$arr = $response->json();
$data = [
'name' => $this->faker->firstName,
'id_number' => 'Coolio',
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->put('/api/v1/clients/' . $arr['data']['id'], $data)
->assertStatus(200);
$data = [
'ids' => [$arr['data']['id']],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/clients/bulk?action=archive', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/clients/bulk?action=restore', $data)
->assertStatus(200);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->post('/api/v1/clients/bulk?action=delete', $data)
->assertStatus(200);
}
}