Additional validation logic to prevent duplicate invoices have a payment schedule assigned
This commit is contained in:
parent
48e8a69fda
commit
f24c8cafff
|
|
@ -14,6 +14,7 @@ namespace App\Http\Requests\TaskScheduler;
|
|||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Http\ValidationRules\Scheduler\ValidClientIds;
|
||||
use App\Http\ValidationRules\Scheduler\InvoiceWithNoExistingSchedule;
|
||||
|
||||
class StoreSchedulerRequest extends Request
|
||||
{
|
||||
|
|
@ -72,7 +73,7 @@ class StoreSchedulerRequest extends Request
|
|||
'parameters.status' => ['bail','sometimes', 'nullable', 'string'],
|
||||
'parameters.include_project_tasks' => ['bail','sometimes', 'boolean', 'required_if:template,invoice_outstanding_tasks'],
|
||||
'parameters.auto_send' => ['bail','sometimes', 'boolean', 'required_if:template,invoice_outstanding_tasks'],
|
||||
'parameters.invoice_id' => ['bail', 'string', 'required_if:template,payment_schedule'],
|
||||
'parameters.invoice_id' => ['bail', 'string', 'required_if:template,payment_schedule', new InvoiceWithNoExistingSchedule()],
|
||||
'parameters.auto_bill' => ['bail', 'boolean', 'required_if:template,payment_schedule'],
|
||||
'parameters.schedule' => ['bail', 'array', 'required_if:template,payment_schedule', 'min:1'],
|
||||
'parameters.schedule.*.id' => ['bail','sometimes', 'integer'],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\ValidationRules\Scheduler;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\Scheduler;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class InvoiceWithNoExistingSchedule.
|
||||
*/
|
||||
class InvoiceWithNoExistingSchedule implements Rule
|
||||
{
|
||||
use MakesHash;
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return Scheduler::where('company_id', $user->company()->id)
|
||||
->where('template', 'payment_schedule')
|
||||
->where('parameters->invoice_id', $value)
|
||||
->count() == 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return 'Invoice already has a payment schedule';
|
||||
}
|
||||
}
|
||||
|
|
@ -64,7 +64,86 @@ class SchedulerTest extends TestCase
|
|||
}
|
||||
|
||||
|
||||
public function testPaymentScheduleWithPercentageBasedScheduleAndFailingValidation()
|
||||
public function testDuplicateInvoicePaymentSchedule()
|
||||
{
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $this->client->id,
|
||||
'date' => now()->format('Y-m-d'),
|
||||
'due_date' => now()->addDays(30)->format('Y-m-d'),
|
||||
'amount' => 300.00,
|
||||
'balance' => 300.00,
|
||||
]);
|
||||
|
||||
$invoice->service()->markSent()->save();
|
||||
|
||||
$data = [
|
||||
'name' => 'A test payment schedule scheduler',
|
||||
'frequency_id' => 0,
|
||||
'next_run' => now()->format('Y-m-d'),
|
||||
'template' => 'payment_schedule',
|
||||
'parameters' => [
|
||||
'invoice_id' => $invoice->hashed_id,
|
||||
'auto_bill' => true,
|
||||
'schedule' => [
|
||||
[
|
||||
'id' => 1,
|
||||
'date' => now()->format('Y-m-d'),
|
||||
'amount' => 40,
|
||||
'is_amount' => false,
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'date' => now()->addDays(30)->format('Y-m-d'),
|
||||
'amount' => 60.00,
|
||||
'is_amount' => false,
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// $data = [
|
||||
// 'schedule' => [
|
||||
// [
|
||||
// 'id' => 1,
|
||||
// 'date' => now()->format('Y-m-d'),
|
||||
// 'amount' => 40,
|
||||
// 'is_amount' => false,
|
||||
// ],
|
||||
// [
|
||||
// 'id' => 2,
|
||||
// 'date' => now()->addDays(30)->format('Y-m-d'),
|
||||
// 'amount' => 60.00,
|
||||
// 'is_amount' => false,
|
||||
// ]
|
||||
// ],
|
||||
// 'auto_bill' => true,
|
||||
// ];
|
||||
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/task_schedulers', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/task_schedulers', $data);
|
||||
|
||||
$response->assertStatus(422);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testPaymentScheduleWithPercentageBasedScheduleAndFailingValidation()
|
||||
{
|
||||
$invoice = Invoice::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
|
|
|
|||
Loading…
Reference in New Issue