1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00
* Fixes for OpenAPI Documentation + fix support for docs for PHP 7.4

* User update tests

* Add total_taxes to invoice table, implement addition create-test-data fields for item and invoice level taxes
This commit is contained in:
David Bomba 2019-12-04 12:06:14 +11:00 committed by GitHub
parent abcd2fd1bb
commit 75df82a71c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 196 additions and 15 deletions

View File

@ -284,7 +284,25 @@ class CreateTestData extends Command
$invoice->date = $faker->date(); $invoice->date = $faker->date();
$invoice->line_items = $this->buildLineItems(); $invoice->line_items = $this->buildLineItems();
$invoice->uses_inclusive_Taxes = false; $invoice->uses_inclusive_taxes = false;
if(rand(0,1))
{
$invoice->tax_name1 = 'GST';
$invoice->tax_rate1 = 10.00;
}
if(rand(0,1))
{
$invoice->tax_name2 = 'VAT';
$invoice->tax_rate2 = 17.50;
}
if(rand(0,1))
{
$invoice->tax_name3 = 'CA Sales Tax';
$invoice->tax_rate3 = 5;
}
$invoice->save(); $invoice->save();
@ -330,6 +348,24 @@ class CreateTestData extends Command
$item->quantity = 1; $item->quantity = 1;
$item->cost =10; $item->cost =10;
if(rand(0, 1))
{
$item->tax_name1 = 'GST';
$item->tax_rate1 = 10.00;
}
if(rand(0, 1))
{
$item->tax_name1 = 'VAT';
$item->tax_rate1 = 17.50;
}
if(rand(0, 1))
{
$item->tax_name1 = 'Sales Tax';
$item->tax_rate1 = 5;
}
$line_items[] = $item; $line_items[] = $item;
return $line_items; return $line_items;

View File

@ -195,6 +195,8 @@ class InvoiceSum
/* Set new calculated total */ /* Set new calculated total */
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision); $this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
$this->invoice->total_taxes = $this->getTotalTaxes();
return $this; return $this;
} }

View File

@ -207,6 +207,8 @@ class InvoiceSumInclusive
/* Set new calculated total */ /* Set new calculated total */
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision); $this->invoice->amount = $this->formatValue($this->getTotal(), $this->invoice->client->currency()->precision);
$this->invoice->total_taxes = $this->getTotalTaxes();
return $this; return $this;
} }

View File

@ -42,9 +42,10 @@ class ActivityController extends BaseController
* @OA\Parameter(ref="#/components/parameters/index"), * @OA\Parameter(ref="#/components/parameters/index"),
* @OA\Parameter( * @OA\Parameter(
* name="rows", * name="rows",
* in="path", * in="query",
* description="The number of activities to return", * description="The number of activities to return",
* example="50", * example="50",
* required=false,
* @OA\Schema( * @OA\Schema(
* type="number", * type="number",
* format="integer", * format="integer",

View File

@ -4,6 +4,6 @@
* schema="Payment", * schema="Payment",
* type="object", * type="object",
* @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), * @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"),
* @OA\Property(property="is_manual", type="bool", example=true, description="______"), * @OA\Property(property="is_manual", type="boolean", example=true, description="______"),
* ) * )
*/ */

View File

@ -408,7 +408,8 @@ class UserController extends BaseController
* @OA\Parameter(ref="#/components/parameters/include"), * @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter( * @OA\Parameter(
* name="token_name", * name="token_name",
* in="path", * in="query",
* required=false,
* description="Customized name for the Users API Token", * description="Customized name for the Users API Token",
* example="iOS Device 11 iPad", * example="iOS Device 11 iPad",
* @OA\Schema( * @OA\Schema(
@ -546,7 +547,22 @@ class UserController extends BaseController
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"), * @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"), * @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"), * @OA\Parameter(ref="#/components/parameters/include"),
* @OA\RequestBody(ref="#/components/schemas/CompanyUser"), * @OA\Parameter(
* name="user",
* in="path",
* description="The user hashed_id",
* example="FD767dfd7",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\RequestBody(
* description="The company user object",
* required=true,
* @OA\JsonContent(ref="#/components/schemas/CompanyUser"),
* ),
* @OA\Response( * @OA\Response(
* response=200, * response=200,
* description="Returns the saved User object", * description="Returns the saved User object",
@ -595,6 +611,17 @@ class UserController extends BaseController
* @OA\Parameter(ref="#/components/parameters/X-Api-Token"), * @OA\Parameter(ref="#/components/parameters/X-Api-Token"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"), * @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(ref="#/components/parameters/include"), * @OA\Parameter(ref="#/components/parameters/include"),
* @OA\Parameter(
* name="user",
* in="path",
* description="The user hashed_id",
* example="FD767dfd7",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response( * @OA\Response(
* response=200, * response=200,
* description="Success response", * description="Success response",

View File

@ -59,7 +59,6 @@ class UpdateCompanyLedgerWithInvoice
$adjustment = $balance + $this->adjustment; $adjustment = $balance + $this->adjustment;
$company_ledger = CompanyLedgerFactory::create($this->invoice->company_id, $this->invoice->user_id); $company_ledger = CompanyLedgerFactory::create($this->invoice->company_id, $this->invoice->user_id);
$company_ledger->client_id = $this->invoice->client_id; $company_ledger->client_id = $this->invoice->client_id;
$company_ledger->adjustment = $this->adjustment; $company_ledger->adjustment = $this->adjustment;

View File

@ -85,13 +85,13 @@ class ApplyInvoicePayment implements ShouldQueue
} }
elseif($this->invoice->partial > 0 && $this->invoice->partial > $this->amount) //partial amount exists, but the amount is less than the partial amount elseif($this->invoice->partial > 0 && $this->invoice->partial > $this->amount) //partial amount exists, but the amount is less than the partial amount
{ {
\Log::error("partial > amount");
$this->invoice->partial -= $this->amount; $this->invoice->partial -= $this->amount;
$this->invoice->updateBalance($this->amount*-1); $this->invoice->updateBalance($this->amount*-1);
} }
elseif($this->invoice->partial > 0 && $this->invoice->partial < $this->amount) //partial exists and the amount paid is GREATER than the partial amount elseif($this->invoice->partial > 0 && $this->invoice->partial < $this->amount) //partial exists and the amount paid is GREATER than the partial amount
{ {
\Log::error("partial < amount");
$this->invoice->clearPartial(); $this->invoice->clearPartial();
$this->invoice->setDueDate(); $this->invoice->setDueDate();
$this->invoice->setStatus(Invoice::STATUS_PARTIAL); $this->invoice->setStatus(Invoice::STATUS_PARTIAL);
@ -101,7 +101,6 @@ class ApplyInvoicePayment implements ShouldQueue
} }
elseif($this->invoice->amount == $this->invoice->balance) //total invoice paid. elseif($this->invoice->amount == $this->invoice->balance) //total invoice paid.
{ {
\Log::error("balance == amount");
$this->invoice->clearPartial(); $this->invoice->clearPartial();
$this->invoice->setDueDate(); $this->invoice->setDueDate();

View File

@ -279,7 +279,7 @@ class Invoice extends BaseModel
if($this->uses_inclusive_taxes) if($this->uses_inclusive_taxes)
$invoice_calc = new InvoiceSumInclusive($this); $invoice_calc = new InvoiceSumInclusive($this);
else else
$invoice_calc = new InvoiceSum($this, $this); $invoice_calc = new InvoiceSum($this);
return $invoice_calc->build(); return $invoice_calc->build();

View File

@ -62,14 +62,18 @@ class UserRepository extends BaseRepository
$cu = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first(); $cu = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
/*No company user exists - attach the user*/
if(!$cu){ if(!$cu){
//$cu = CompanyUserFactory::create($user->id, $company->id, $account_id);
$data['company_user']['account_id'] = $account_id; $data['company_user']['account_id'] = $account_id;
$user->companies()->attach($company->id, $data['company_user']); $user->companies()->attach($company->id, $data['company_user']);
} }
else
{
$cu->fill($data['company_user']);
$cu->save();
}
} }

View File

@ -109,6 +109,7 @@ class InvoiceTransformer extends EntityTransformer
'tax_rate2' => (float) $invoice->tax_rate2, 'tax_rate2' => (float) $invoice->tax_rate2,
'tax_name3' => $invoice->tax_name3 ? $invoice->tax_name3 : '', 'tax_name3' => $invoice->tax_name3 ? $invoice->tax_name3 : '',
'tax_rate3' => (float) $invoice->tax_rate3, 'tax_rate3' => (float) $invoice->tax_rate3,
'total_taxes' => (float) $invoice->total_taxes,
'is_amount_discount' => (bool) ($invoice->is_amount_discount ?: false), 'is_amount_discount' => (bool) ($invoice->is_amount_discount ?: false),
'footer' => $invoice->footer ?: '', 'footer' => $invoice->footer ?: '',
'partial' => (float) ($invoice->partial ?: 0.0), 'partial' => (float) ($invoice->partial ?: 0.0),

View File

@ -438,6 +438,8 @@ class CreateUsersTable extends Migration
$t->string('tax_name3')->nullable(); $t->string('tax_name3')->nullable();
$t->decimal('tax_rate3', 13, 3)->default(0); $t->decimal('tax_rate3', 13, 3)->default(0);
$t->decimal('total_taxes', 13, 3)->default(0);
$t->boolean('uses_inclusive_taxes')->default(0); $t->boolean('uses_inclusive_taxes')->default(0);
$t->string('custom_value1')->nullable(); $t->string('custom_value1')->nullable();

View File

@ -1,9 +1,10 @@
<?php <?php
namespace Tests\Feature; namespace Feature;
use App\Factory\UserFactory; use App\Factory\UserFactory;
use App\Factory\CompanyUserFactory;
use App\Models\Account; use App\Models\Account;
use App\Models\Activity; use App\Models\Activity;
use App\Models\Company; use App\Models\Company;
@ -78,6 +79,7 @@ class UserTest extends TestCase
$arr = $response->json(); $arr = $response->json();
$this->assertNotNull($arr['data']['company_user']);
} }
public function testUserAttachAndDetach() public function testUserAttachAndDetach()
@ -114,4 +116,110 @@ class UserTest extends TestCase
$this->assertNotNull($user); $this->assertNotNull($user);
} }
public function testAttachUserToMultipleCompanies()
{
/* Create New Company */
$company2 = factory(\App\Models\Company::class)->create([
'account_id' => $this->account->id,
'domain' => 'ninja.test:8000',
]);
/* Create New Company Token*/
$user_1_company_token = CompanyToken::create([
'user_id' => $this->user->id,
'company_id' => $company2->id,
'account_id' => $this->account->id,
'name' => 'test token',
'token' => \Illuminate\Support\Str::random(64),
]);
/*Manually link this user to the company*/
$cu = CompanyUserFactory::create($this->user->id, $company2->id, $this->account->id);
$cu->is_owner = true;
$cu->is_admin = true;
$cu->save();
/*Create New Blank User and Attach to Company 2*/
$new_user = UserFactory::create();
$new_user->first_name = 'Test';
$new_user->last_name = 'Palloni';
$new_user->save();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $user_1_company_token->token,
])->post('/api/v1/users/'.$this->encodePrimaryKey($new_user->id).'/attach_to_company?include=company_user');
$response->assertStatus(200);
$this->assertNotNull($new_user->company_user);
$this->assertEquals($new_user->company_user->company_id, $company2->id);
/*Create brand new user manually with company_user object and attach to a different company*/
$data = [
'first_name' => 'hey',
'last_name' => 'you',
'email' => 'bob@good.ole.boys.co2.com',
'company_user' => [
'is_admin' => false,
'is_owner' => false,
'permissions' => 'create_client,create_invoice'
],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $user_1_company_token->token,
])->post('/api/v1/users?include=company_user', $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertNotNull($arr['data']['company_user']);
$this->assertFalse($arr['data']['company_user']['is_admin']);
$this->assertFalse($arr['data']['company_user']['is_owner']);
$this->assertEquals($arr['data']['company_user']['permissions'], 'create_client,create_invoice');
$user = User::whereEmail('bob@good.ole.boys.co2.com')->first();
$this->assertNotNull($user);
$cu = CompanyUser::whereUserId($user->id)->whereCompanyId($company2->id)->first();
$this->assertNotNull($cu);
/*Update the user permissions of this user*/
$data = [
'first_name' => 'Captain',
'last_name' => 'Morgain',
'email' => 'bob@good.ole.boys.co2.com',
'company_user' => [
'is_admin' => true,
'is_owner' => false,
'permissions' => 'create_invoice,create_invoice'
],
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $user_1_company_token->token,
])->put('/api/v1/users/'.$this->encodePrimaryKey($user->id).'?include=company_user', $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertNotNull($arr['data']['company_user']);
$this->assertTrue($arr['data']['company_user']['is_admin']);
$this->assertFalse($arr['data']['company_user']['is_owner']);
$this->assertEquals($arr['data']['company_user']['permissions'], 'create_invoice,create_invoice');
}
} }