diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index 13d1284cbc64..60e57d9adab7 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -562,6 +562,16 @@ class InvoiceController extends BaseController
return response()->json(['message' => $hash_or_response], 200);
}
+ if($action == 'set_payment_link' && $request->has('subscription_id')) {
+
+ $invoices->each(function ($invoice) use($user, $request){
+ if($user->can('edit', $invoice))
+ $invoice->service()->setPaymentLink($request->subscription_id)->save();
+ });
+
+ return $this->listResponse(Invoice::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
+ }
+
/*
* Send the other actions to the switch
*/
diff --git a/app/Http/Controllers/RecurringInvoiceController.php b/app/Http/Controllers/RecurringInvoiceController.php
index c0412442dc4b..642806a7d367 100644
--- a/app/Http/Controllers/RecurringInvoiceController.php
+++ b/app/Http/Controllers/RecurringInvoiceController.php
@@ -424,13 +424,26 @@ class RecurringInvoiceController extends BaseController
$recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
+
+ if($request->action == 'set_payment_link' && $request->has('subscription_id')) {
+
+ $recurring_invoices->each(function ($invoice) use ($user, $request) {
+ if($user->can('edit', $invoice)) {
+ $invoice->service()->setPaymentLink($request->subscription_id)->save();
+ }
+ });
+
+ return $this->listResponse(RecurringInvoice::query()->withTrashed()->whereIn('id', $request->ids)->company());
+ }
+
$recurring_invoices->each(function ($recurring_invoice, $key) use ($request, $user) {
if ($user->can('edit', $recurring_invoice)) {
$this->performAction($recurring_invoice, $request->action, true);
}
});
- return $this->listResponse(RecurringInvoice::withTrashed()->whereIn('id', $request->ids));
+ return $this->listResponse(RecurringInvoice::query()->withTrashed()->whereIn('id', $request->ids)->company());
+
}
/**
diff --git a/app/Http/Requests/Invoice/BulkInvoiceRequest.php b/app/Http/Requests/Invoice/BulkInvoiceRequest.php
index c46fe6db8069..e5df287f75df 100644
--- a/app/Http/Requests/Invoice/BulkInvoiceRequest.php
+++ b/app/Http/Requests/Invoice/BulkInvoiceRequest.php
@@ -28,7 +28,8 @@ class BulkInvoiceRequest extends Request
'email_type' => 'sometimes|in:reminder1,reminder2,reminder3,reminder_endless,custom1,custom2,custom3,invoice,quote,credit,payment,payment_partial,statement,purchase_order',
'template' => 'sometimes|string',
'template_id' => 'sometimes|string',
- 'send_email' => 'sometimes|bool'
+ 'send_email' => 'sometimes|bool',
+ 'subscriptin_id' => 'sometimes|string',
];
}
}
diff --git a/app/Http/Requests/RecurringInvoice/BulkRecurringInvoiceRequest.php b/app/Http/Requests/RecurringInvoice/BulkRecurringInvoiceRequest.php
index e030435eb06b..162362851799 100644
--- a/app/Http/Requests/RecurringInvoice/BulkRecurringInvoiceRequest.php
+++ b/app/Http/Requests/RecurringInvoice/BulkRecurringInvoiceRequest.php
@@ -31,10 +31,14 @@ class BulkRecurringInvoiceRequest extends Request
public function rules()
{
+ /** @var \App\Models\User $user */
+ $user = auth()->user();
+
return [
- 'ids' => ['required','bail','array',Rule::exists('recurring_invoices', 'id')->where('company_id', auth()->user()->company()->id)],
- 'action' => 'in:archive,restore,delete,increase_prices,update_prices,start,stop,send_now',
+ 'ids' => ['required','bail','array', Rule::exists('recurring_invoices', 'id')->where('company_id', $user->company()->id)],
+ 'action' => 'in:archive,restore,delete,increase_prices,update_prices,start,stop,send_now,set_payment_link',
'percentage_increase' => 'required_if:action,increase_prices|numeric|min:0|max:100',
+ 'subscription_id' => 'sometimes|string'
];
}
diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php
index 045282f41aaf..89a1ab51ddf1 100644
--- a/app/Services/Invoice/InvoiceService.php
+++ b/app/Services/Invoice/InvoiceService.php
@@ -11,20 +11,21 @@
namespace App\Services\Invoice;
-use App\Events\Invoice\InvoiceWasArchived;
-use App\Jobs\Entity\CreateRawPdf;
-use App\Jobs\Inventory\AdjustProductInventory;
-use App\Jobs\Invoice\CreateEInvoice;
-use App\Libraries\Currency\Conversion\CurrencyApi;
-use App\Models\CompanyGateway;
+use App\Models\Task;
+use App\Utils\Ninja;
use App\Models\Expense;
use App\Models\Invoice;
use App\Models\Payment;
-use App\Models\Task;
-use App\Utils\Ninja;
-use App\Utils\Traits\MakesHash;
+use App\Models\Subscription;
+use App\Models\CompanyGateway;
use Illuminate\Support\Carbon;
+use App\Utils\Traits\MakesHash;
+use App\Jobs\Entity\CreateRawPdf;
+use App\Jobs\Invoice\CreateEInvoice;
use Illuminate\Support\Facades\Storage;
+use App\Events\Invoice\InvoiceWasArchived;
+use App\Jobs\Inventory\AdjustProductInventory;
+use App\Libraries\Currency\Conversion\CurrencyApi;
class InvoiceService
{
@@ -619,6 +620,19 @@ class InvoiceService
return $this;
}
+ public function setPaymentLink(string $subscription_id): self
+ {
+
+ $sub_id = $this->decodePrimaryKey($subscription_id);
+
+ if(Subscription::withTrashed()->where('id', $sub_id)->company()->exists()) {
+ $this->invoice->subscription_id = $sub_id;
+ }
+
+ return $this;
+
+ }
+
/**
* Saves the invoice.
* @return Invoice object
diff --git a/app/Services/Recurring/RecurringService.php b/app/Services/Recurring/RecurringService.php
index 61ae416956b1..8bfb0d1aaef7 100644
--- a/app/Services/Recurring/RecurringService.php
+++ b/app/Services/Recurring/RecurringService.php
@@ -11,16 +11,20 @@
namespace App\Services\Recurring;
-use App\Jobs\RecurringInvoice\SendRecurring;
+use App\Utils\Ninja;
+use App\Models\Subscription;
+use App\Models\RecurringQuote;
+use Illuminate\Support\Carbon;
+use App\Utils\Traits\MakesHash;
use App\Models\RecurringExpense;
use App\Models\RecurringInvoice;
-use App\Models\RecurringQuote;
-use App\Utils\Ninja;
-use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Storage;
+use App\Jobs\RecurringInvoice\SendRecurring;
class RecurringService
{
+ use MakesHash;
+
public function __construct(public RecurringInvoice | RecurringExpense | RecurringQuote $recurring_entity)
{
}
@@ -161,6 +165,19 @@ class RecurringService
return $this;
}
+ public function setPaymentLink(string $subscription_id): self
+ {
+
+ $sub_id = $this->decodePrimaryKey($subscription_id);
+
+ if(Subscription::withTrashed()->where('id', $sub_id)->where('company_id', $this->recurring_entity->company_id)->exists()) {
+ $this->recurring_entity->subscription_id = $sub_id;
+ }
+
+ return $this;
+
+ }
+
public function save()
{
$this->recurring_entity->saveQuietly();
diff --git a/lang/en/texts.php b/lang/en/texts.php
index 784d9f981b63..d46a3711de69 100644
--- a/lang/en/texts.php
+++ b/lang/en/texts.php
@@ -5255,6 +5255,8 @@ $lang = array(
'select_provider' => 'Select Provider',
'nordigen_requisition_subject' => 'Requisition expired, please reauthenticate.',
'nordigen_requisition_body' => 'Access to bank account feeds has expired as set in End User Agreement.
Please log into Invoice Ninja and re-authenticate with your banks to continue receiving transactions.',
+ 'participant' => 'Participant',
+ 'participant_name' => 'Participant name',
);
return $lang;
diff --git a/tests/Feature/InvoiceTest.php b/tests/Feature/InvoiceTest.php
index f17351c9749d..57e8804a7416 100644
--- a/tests/Feature/InvoiceTest.php
+++ b/tests/Feature/InvoiceTest.php
@@ -11,18 +11,20 @@
namespace Tests\Feature;
-use App\Helpers\Invoice\InvoiceSum;
+use Tests\TestCase;
use App\Models\Client;
-use App\Models\ClientContact;
use App\Models\Invoice;
use App\Models\Project;
-use App\Repositories\InvoiceRepository;
-use App\Utils\Traits\MakesHash;
-use Illuminate\Database\Eloquent\Model;
-use Illuminate\Foundation\Testing\DatabaseTransactions;
-use Illuminate\Support\Facades\Session;
use Tests\MockAccountData;
-use Tests\TestCase;
+use App\Models\Subscription;
+use App\Models\ClientContact;
+use App\Utils\Traits\MakesHash;
+use App\Models\RecurringInvoice;
+use App\Helpers\Invoice\InvoiceSum;
+use App\Repositories\InvoiceRepository;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Session;
+use Illuminate\Foundation\Testing\DatabaseTransactions;
/**
* @test
@@ -49,6 +51,48 @@ class InvoiceTest extends TestCase
$this->makeTestData();
}
+ public function testInvoicePaymentLinkMutation()
+ {
+
+
+ $s = Subscription::factory()
+ ->create(['company_id' => $this->company->id, 'user_id' => $this->user->id]);
+
+
+ $s2 = Subscription::factory()
+ ->create(['company_id' => $this->company->id, 'user_id' => $this->user->id]);
+
+
+ $r = Invoice::factory()
+ ->create(['company_id' => $this->company->id, 'user_id' => $this->user->id,'client_id' => $this->client->id]);
+
+ $rr = $r->service()->setPaymentLink($s->hashed_id)->save();
+
+ $this->assertEquals($s->id, $rr->subscription_id);
+
+ $data = [
+ 'subscription_id' => $s2->hashed_id,
+ 'action' => 'set_payment_link',
+ 'ids' => [$r->hashed_id],
+ ];
+
+ $response = $this->withHeaders([
+ 'X-API-SECRET' => config('ninja.api_secret'),
+ 'X-API-TOKEN' => $this->token,
+ ])->postJson('/api/v1/invoices/bulk', $data)
+ ->assertStatus(200);
+
+ $arr = $response->json();
+
+ $r = $r->fresh();
+
+ $this->assertEquals($s2->id, $r->subscription_id);
+
+
+
+ }
+
+
public function testPostNewInvoiceWithProjectButNoClient()
{
diff --git a/tests/Feature/RecurringInvoiceTest.php b/tests/Feature/RecurringInvoiceTest.php
index 8f2c3e5e7fa9..5a8bd0c33dbf 100644
--- a/tests/Feature/RecurringInvoiceTest.php
+++ b/tests/Feature/RecurringInvoiceTest.php
@@ -11,24 +11,26 @@
namespace Tests\Feature;
-use App\Factory\InvoiceItemFactory;
-use App\Factory\InvoiceToRecurringInvoiceFactory;
-use App\Factory\RecurringInvoiceFactory;
-use App\Factory\RecurringInvoiceToInvoiceFactory;
-use App\Jobs\RecurringInvoice\UpdateRecurring;
-use App\Models\Client;
-use App\Models\ClientContact;
-use App\Models\Product;
-use App\Models\RecurringInvoice;
-use App\Utils\Helpers;
-use App\Utils\Traits\MakesHash;
use Carbon\Carbon;
-use Illuminate\Database\Eloquent\Model;
-use Illuminate\Foundation\Testing\DatabaseTransactions;
-use Illuminate\Routing\Middleware\ThrottleRequests;
-use Illuminate\Support\Facades\Session;
-use Tests\MockAccountData;
use Tests\TestCase;
+use App\Models\Client;
+use App\Utils\Helpers;
+use App\Models\Product;
+use Tests\MockAccountData;
+use App\Models\Subscription;
+use App\Models\ClientContact;
+use App\Utils\Traits\MakesHash;
+use App\Models\RecurringInvoice;
+use App\Factory\InvoiceItemFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Session;
+use App\Factory\RecurringInvoiceFactory;
+use Database\Factories\SubscriptionFactory;
+use App\Jobs\RecurringInvoice\UpdateRecurring;
+use App\Factory\InvoiceToRecurringInvoiceFactory;
+use App\Factory\RecurringInvoiceToInvoiceFactory;
+use Illuminate\Routing\Middleware\ThrottleRequests;
+use Illuminate\Foundation\Testing\DatabaseTransactions;
/**
* @test
@@ -59,8 +61,44 @@ class RecurringInvoiceTest extends TestCase
$this->makeTestData();
}
+ public function testLinkingSubscription()
+ {
+ $s = Subscription::factory()
+ ->create(['company_id' => $this->company->id, 'user_id' => $this->user->id]);
+ $s2 = Subscription::factory()
+ ->create(['company_id' => $this->company->id, 'user_id' => $this->user->id]);
+
+
+ $r = RecurringInvoice::factory()
+ ->create(['company_id' => $this->company->id, 'user_id' => $this->user->id,'client_id' => $this->client->id]);
+
+ $rr = $r->service()->setPaymentLink($s->hashed_id)->save();
+
+ $this->assertEquals($s->id, $rr->subscription_id);
+
+ $data = [
+ 'subscription_id' => $s2->hashed_id,
+ 'action' => 'set_payment_link',
+ 'ids' => [$r->hashed_id],
+ ];
+
+ $response = $this->withHeaders([
+ 'X-API-SECRET' => config('ninja.api_secret'),
+ 'X-API-TOKEN' => $this->token,
+ ])->postJson('/api/v1/recurring_invoices/bulk', $data)
+ ->assertStatus(200);
+
+ $arr = $response->json();
+
+ $r = $r->fresh();
+
+ $this->assertEquals($s2->id, $r->subscription_id);
+
+
+ }
+
public function testStartDate()
{
$line_items = [];