Updates for recurring expense currency id for foreign currencies

This commit is contained in:
David Bomba 2023-09-03 16:28:30 +10:00
parent 283c3d4ead
commit bb3dfd5a5c
4 changed files with 205 additions and 13 deletions

View File

@ -65,6 +65,7 @@ class RecurringExpenseToExpenseFactory
$expense->tax_amount3 = $recurring_expense->tax_amount3 ?: 0;
$expense->uses_inclusive_taxes = $recurring_expense->uses_inclusive_taxes;
$expense->calculate_tax_by_amount = $recurring_expense->calculate_tax_by_amount;
$expense->invoice_currency_id = $recurring_expense->invoice_currency_id;
return $expense;
}

View File

@ -27,27 +27,35 @@ class StoreRecurringExpenseRequest extends Request
*/
public function authorize() : bool
{
return auth()->user()->can('create', RecurringExpense::class);
/** @var \App\Models\User $user */
$user = auth()->user();
return $user->can('create', RecurringExpense::class);
}
public function rules()
{
/** @var \App\Models\User $user */
$user = auth()->user();
$rules = [];
if ($this->number) {
$rules['number'] = Rule::unique('recurring_expenses')->where('company_id', auth()->user()->company()->id);
$rules['number'] = Rule::unique('recurring_expenses')->where('company_id', $user->company()->id);
}
if (! empty($this->client_id)) {
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.$user->company()->id;
}
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.$user->company()->id.',is_deleted,0';
$rules['frequency_id'] = 'required|integer|digits_between:1,12';
$rules['tax_amount1'] = 'numeric';
$rules['tax_amount2'] = 'numeric';
$rules['tax_amount3'] = 'numeric';
$rules['currency_id'] = 'bail|required|integer|exists:currencies,id';
if ($this->file('documents') && is_array($this->file('documents'))) {
$rules['documents.*'] = $this->file_validation;
} elseif ($this->file('documents')) {
@ -65,6 +73,10 @@ class StoreRecurringExpenseRequest extends Request
public function prepareForValidation()
{
/** @var \App\Models\User $user */
$user = auth()->user();
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
@ -74,7 +86,7 @@ class StoreRecurringExpenseRequest extends Request
}
if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
$input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
$input['currency_id'] = (string) $user->company()->settings->currency_id;
}
if (array_key_exists('color', $input) && is_null($input['color'])) {

View File

@ -35,6 +35,12 @@ class RecurringExpenseFactory extends Factory
'private_notes' => $this->faker->text(50),
'transaction_reference' => $this->faker->text(5),
'invoice_id' => null,
'tax_rate1' => 0,
'tax_rate2' => 0,
'tax_rate3' => 0,
'tax_name1' => '',
'tax_name2' => '',
'tax_name3' => '',
];
}
}

View File

@ -11,14 +11,16 @@
namespace Tests\Feature;
use App\Models\RecurringInvoice;
use App\Utils\Traits\MakesHash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\ValidationException;
use Tests\MockAccountData;
use Tests\TestCase;
use Tests\MockAccountData;
use Illuminate\Support\Str;
use App\Utils\Traits\MakesHash;
use App\Models\RecurringInvoice;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Session;
use App\Jobs\Cron\RecurringExpensesCron;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Testing\DatabaseTransactions;
/**
* @test
@ -30,6 +32,8 @@ class RecurringExpenseApiTest extends TestCase
use DatabaseTransactions;
use MockAccountData;
public $faker;
protected function setUp() :void
{
parent::setUp();
@ -43,6 +47,175 @@ class RecurringExpenseApiTest extends TestCase
Model::reguard();
}
public function testRecurringExpenseGenerationWithCurrencyConversion()
{
$r = \App\Models\RecurringExpense::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 100,
'number' => Str::random(10),
'frequency_id' => 5,
'remaining_cycles' => -1,
'status_id' => \App\Models\RecurringInvoice::STATUS_ACTIVE,
'date' => now()->format('Y-m-d'),
'currency_id' => 1,
'next_send_date' => now(),
'next_send_date_client' => now(),
'invoice_currency_id' => 2,
'foreign_amount' => 50,
]);
(new RecurringExpensesCron())->handle();
$expense = \App\Models\Expense::where('recurring_expense_id', $r->id)->orderBy('id','desc')->first();
$this->assertEquals($r->amount, $expense->amount);
$this->assertEquals($r->currency_id, $expense->currency_id);
$this->assertEquals($r->invoice_currency_id, $expense->invoice_currency_id);
$this->assertEquals($r->foreign_amount, $expense->foreign_amount);
}
public function testRecurringExpenseGenerationNullForeignCurrency()
{
$r = \App\Models\RecurringExpense::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 100,
'number' => Str::random(10),
'frequency_id' => 5,
'remaining_cycles' => -1,
'status_id' => \App\Models\RecurringInvoice::STATUS_ACTIVE,
'date' => now()->format('Y-m-d'),
'currency_id' => 1,
'next_send_date' => now(),
'next_send_date_client' => now(),
'invoice_currency_id' => null
]);
(new RecurringExpensesCron())->handle();
$expense = \App\Models\Expense::where('recurring_expense_id', $r->id)->orderBy('id','desc')->first();
$this->assertEquals($r->amount, $expense->amount);
$this->assertEquals($r->currency_id, $expense->currency_id);
$this->assertEquals($r->invoice_currency_id, $expense->invoice_currency_id);
}
public function testRecurringExpenseGeneration()
{
$r = \App\Models\RecurringExpense::factory()->create([
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 100,
'number' => Str::random(10),
'frequency_id' => 5,
'remaining_cycles' => -1,
'status_id' => \App\Models\RecurringInvoice::STATUS_ACTIVE,
'date' => now()->format('Y-m-d'),
'currency_id' => 1,
'next_send_date' => now(),
'next_send_date_client' => now(),
]);
(new RecurringExpensesCron())->handle();
$expense = \App\Models\Expense::where('recurring_expense_id', $r->id)->orderBy('id','desc')->first();
$this->assertEquals($r->amount, $expense->amount);
$this->assertEquals($r->currency_id, $expense->currency_id);
}
public function testRecurringExpenseValidation()
{
$data = [
'amount' => 10,
'client_id' => $this->client->hashed_id,
'number' => '123321',
'frequency_id' => 5,
'remaining_cycles' =>5,
'currency_id' => 34545435425
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/recurring_expenses?start=true', $data);
$response->assertStatus(422);
}
public function testRecurringExpenseValidation2()
{
$data = [
'amount' => 10,
'client_id' => $this->client->hashed_id,
'number' => '123321',
'frequency_id' => 5,
'remaining_cycles' =>5,
'currency_id' => 1
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/recurring_expenses?start=true', $data);
$response->assertStatus(200);
}
public function testRecurringExpenseValidation3()
{
$data = [
'amount' => 10,
'client_id' => $this->client->hashed_id,
'number' => '123321',
'frequency_id' => 5,
'remaining_cycles' =>5,
'currency_id' => null
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/recurring_expenses?start=true', $data);
$data = $response->json();
$response->assertStatus(200);
$this->assertEquals(1, $data['data']['currency_id']);
}
public function testRecurringExpenseValidation4()
{
$data = [
'amount' => 10,
'client_id' => $this->client->hashed_id,
'number' => '123321',
'frequency_id' => 5,
'remaining_cycles' =>5,
'currency_id' => ""
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/recurring_expenses?start=true', $data);
$data = $response->json();
$response->assertStatus(200);
$this->assertEquals(1, $data['data']['currency_id']);
}
public function testRecurringExpenseGetFiltered()
{
$response = $this->withHeaders([