diff --git a/app/DataMapper/Settings/SettingsData.php b/app/DataMapper/Settings/SettingsData.php new file mode 100644 index 000000000000..b76379806ff6 --- /dev/null +++ b/app/DataMapper/Settings/SettingsData.php @@ -0,0 +1,515 @@ + $value) { + + try{ + settype($object->{$key}, gettype($this->{$key})); + } + catch(\Exception | \Error | \Throwable $e){ + + if(property_exists($this, $key)) + $object->{$key} = $this->{$key}; + else + unset($object->{$key}); + + } + + // if(!property_exists($this, $key)) { + // unset($object->{$key}); + // } + // elseif(is_array($object->{$key}) && gettype($this->{$key} != 'array')){ + // $object->{$key} = $this->{$key}; + // } + // else { + // settype($object->{$key}, gettype($this->{$key})); + // } + } + } + $this->object = $object; + + return $this; + } + + public function toObject(): object + { + return (object)$this->object; + } + + public function toArray(): array + { + return (array)$this->object; + } +} \ No newline at end of file diff --git a/app/Http/Requests/GroupSetting/StoreGroupSettingRequest.php b/app/Http/Requests/GroupSetting/StoreGroupSettingRequest.php index 7099cc6317ae..d35e7ac2bc78 100644 --- a/app/Http/Requests/GroupSetting/StoreGroupSettingRequest.php +++ b/app/Http/Requests/GroupSetting/StoreGroupSettingRequest.php @@ -11,11 +11,13 @@ namespace App\Http\Requests\GroupSetting; -use App\DataMapper\ClientSettings; -use App\Http\Requests\Request; -use App\Http\ValidationRules\ValidClientGroupSettingsRule; use App\Models\Account; use App\Models\GroupSetting; +use App\Http\Requests\Request; +use App\DataMapper\ClientSettings; +use App\DataMapper\CompanySettings; +use App\DataMapper\Settings\SettingsData; +use App\Http\ValidationRules\ValidClientGroupSettingsRule; class StoreGroupSettingRequest extends Request { @@ -48,15 +50,12 @@ class StoreGroupSettingRequest extends Request { $input = $this->all(); - $group_settings = ClientSettings::defaults(); - - if (array_key_exists('settings', $input) && ! empty($input['settings'])) { - foreach ($input['settings'] as $key => $value) { - $group_settings->{$key} = $value; - } + if (array_key_exists('settings', $input)) { + $input['settings'] = $this->filterSaveableSettings($input['settings']); + } + else { + $input['settings'] = (array)ClientSettings::defaults(); } - - $input['settings'] = (array)$group_settings; $this->replace($input); } @@ -67,4 +66,38 @@ class StoreGroupSettingRequest extends Request 'settings' => 'settings must be a valid json structure', ]; } + + /** + * For the hosted platform, we restrict the feature settings. + * + * This method will trim the company settings object + * down to the free plan setting properties which + * are saveable + * + * @param object $settings + * @return array $settings + */ + private function filterSaveableSettings($settings) + { + /** @var \App\Models\User $user */ + $user = auth()->user(); + + $settings_data = new SettingsData(); + $settings = $settings_data->cast($settings)->toObject(); + + if (! $user->account->isFreeHostedClient()) { + return (array)$settings; + } + + $saveable_casts = CompanySettings::$free_plan_casts; + + foreach ($settings as $key => $value) { + if (! array_key_exists($key, $saveable_casts)) { + unset($settings->{$key}); + } + } + + return (array)$settings; + } + } diff --git a/app/Http/Requests/GroupSetting/UpdateGroupSettingRequest.php b/app/Http/Requests/GroupSetting/UpdateGroupSettingRequest.php index 84120cc3475a..a264d74c018d 100644 --- a/app/Http/Requests/GroupSetting/UpdateGroupSettingRequest.php +++ b/app/Http/Requests/GroupSetting/UpdateGroupSettingRequest.php @@ -11,8 +11,9 @@ namespace App\Http\Requests\GroupSetting; -use App\DataMapper\CompanySettings; use App\Http\Requests\Request; +use App\DataMapper\CompanySettings; +use App\DataMapper\Settings\SettingsData; use App\Http\ValidationRules\ValidClientGroupSettingsRule; class UpdateGroupSettingRequest extends Request @@ -62,10 +63,14 @@ class UpdateGroupSettingRequest extends Request */ private function filterSaveableSettings($settings) { - $account = $this->group_setting->company->account; + /** @var \App\Models\User $user */ + $user = auth()->user(); - if (! $account->isFreeHostedClient()) { - return $settings; + $settings_data = new SettingsData(); + $settings = $settings_data->cast($settings)->toObject(); + + if (! $user->account->isFreeHostedClient()) { + return (array)$settings; } $saveable_casts = CompanySettings::$free_plan_casts; @@ -75,7 +80,7 @@ class UpdateGroupSettingRequest extends Request unset($settings->{$key}); } } - + return (array)$settings; } } diff --git a/tests/Feature/GroupSettingTest.php b/tests/Feature/GroupSettingTest.php index da637d39506c..98bad3daa703 100644 --- a/tests/Feature/GroupSettingTest.php +++ b/tests/Feature/GroupSettingTest.php @@ -11,20 +11,21 @@ namespace Tests\Feature; +use Tests\TestCase; +use Tests\MockAccountData; use App\Utils\Traits\MakesHash; use Illuminate\Database\Eloquent\Model; -use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Session; -use Tests\MockAccountData; -use Tests\TestCase; +use App\DataMapper\Settings\SettingsData; +use Spatie\LaravelData\Support\Wrapping\WrapExecutionType; class GroupSettingTest extends TestCase { use MakesHash; - - //use DatabaseTransactions; use MockAccountData; + public $faker; + protected function setUp(): void { parent::setUp(); @@ -38,6 +39,85 @@ class GroupSettingTest extends TestCase $this->makeTestData(); } + public function testCastingMagic() + { + + $settings = new \stdClass; + $settings->currency_id = '1'; + $settings->tax_name1 = ''; + $settings->tax_rate1 = 0; + $s = new SettingsData(); + $settings = $s->cast($settings)->toObject(); + + $this->assertEquals("", $settings->tax_name1); + $settings = null; + + $settings = new \stdClass; + $settings->currency_id = '1'; + $settings->tax_name1 = "1"; + $settings->tax_rate1 = 0; + + $settings = $s->cast($settings)->toObject(); + + $this->assertEquals("1", $settings->tax_name1); + + $settings = $s->cast($settings)->toArray(); + $this->assertEquals("1", $settings['tax_name1']); + + $settings = new \stdClass; + $settings->currency_id = '1'; + $settings->tax_name1 = []; + $settings->tax_rate1 = 0; + + $settings = $s->cast($settings)->toObject(); + + $this->assertEquals("", $settings->tax_name1); + + $settings = $s->cast($settings)->toArray(); + $this->assertEquals("", $settings['tax_name1']); + + $settings = new \stdClass; + $settings->currency_id = '1'; + $settings->tax_name1 = new \stdClass; + $settings->tax_rate1 = 0; + + $settings = $s->cast($settings)->toObject(); + + $this->assertEquals("", $settings->tax_name1); + + $settings = $s->cast($settings)->toArray(); + $this->assertEquals("", $settings['tax_name1']); + + + + // nlog(json_encode($settings)); + } + + public function testTaxNameInGroupFilters() + { + $settings = new \stdClass; + $settings->currency_id = '1'; + $settings->tax_name1 = ''; + $settings->tax_rate1 = 0; + + $data = [ + 'name' => 'testX', + 'settings' => $settings, + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/group_settings', $data); + + $response->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals("", (string)NULL); + $this->assertNotNull($arr['data']['settings']['tax_name1']); + } + public function testAddGroupFilters() { diff --git a/tests/Unit/GroupSettingsTest.php b/tests/Unit/GroupSettingsTest.php index 6dd5b662eba0..4874753e5fa2 100644 --- a/tests/Unit/GroupSettingsTest.php +++ b/tests/Unit/GroupSettingsTest.php @@ -28,6 +28,10 @@ class GroupSettingsTest extends TestCase use DatabaseTransactions; use ClientGroupSettingsSaver; + public $company_settings; + public $client_settings; + public $settings; + protected function setUp() :void { parent::setUp();