Working on cascading settings

This commit is contained in:
David Bomba 2019-09-11 15:32:47 +10:00
parent af28b02fae
commit ac19a4bb12
15 changed files with 170 additions and 72 deletions

View File

@ -93,7 +93,10 @@ class LoginController extends BaseController
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return response()->json(['message' => 'Too many login attempts, you are being throttled'], 401)->header('X-API-VERSION', config('ninja.api_version'));
return response()
->json(['message' => 'Too many login attempts, you are being throttled'], 401)
->header('X-App-Version', config('ninja.app_version'))
->header('X-Api-Version', config('ninja.api_version'));
}
if ($this->attemptLogin($request)) {
@ -108,7 +111,10 @@ class LoginController extends BaseController
$this->incrementLoginAttempts($request);
return response()->json(['message' => ctrans('texts.invalid_credentials')], 401)->header('X-API-VERSION', config('ninja.api_version'));
return response()
->json(['message' => ctrans('texts.invalid_credentials')], 401)
->header('X-App-Version', config('ninja.app_version'))
->header('X-Api-Version', config('ninja.api_version'));
}
}

View File

@ -110,7 +110,8 @@ class BaseController extends Controller
{
return response()->json(['message' => '404 | Nothing to see here!'], 404)
->header('X-API-VERSION', config('ninja.api_version'));
->header('X-Api-Version', config('ninja.api_version'))
->header('X-App-Version', config('ninja.app_version'));
}
@ -239,7 +240,8 @@ class BaseController extends Controller
//'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
//'Access-Control-Allow-Credentials' => 'true',
//'X-Total-Count' => $count,
'X-API-VERSION' => config('ninja.api_version'),
'X-Api-Version' => config('ninja.api_version'),
'X-App-Version' => config('ninja.app_version'),
//'X-Rate-Limit-Limit' - The number of allowed requests in the current period
//'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
//'X-Rate-Limit-Reset' - The number of seconds left in the current period,

View File

@ -132,7 +132,7 @@ class InvoiceController extends Controller
});
$formatted_total = Number::formatMoney($total, auth()->user()->client->currency, auth()->user()->client->country, auth()->user()->client->getMergedSettings());
$formatted_total = Number::formatMoney($total, auth()->user()->client);
$payment_methods = auth()->user()->client->getPaymentMethods($total);

View File

@ -32,7 +32,10 @@ class ApiSecretCheck
$error['error'] = ['message' => 'Invalid secret'];
return response()->json(json_encode($error, JSON_PRETTY_PRINT) ,403)->header('X-API-VERSION', config('ninja.api_version'));
return response()
->json(json_encode($error, JSON_PRETTY_PRINT) ,403)
->header('X-App-Version', config('ninja.app_version'))
->header('X-API-VERSION', config('ninja.api_version'));
}

View File

@ -38,7 +38,6 @@ class Client extends BaseModel
use SoftDeletes;
use Filterable;
use GeneratesCounter;
use CompanyGatewaySettings;
protected $presenter = 'App\Models\Presenters\ClientPresenter';
@ -128,27 +127,36 @@ class Client extends BaseModel
public function timezone()
{
return Timezone::find($this->getMergedSettings()->timezone_id);
return Timezone::find($this->getSetting('timezone_id'));
}
public function date_format()
{
return $this->getMergedSettings()->date_format;
return $this->getSetting('date_format');
}
public function datetime_format()
{
return $this->getMergedSettings()->datetime_format;
return $this->getSetting('datetime_format');
}
public function currency()
{
return $this->belongsTo(Currency::class);
//return Currency::find($this->getMergedSettings()->currency_id);
}
public function getMergedSettings()
{
if($this->group_settings !== null)
{
$group_settings = ClientSettings::buildClientSettings(new ClientSettings($this->group_settings()), new ClientSettings($this->settings));
return ClientSettings::buildClientSettings(new CompanySettings($this->company->settings), $group_settings);
}
return ClientSettings::buildClientSettings(new CompanySettings($this->company->settings), new ClientSettings($this->settings));
}
@ -170,7 +178,7 @@ class Client extends BaseModel
return $this->settings->{$setting};
//check group level (if a group is assigned)
if($this->group_settings && isset($this->group_settings->{$setting}) && property_exists($this->group_settings, $setting))
if($this->group_settings && isset($this->group_settings->settings->{$setting}) && property_exists($this->group_settings->settings, $setting))
return $this->group_settings->{$setting};
//check company level
@ -206,11 +214,11 @@ class Client extends BaseModel
*/
public function getPaymentMethods($amount) :array
{
$settings = $this->getMergedSettings();
$payment_gateways = $this->getSetting('payment_gateways');
/* If we have a custom gateway list pass this back first */
if($settings->payment_gateways)
$gateways = $this->company->company_gateways->whereIn('id', $settings->payment_gateways);
if($settings)
$gateways = $this->company->company_gateways->whereIn('id', $payment_gateways);
else
$gateways = $this->company->company_gateways;

View File

@ -151,7 +151,7 @@ class CompanyGateway extends BaseModel
$fee = $this->calcGatewayFee($amount);
if($fee > 0 ){
$fee = Number::formatMoney(round($fee, 2), $client->currency, $client->country(), $client->getMergedSettings());
$fee = Number::formatMoney(round($fee, 2), $client);
$label = ' - ' . $fee . ' ' . ctrans('texts.fee');
}

View File

@ -13,14 +13,18 @@ namespace App\Models;
use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings;
use App\Models\Client;
use App\Models\Company;
use App\Models\User;
use App\Utils\Traits\MakesHash;
use Hashids\Hashids;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;
class GroupSetting extends BaseModel
class GroupSetting extends Model
{
public $timestamps = false;
protected $casts = [
'settings' => 'object'
];
@ -35,5 +39,10 @@ class GroupSetting extends BaseModel
return $this->belongsTo(User::class);
}
public function clients()
{
return $this->hasMany(Client::class, 'id', 'group_settings_id');
}
}

View File

@ -169,7 +169,7 @@ class Invoice extends BaseModel
*/
public function isLocked() : bool
{
return $this->client->getMergedSettings()->lock_sent_invoices;
return $this->client->getSetting('lock_sent_invoices');
}
/**
@ -252,7 +252,7 @@ class Invoice extends BaseModel
public function calc()
{
$invoice_calc = new InvoiceCalc($this, $this->client->getMergedSettings());
$invoice_calc = new InvoiceCalc($this, $this->settings);
return $invoice_calc->build();

View File

@ -1,47 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Utils\Traits;
/**
* Class CompanyGatewaySettings
* @package App\Utils\Traits
*/
trait CompanyGatewaySettings
{
/**
*
* This method will cascade through a sequence of
* levels and return the first available set of settings
* it hits
*
* @return array A single dimension array of company gateway ids
*/
public function findCompanyGateways()
{
$settings = $this->getMergedSettings();
/* Group Level */
if(isset($settings->groups->company_gateways)){
$gateways = $this->company->company_gateways->whereIn('id', $settings->group_selectors->{$settings->group->company_gateways});
}
/* Client Level - Company Level*/
else if(isset($settings->company_gateways)) {
$gateways = $this->company->company_gateways->whereIn('id', $settings->company_gateways);
}
/* DB raw*/
else
return $this->company->company_gateways;
}
}

View File

@ -920,8 +920,6 @@ class CreateUsersTable extends Migration
$table->unsignedInteger('user_id')->nullable();
$table->string('name');
$table->text('settings');
$table->boolean('is_default')->default(false);
$table->timestamps(6);
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
});

View File

@ -123,7 +123,6 @@ class RandomDataSeeder extends Seeder
GroupSetting::create([
'company_id' => $company->id,
'user_id' => $user->id,
'is_default' =>true,
'settings' => ClientSettings::buildClientSettings(new CompanySettings(CompanySettings::defaults()), new ClientSettings(ClientSettings::defaults())),
'name' => 'Default Client Settings',
]);

View File

@ -245,7 +245,7 @@ class ClientTest extends TestCase
$this->assertNotNull($client);
/* Make sure we have a valid settings object*/
$this->assertEquals($client->getMergedSettings()->timezone_id, 15);
$this->assertEquals($client->getSetting('timezone_id'), 15);
/* Make sure we are harvesting valid data */
$this->assertEquals($client->timezone()->name, 'US/Eastern');

View File

@ -45,8 +45,8 @@ class UserTest extends TestCase
$data = [
'first_name' => $this->faker->firstName,
'last_name' => $this->faker->lastName,
'name' => $this->faker->company,
'email' => $this->faker->unique()->safeEmail,
'name' => $this->faker->company,
'email' => $this->faker->unique()->safeEmail,
'password' => 'ALongAndBrilliantPassword123',
'_token' => csrf_token(),
'privacy_policy' => 1,

View File

@ -11,6 +11,7 @@
namespace Tests;
use App\DataMapper\ClientSettings;
use App\Factory\ClientFactory;
use App\Factory\InvoiceFactory;
use App\Factory\InvoiceItemFactory;
@ -19,6 +20,7 @@ use App\Helpers\Invoice\InvoiceCalc;
use App\Jobs\Company\UpdateCompanyLedgerWithInvoice;
use App\Models\Client;
use App\Models\Credit;
use App\Models\GroupSetting;
use App\Models\Invoice;
use App\Models\Quote;
use App\Models\RecurringInvoice;
@ -66,6 +68,17 @@ trait MockAccountData
$this->client = ClientFactory::create($this->company->id, $this->user->id);
$this->client->save();
$gs = new GroupSetting;
$gs->name = 'Test';
$gs->company_id = $this->client->company_id;
$gs->settings = new ClientSettings(ClientSettings::defaults());
$gs->save();
$this->client->group_settings_id = $gs->id;
$this->client->save();
$this->invoice = InvoiceFactory::create($this->company->id,$this->user->id);//stub the company and user_id
$this->invoice->client_id = $this->client->id;

View File

@ -0,0 +1,107 @@
<?php
namespace Tests\Unit;
use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings;
use App\Models\GroupSetting;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test
* @covers App\Models\Client
*/
class GroupSettingsTest extends TestCase
{
use MockAccountData;
use DatabaseTransactions;
public function setUp() :void
{
parent::setUp();
$this->makeTestData();
$this->company_settings = CompanySettings::defaults();
$this->client->settings = new ClientSettings(ClientSettings::defaults());
}
public function testCompanyDefaults()
{
$this->company_settings->timezone_id = 'fluffy';
$this->client->company->settings = $this->company_settings;
$this->assertEquals($this->client->company->settings->timezone_id, 'fluffy');
$this->assertEquals($this->client->getSetting('timezone_id'), 'fluffy');
$this->assertEquals($this->client->getMergedSettings()->timezone_id, 'fluffy');
}
public function testGroupDefaults()
{
$cs = $this->client->company->settings;
$cs->timezone_id = NULL;
$this->client->company->settings = $cs;
$gs = $this->client->group_settings->settings;
$gs->timezone_id = 'SPOCK';
$this->client->group_settings->settings = $gs;
$cls = $this->client->settings;
$cls->timezone_id = NULL;
$cls->date_format = 'sharleen';
$this->client->settings = $cls;
$this->client->group_settings->save();
$this->client->company->save();
$this->client->save();
$this->client->fresh();
// \Log::error(print_r($this->client,1));
\Log::error(print_r($this->client->settings,1));
\Log::error(print_r($this->client->settings->timezone_id,1));
\Log::error(print_r($this->client->settings->date_format,1));
\Log::error(print_r($this->client->group_settings->settings->timezone_id,1));
\Log::error(print_r($this->client->group_settings->settings,1));
\Log::error(print_r($this->client->company->settings->timezone_id,1));
$this->assertEquals($this->client->group_settings->settings->timezone_id, 'SPOCK');
$this->assertEquals($this->client->getSetting('timezone_id'), 'SPOCK');
$this->assertEquals($this->client->getMergedSettings()->timezone_id, 'SPOCK');
}
public function testClientDefaults()
{
$this->company_settings->timezone_id = NULL;
$this->client->group_settings->settings->timezone_id = NULL;
$this->client->settings->timezone_id = 'SCOTTY';
$this->client->company->settings = $this->company_settings;
$this->client->save();
$this->client->company->save();
$this->client->group_settings->save();
$this->assertEquals($this->client->settings->timezone_id, 'SCOTTY');
$this->assertEquals($this->client->getSetting('timezone_id'), 'SCOTTY');
$this->assertEquals($this->client->getMergedSettings()->timezone_id, 'SCOTTY');
}
}