diff --git a/app/DataMapper/ClientSettings.php b/app/DataMapper/ClientSettings.php index dc60f7ea3dfa..f6a0e62a2a7e 100644 --- a/app/DataMapper/ClientSettings.php +++ b/app/DataMapper/ClientSettings.php @@ -5,6 +5,7 @@ namespace App\DataMapper; use App\DataMapper\ClientSettings; use App\DataMapper\CompanySettings; use App\Utils\TranslationHelper; +use Illuminate\Support\Facades\Log; /** * ClientSettings @@ -99,7 +100,7 @@ class ClientSettings extends BaseSettings * @param \stdClass $client_settings * @return \stdClass of merged settings */ - public static function buildClientSettings(CompanySettings $company_settings, ClientSettings $client_settings) : ClientSettings + public static function buildClientSettings($company_settings, $client_settings) { @@ -111,7 +112,6 @@ class ClientSettings extends BaseSettings } - return $client_settings; } diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index 2451b243f148..261d69a91038 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -55,6 +55,9 @@ class CompanySettings extends BaseSettings public $custom_expense_label3; public $custom_expense_label4; + public $custom_taxes1; + public $custom_taxes2; + public $default_task_rate; public $send_reminders; public $show_tasks_in_portal; diff --git a/app/Factory/InvoiceFactory.php b/app/Factory/InvoiceFactory.php index f170c61661c3..1b3be6898506 100644 --- a/app/Factory/InvoiceFactory.php +++ b/app/Factory/InvoiceFactory.php @@ -2,7 +2,10 @@ namespace App\Factory; +use App\DataMapper\ClientSettings; +use App\DataMapper\CompanySettings; use App\Models\Invoice; +use Illuminate\Support\Facades\Log; class InvoiceFactory { @@ -18,7 +21,7 @@ class InvoiceFactory $invoice->due_date = null; $invoice->is_deleted = false; $invoice->line_items = json_encode([]); - $invoice->settings = json_encode([]); //todo need to embed the settings here + $invoice->settings = ClientSettings::buildClientSettings(CompanySettings::defaults(), ClientSettings::defaults()); //todo need to embed the settings here $invoice->backup = json_encode([]); $invoice->tax_name1 = ''; $invoice->tax_rate1 = 0; @@ -33,7 +36,7 @@ class InvoiceFactory $invoice->partial = 0; $invoice->user_id = $user_id; $invoice->company_id = $company_id; - + return $invoice; } } diff --git a/app/Helpers/Invoice/InvoiceCalc.php b/app/Helpers/Invoice/InvoiceCalc.php index d1565c2f7f15..0546358e1c8f 100644 --- a/app/Helpers/Invoice/InvoiceCalc.php +++ b/app/Helpers/Invoice/InvoiceCalc.php @@ -6,6 +6,7 @@ use App\Helpers\Invoice\InvoiceItemCalc; use App\Models\Invoice; use App\Utils\Traits\NumberFormatter; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; /** * Class for invoice calculations. @@ -57,6 +58,9 @@ class InvoiceCalc */ public function build() { + + Log::error($this->invoice); + $this->calcLineItems() ->calcDiscount() ->calcCustomValues() @@ -121,20 +125,20 @@ class InvoiceCalc { // custom fields charged taxes - if ($this->invoice->custom_value1 && $this->settings->custom_taxes1) { + if (isset($this->invoice->custom_value1) && $this->settings->custom_taxes1) { $this->total += $this->invoice->custom_value1; } - if ($this->invoice->custom_value2 && $this->invoice->custom_taxes2) { + if (isset($this->invoice->custom_value2) && $this->invoice->custom_taxes2) { $this->total += $this->invoice->custom_value2; } $this->calcTaxes(); // custom fields not charged taxes - if ($this->invoice->custom_value1 && ! $this->settings->custom_taxes1) { + if (isset($this->invoice->custom_value1) && ! $this->settings->custom_taxes1) { $this->total += $this->invoice->custom_value1; } - if ($this->invoice->custom_value2 && ! $this->settings->custom_taxes2) { + if (isset($this->invoice->custom_value2) && ! $this->settings->custom_taxes2) { $this->total += $this->invoice->custom_value2; } @@ -164,6 +168,8 @@ class InvoiceCalc */ private function calcLineItems() { + if(!$this->invoice->line_items || count($this->invoice->line_items) == 0) + return $this; $new_line_items = []; diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 022503d5b941..c6b0f5e31622 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Factory\InvoiceFactory; use App\Filters\InvoiceFilters; use App\Http\Requests\Invoice\CreateInvoiceRequest; +use App\Http\Requests\Invoice\DestroyInvoiceRequest; use App\Http\Requests\Invoice\EditInvoiceRequest; use App\Http\Requests\Invoice\ShowInvoiceRequest; use App\Http\Requests\Invoice\StoreInvoiceRequest; @@ -122,7 +123,7 @@ class InvoiceController extends BaseController public function update(UpdateInvoiceRequest $request, Invoice $invoice) { - $invoice = $this->invoice_repo->save($request, $invoice); + $invoice = $this->invoice_repo->save(request(), $invoice); return $this->itemResponse($invoice); diff --git a/app/Http/Requests/Invoice/EditInvoiceRequest.php b/app/Http/Requests/Invoice/EditInvoiceRequest.php index a3359226f7cd..4bd9391d0ba1 100644 --- a/app/Http/Requests/Invoice/EditInvoiceRequest.php +++ b/app/Http/Requests/Invoice/EditInvoiceRequest.php @@ -18,6 +18,14 @@ class EditInvoiceRequest extends Request return auth()->user()->can('edit', $this->invoice); } + public function rules() + { + $rules = []; + + return $rules; + } + + public function sanitize() { $input = $this->all(); diff --git a/app/Http/Requests/Invoice/StoreInvoiceRequest.php b/app/Http/Requests/Invoice/StoreInvoiceRequest.php index 91b8634f8574..e72fb694e53b 100644 --- a/app/Http/Requests/Invoice/StoreInvoiceRequest.php +++ b/app/Http/Requests/Invoice/StoreInvoiceRequest.php @@ -18,11 +18,6 @@ class StoreInvoiceRequest extends Request return auth()->user()->can('create', Invoice::class); } - public function rules() - { - - - } public function sanitize() { diff --git a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php index 0e5106c42e72..86cb5604acbe 100644 --- a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php +++ b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php @@ -16,34 +16,8 @@ class UpdateInvoiceRequest extends Request public function authorize() : bool { + return auth()->user()->can('edit', $this->invoice); - } - - public function rules() - { - if (! $this->entity()) { - return []; - } - - $invoiceId = $this->entity()->id; - - $rules = [ - 'client' => 'required', - 'discount' => 'positive', - 'invoice_date' => 'required', - ]; - - return $rules; - } - - public function sanitize() - { - //do post processing of invoice request here, ie. invoice_items - - } - - public function messages() - { } diff --git a/app/Jobs/Company/CreateCompany.php b/app/Jobs/Company/CreateCompany.php index f180dda5ab12..bc49559a4fa3 100644 --- a/app/Jobs/Company/CreateCompany.php +++ b/app/Jobs/Company/CreateCompany.php @@ -43,7 +43,7 @@ class CreateCompany $company->account_id = $this->account->id; $company->company_key = $this->createHash(); $company->ip = request()->ip(); - $company->settings = CompanySettings::defaults(); + $company->settings = new CompanySettings(CompanySettings::defaults()); $company->db = config('database.default'); $company->save(); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 2329900c8600..9cbe771a79a2 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -17,6 +17,10 @@ class Invoice extends BaseModel 'id', ]; + protected $casts = [ + 'settings' => 'object' + ]; + const STATUS_DRAFT = 1; const STATUS_SENT = 2; const STATUS_VIEWED = 3; diff --git a/database/factories/ClientFactory.php b/database/factories/ClientFactory.php index 2114dc443d9e..9aeb10d2c0ce 100644 --- a/database/factories/ClientFactory.php +++ b/database/factories/ClientFactory.php @@ -27,6 +27,6 @@ $factory->define(App\Models\Client::class, function (Faker $faker) { 'shipping_state' => $faker->state, 'shipping_postal_code' => $faker->postcode, 'shipping_country_id' => 4, - 'settings' => ClientSettings::defaults(), + 'settings' => new ClientSettings(ClientSettings::defaults()), ]; }); diff --git a/database/factories/CompanyFactory.php b/database/factories/CompanyFactory.php index dbd58a140b6d..d6cd7e192bf7 100644 --- a/database/factories/CompanyFactory.php +++ b/database/factories/CompanyFactory.php @@ -9,6 +9,6 @@ $factory->define(App\Models\Company::class, function (Faker $faker) { 'company_key' => strtolower(str_random(RANDOM_KEY_LENGTH)), 'ip' => $faker->ipv4, 'db' => config('database.default'), - 'settings' => CompanySettings::defaults(), + 'settings' => new CompanySettings(CompanySettings::defaults()), ]; }); diff --git a/database/factories/InvoiceFactory.php b/database/factories/InvoiceFactory.php index 752516199938..a98de9e98f2e 100644 --- a/database/factories/InvoiceFactory.php +++ b/database/factories/InvoiceFactory.php @@ -1,5 +1,7 @@ define(App\Models\Invoice::class, function (Faker $faker) { @@ -12,15 +14,16 @@ $factory->define(App\Models\Invoice::class, function (Faker $faker) { 'tax_rate1' => 10, 'tax_name2' => 'VAT', 'tax_rate2' => 17.5, - 'custom_value1' => $faker->text(20), - 'custom_value2' => $faker->text(20), - 'custom_value3' => $faker->text(20), - 'custom_value4' => $faker->text(20), + 'custom_value1' => $faker->numberBetween(1,4), + 'custom_value2' => $faker->numberBetween(1,4), + 'custom_value3' => $faker->numberBetween(1,4), + 'custom_value4' => $faker->numberBetween(1,4), 'is_deleted' => false, 'po_number' => $faker->text(10), 'invoice_date' => $faker->date(), 'due_date' => $faker->date(), 'line_items' => false, 'backup' => '', + 'settings' => ClientSettings::buildClientSettings(new CompanySettings(CompanySettings::defaults()), new CompanySettings(ClientSettings::defaults())) ]; }); \ No newline at end of file diff --git a/tests/Feature/ClientTest.php b/tests/Feature/ClientTest.php index c0bd5893228d..2c2cf12f0a05 100644 --- a/tests/Feature/ClientTest.php +++ b/tests/Feature/ClientTest.php @@ -162,7 +162,7 @@ class ClientTest extends TestCase ])->delete('/api/v1/clients/'.$this->encodePrimaryKey($client->id)); $response->assertStatus(200); -/* + $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), @@ -173,7 +173,7 @@ class ClientTest extends TestCase $response->assertStatus(200); -*/ + } } diff --git a/tests/Feature/InvoiceTest.php b/tests/Feature/InvoiceTest.php index 8fa99b2f87df..bec201019558 100644 --- a/tests/Feature/InvoiceTest.php +++ b/tests/Feature/InvoiceTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature; use App\Models\Account; use App\Models\Client; +use App\Models\Invoice; use App\Utils\Traits\MakesHash; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -11,6 +12,10 @@ use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Session; use Tests\TestCase; +/* + * @covers InvoiceController + */ + class InvoiceTest extends TestCase { @@ -81,7 +86,7 @@ class InvoiceTest extends TestCase }); $client = Client::all()->first(); - factory(\App\Models\Invoice::class, 5)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]); + factory(\App\Models\Invoice::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]); $response = $this->withHeaders([ @@ -93,4 +98,92 @@ class InvoiceTest extends TestCase } + public function testInvoiceRESTEndPoints() + { + $data = [ + 'first_name' => $this->faker->firstName, + 'last_name' => $this->faker->lastName, + 'email' => $this->faker->unique()->safeEmail, + 'password' => 'ALongAndBrilliantPassword123', + '_token' => csrf_token(), + 'privacy_policy' => 1, + 'terms_of_service' => 1 + ]; + + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + ])->post('/api/v1/signup', $data); + + $acc = $response->json(); + + $account = Account::find($acc['id']); + + $company_token = $account->default_company->tokens()->first(); + $token = $company_token->token; + $company = $company_token->company; + + $user = $company_token->user; + + $this->assertNotNull($company_token); + $this->assertNotNull($token); + $this->assertNotNull($user); + $this->assertNotNull($company); + $this->assertNotNull($user->tokens->first()->company); + + factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){ + + factory(\App\Models\ClientContact::class,1)->create([ + 'user_id' => $user->id, + 'client_id' => $c->id, + 'company_id' => $company->id, + 'is_primary' => 1 + ]); + + factory(\App\Models\ClientContact::class,1)->create([ + 'user_id' => $user->id, + 'client_id' => $c->id, + 'company_id' => $company->id + ]); + + }); + $client = Client::all()->first(); + + factory(\App\Models\Invoice::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]); + + $invoice = Invoice::where('user_id',$user->id)->first(); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $token, + ])->get('/api/v1/invoices/'.$this->encodePrimaryKey($invoice->id)); + + $response->assertStatus(200); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $token, + ])->get('/api/v1/invoices/'.$this->encodePrimaryKey($invoice->id).'/edit'); + + $response->assertStatus(200); + + $invoice_update = [ + 'invoice_status_id' => Invoice::STATUS_PAID + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $token, + ])->put('/api/v1/invoices/'.$this->encodePrimaryKey($invoice->id), $invoice_update) + ->assertStatus(200); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $token, + ])->delete('/api/v1/invoices/'.$this->encodePrimaryKey($invoice->id)); + + $response->assertStatus(200); + + } + } diff --git a/tests/Unit/CompareObjectTest.php b/tests/Unit/CompareObjectTest.php index ad11cb75581c..de14db9ed01a 100644 --- a/tests/Unit/CompareObjectTest.php +++ b/tests/Unit/CompareObjectTest.php @@ -18,8 +18,8 @@ class CompanyObjectTest extends TestCase parent::setUp(); - $this->client_settings = ClientSettings::defaults(); - $this->company_settings = CompanySettings::defaults(); + $this->client_settings = new ClientSettings(ClientSettings::defaults()); + $this->company_settings = new CompanySettings(CompanySettings::defaults()); }