diff --git a/app/Events/Credit/CreditWasRestored.php b/app/Events/Credit/CreditWasRestored.php index 62f343eab3ca..70ba1d5fd463 100644 --- a/app/Events/Credit/CreditWasRestored.php +++ b/app/Events/Credit/CreditWasRestored.php @@ -11,6 +11,7 @@ namespace App\Events\Credit; +use App\Models\Company; use App\Models\Credit; use Illuminate\Queue\SerializesModels; diff --git a/app/Factory/CloneQuoteToInvoiceFactory.php b/app/Factory/CloneQuoteToInvoiceFactory.php index 326c33489822..0c02506d2c08 100644 --- a/app/Factory/CloneQuoteToInvoiceFactory.php +++ b/app/Factory/CloneQuoteToInvoiceFactory.php @@ -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; diff --git a/app/Http/Controllers/ClientPortal/QuoteController.php b/app/Http/Controllers/ClientPortal/QuoteController.php index 6d8a7b350e0e..30eb3e9738e4 100644 --- a/app/Http/Controllers/ClientPortal/QuoteController.php +++ b/app/Http/Controllers/ClientPortal/QuoteController.php @@ -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() diff --git a/app/Repositories/TaskRepository.php b/app/Repositories/TaskRepository.php index e73f3109a357..639567c25686 100644 --- a/app/Repositories/TaskRepository.php +++ b/app/Repositories/TaskRepository.php @@ -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']); diff --git a/app/Services/Quote/ConvertQuote.php b/app/Services/Quote/ConvertQuote.php index be13069ab525..f8a757c5e57f 100644 --- a/app/Services/Quote/ConvertQuote.php +++ b/app/Services/Quote/ConvertQuote.php @@ -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(); diff --git a/app/Services/Quote/QuoteService.php b/app/Services/Quote/QuoteService.php index 72aade07b952..f74dd3cfe590 100644 --- a/app/Services/Quote/QuoteService.php +++ b/app/Services/Quote/QuoteService.php @@ -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')) { diff --git a/tests/Integration/EventTest.php b/tests/Integration/EventTest.php index 73bec63fce06..b21deec1839f 100644 --- a/tests/Integration/EventTest.php +++ b/tests/Integration/EventTest.php @@ -17,6 +17,11 @@ 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\Invoice\InvoiceWasArchived; use App\Events\Invoice\InvoiceWasCreated; use App\Events\Invoice\InvoiceWasDeleted; @@ -27,11 +32,17 @@ 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\Models\Credit; use App\Models\Design; use App\Models\Invoice; @@ -64,6 +75,130 @@ class EventTest extends TestCase $this->makeTestData(); } + 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() { @@ -79,6 +214,7 @@ class EventTest extends TestCase QuoteWasArchived::class, QuoteWasRestored::class, QuoteWasDeleted::class, + QuoteWasApproved::class, ]); $response = $this->withHeaders([ @@ -106,6 +242,10 @@ class EventTest extends TestCase '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, @@ -118,6 +258,12 @@ class EventTest extends TestCase ])->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,