mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
validation rules for max amounts
This commit is contained in:
parent
6e5fb456c1
commit
deab4b6ace
42
app/Events/Statement/StatementWasEmailed.php
Normal file
42
app/Events/Statement/StatementWasEmailed.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Events\Statement;
|
||||||
|
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Company;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StatementWasEmailed.
|
||||||
|
*/
|
||||||
|
class StatementWasEmailed
|
||||||
|
{
|
||||||
|
use Dispatchable;
|
||||||
|
use InteractsWithSockets;
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public function __construct(public Client $client, public Company $company, public string $end_date, public array $event_vars)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Get the channels the event should broadcast on.
|
||||||
|
// *
|
||||||
|
// * @return Channel|array
|
||||||
|
// */
|
||||||
|
public function broadcastOn()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,7 @@ class StoreBankTransactionRequest extends Request
|
|||||||
$rules = [];
|
$rules = [];
|
||||||
|
|
||||||
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.$user->company()->id.',is_deleted,0';
|
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.$user->company()->id.',is_deleted,0';
|
||||||
|
$rules['amount'] = ['sometimes', 'bail', 'numeric', 'nullable', 'max:99999999999999'];
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +55,7 @@ class StoreBankTransactionRequest extends Request
|
|||||||
$input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']);
|
$input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,9 +44,7 @@ class UpdateBankTransactionRequest extends Request
|
|||||||
$rules['vendor_id'] = 'bail|required|exists:vendors,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
$rules['vendor_id'] = 'bail|required|exists:vendors,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (isset($this->expense_id)) {
|
$rules['amount'] = ['sometimes', 'bail', 'nullable', 'numeric', 'max:99999999999999'];
|
||||||
// $rules['expense_id'] = 'bail|required|exists:expenses,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
|
||||||
// }
|
|
||||||
|
|
||||||
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
$rules['bank_integration_id'] = 'bail|required|exists:bank_integrations,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ class StoreExpenseRequest extends Request
|
|||||||
$rules['payment_date'] = 'bail|nullable|sometimes|date:Y-m-d';
|
$rules['payment_date'] = 'bail|nullable|sometimes|date:Y-m-d';
|
||||||
$rules['date'] = 'bail|sometimes|date:Y-m-d';
|
$rules['date'] = 'bail|sometimes|date:Y-m-d';
|
||||||
$rules['documents'] = 'bail|sometimes|array';
|
$rules['documents'] = 'bail|sometimes|array';
|
||||||
|
$rules['amount'] = ['sometimes', 'bail', 'nullable', 'numeric', 'max:99999999999999'];
|
||||||
|
|
||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ class UpdateExpenseRequest extends Request
|
|||||||
$rules['transaction_id'] = 'bail|sometimes|nullable|exists:bank_transactions,id,company_id,'.$user->company()->id;
|
$rules['transaction_id'] = 'bail|sometimes|nullable|exists:bank_transactions,id,company_id,'.$user->company()->id;
|
||||||
$rules['invoice_id'] = 'bail|sometimes|nullable|exists:invoices,id,company_id,'.$user->company()->id;
|
$rules['invoice_id'] = 'bail|sometimes|nullable|exists:invoices,id,company_id,'.$user->company()->id;
|
||||||
$rules['documents'] = 'bail|sometimes|array';
|
$rules['documents'] = 'bail|sometimes|array';
|
||||||
|
$rules['amount'] = ['sometimes', 'bail', 'nullable', 'numeric', 'max:99999999999999'];
|
||||||
|
|
||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
@ -67,9 +67,8 @@ class RefundPaymentRequest extends Request
|
|||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
$rules = [
|
$rules = [
|
||||||
'id' => 'bail|required', //@phpstan-ignore-line
|
'id' => ['bail','required', new ValidRefundableRequest($input)],
|
||||||
'id' => new ValidRefundableRequest($input),
|
'amount' => ['numeric', 'max:99999999999999'],
|
||||||
'amount' => 'numeric',
|
|
||||||
'date' => 'required',
|
'date' => 'required',
|
||||||
'invoices.*.invoice_id' => 'required',
|
'invoices.*.invoice_id' => 'required',
|
||||||
'invoices.*.amount' => 'required',
|
'invoices.*.amount' => 'required',
|
||||||
|
@ -50,7 +50,7 @@ class StorePaymentRequest extends Request
|
|||||||
'invoices.*.invoice_id' => ['bail','required','distinct', new ValidInvoicesRules($this->all()),Rule::exists('invoices','id')->where('company_id', $user->company()->id)->where('client_id', $this->client_id)],
|
'invoices.*.invoice_id' => ['bail','required','distinct', new ValidInvoicesRules($this->all()),Rule::exists('invoices','id')->where('company_id', $user->company()->id)->where('client_id', $this->client_id)],
|
||||||
'credits.*.credit_id' => ['bail','required','distinct', new ValidCreditsRules($this->all()),Rule::exists('credits','id')->where('company_id', $user->company()->id)->where('client_id', $this->client_id)],
|
'credits.*.credit_id' => ['bail','required','distinct', new ValidCreditsRules($this->all()),Rule::exists('credits','id')->where('company_id', $user->company()->id)->where('client_id', $this->client_id)],
|
||||||
'credits.*.amount' => ['bail','required', new CreditsSumRule($this->all())],
|
'credits.*.amount' => ['bail','required', new CreditsSumRule($this->all())],
|
||||||
'amount' => ['bail', 'numeric', new PaymentAmountsBalanceRule()],
|
'amount' => ['bail', 'numeric', new PaymentAmountsBalanceRule(), 'max:99999999999999'],
|
||||||
'number' => ['bail', 'nullable', Rule::unique('payments')->where('company_id', $user->company()->id)],
|
'number' => ['bail', 'nullable', Rule::unique('payments')->where('company_id', $user->company()->id)],
|
||||||
'idempotency_key' => ['nullable', 'bail', 'string','max:64', Rule::unique('payments')->where('company_id', $user->company()->id)],
|
'idempotency_key' => ['nullable', 'bail', 'string','max:64', Rule::unique('payments')->where('company_id', $user->company()->id)],
|
||||||
];
|
];
|
||||||
|
56
app/Listeners/Statement/StatementEmailedActivity.php
Normal file
56
app/Listeners/Statement/StatementEmailedActivity.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Listeners\Statement;
|
||||||
|
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Repositories\ActivityRepository;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class StatementEmailedActivity implements ShouldQueue
|
||||||
|
{
|
||||||
|
protected $activityRepo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the event listener.
|
||||||
|
*
|
||||||
|
* @param ActivityRepository $activityRepo
|
||||||
|
*/
|
||||||
|
public function __construct(ActivityRepository $activityRepo)
|
||||||
|
{
|
||||||
|
$this->activityRepo = $activityRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the event.
|
||||||
|
*
|
||||||
|
* @param object $event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle($event)
|
||||||
|
{
|
||||||
|
MultiDB::setDb($event->company->db);
|
||||||
|
|
||||||
|
$fields = new stdClass();
|
||||||
|
|
||||||
|
$user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->client->id;
|
||||||
|
|
||||||
|
$fields->user_id = $user_id;
|
||||||
|
$fields->client_id = $event->client->id;
|
||||||
|
$fields->notes = $event->end_date;
|
||||||
|
$fields->company_id = $event->company->id;
|
||||||
|
$fields->activity_type_id = Activity::EMAIL_STATEMENT;
|
||||||
|
|
||||||
|
$this->activityRepo->save($fields, $event->client, $event->event_vars);
|
||||||
|
}
|
||||||
|
}
|
199
tests/Feature/MaxAmountTest.php
Normal file
199
tests/Feature/MaxAmountTest.php
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
use App\Models\Quote;
|
||||||
|
use App\Models\Credit;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use Tests\MockAccountData;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use App\DataMapper\InvoiceItem;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @covers App\Http\Controllers\ActivityController
|
||||||
|
*/
|
||||||
|
class MaxAmountTest extends TestCase
|
||||||
|
{
|
||||||
|
use DatabaseTransactions;
|
||||||
|
use MockAccountData;
|
||||||
|
|
||||||
|
protected function setUp() :void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->makeTestData();
|
||||||
|
|
||||||
|
$this->withoutMiddleware(
|
||||||
|
ThrottleRequests::class
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInvoiceMaxAmount()
|
||||||
|
{
|
||||||
|
$item = new InvoiceItem();
|
||||||
|
$item->cost = 10000000000000000;
|
||||||
|
$item->quantity = 100;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'line_items' => [$item]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/invoices', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
$i = Invoice::factory()->create($data);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->putJson("/api/v1/invoices/{$i->hashed_id}", $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testCreditMaxAmount()
|
||||||
|
{
|
||||||
|
$item = new InvoiceItem();
|
||||||
|
$item->cost = 10000000000000000;
|
||||||
|
$item->quantity = 100;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'line_items' => [$item]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/credits', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
$i = Credit::factory()->create($data);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->putJson("/api/v1/credits/{$i->hashed_id}", $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testQuoteMaxAmount()
|
||||||
|
{
|
||||||
|
$item = new InvoiceItem();
|
||||||
|
$item->cost = 10000000000000000;
|
||||||
|
$item->quantity = 100;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'line_items' => [$item]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/quotes', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
$i = Quote::factory()->create($data);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->putJson("/api/v1/quotes/{$i->hashed_id}", $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPurchaseOrderMaxAmount()
|
||||||
|
{
|
||||||
|
$item = new InvoiceItem();
|
||||||
|
$item->cost = 10000000000000000;
|
||||||
|
$item->quantity = 100;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'vendor_id' => $this->vendor->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'line_items' => [$item]
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/purchase_orders', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
$i = PurchaseOrder::factory()->create($data);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->putJson("/api/v1/purchase_orders/{$i->hashed_id}", $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecurringInvoiceMaxAmount()
|
||||||
|
{
|
||||||
|
$item = new InvoiceItem();
|
||||||
|
$item->cost = 10000000000000000;
|
||||||
|
$item->quantity = 100;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'line_items' => [$item],
|
||||||
|
'frequency_id' => 5
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/recurring_invoices', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
|
||||||
|
$i = RecurringInvoice::factory()->create($data);
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->putJson("/api/v1/recurring_invoices/{$i->hashed_id}", $data);
|
||||||
|
|
||||||
|
$response->assertStatus(422);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user