mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Fixes (#3116)
* 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:
parent
abcd2fd1bb
commit
75df82a71c
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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",
|
||||||
|
@ -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="______"),
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
@ -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",
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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();
|
||||||
|
@ -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');
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user