diff --git a/app/DataMapper/ClientSettings.php b/app/DataMapper/ClientSettings.php index d0b559090b65..8b7935144180 100644 --- a/app/DataMapper/ClientSettings.php +++ b/app/DataMapper/ClientSettings.php @@ -37,6 +37,15 @@ class ClientSettings extends BaseSettings 'size_id' => 'string', ]; + public static $property_casts = [ + 'language_id' => 'string', + 'currency_id' => 'string', + 'payment_terms' => 'string', + 'valid_until' => 'string', + 'default_task_rate' => 'float', + 'send_reminders' => 'bool', + ]; + /** * Cast object values and return entire class * prevents missing properties from not being returned diff --git a/app/Factory/CloneQuoteToInvoiceFactory.php b/app/Factory/CloneQuoteToInvoiceFactory.php index 936ca18c5706..f2277c4eeb9f 100644 --- a/app/Factory/CloneQuoteToInvoiceFactory.php +++ b/app/Factory/CloneQuoteToInvoiceFactory.php @@ -28,7 +28,11 @@ class CloneQuoteToInvoiceFactory unset($quote_array['invoice_id']); unset($quote_array['id']); unset($quote_array['invitations']); - unset($quote_array['terms']); + + //preserve terms if they exist on Quotes + if(strlen($quote_array['terms']) < 2) + unset($quote_array['terms']); + // unset($quote_array['public_notes']); unset($quote_array['footer']); unset($quote_array['design_id']); diff --git a/app/Utils/Traits/ClientGroupSettingsSaver.php b/app/Utils/Traits/ClientGroupSettingsSaver.php index a7dabe4f2076..d04e830413ec 100644 --- a/app/Utils/Traits/ClientGroupSettingsSaver.php +++ b/app/Utils/Traits/ClientGroupSettingsSaver.php @@ -11,6 +11,7 @@ namespace App\Utils\Traits; +use App\DataMapper\ClientSettings; use App\DataMapper\CompanySettings; use stdClass; @@ -63,15 +64,6 @@ trait ClientGroupSettingsSaver $entity_settings->{$key} = $value; } - //this pass will handle any null values that are in the translations - // foreach ($settings->translations as $key => $value) { - // if (is_null($settings->translations[$key])) { - // $settings->translations[$key] = ''; - // } - // } - - // $entity_settings->translations = $settings->translations; - $entity->settings = $entity_settings; $entity->save(); @@ -92,6 +84,8 @@ trait ClientGroupSettingsSaver $settings = (object) $settings; $casts = CompanySettings::$casts; + // $casts = ClientSettings::$property_casts; + ksort($casts); if(property_exists($settings, 'translations')) @@ -121,7 +115,7 @@ trait ClientGroupSettingsSaver continue; } /*Separate loop if it is a _id field which is an integer cast as a string*/ - elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter') { + elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter' || $key == 'payment_terms' || $key == 'valid_until') { $value = 'integer'; if (! property_exists($settings, $key)) { @@ -170,7 +164,7 @@ trait ClientGroupSettingsSaver } /*Separate loop if it is a _id field which is an integer cast as a string*/ - if (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter') { + if (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter' || $key == 'payment_terms' || $key == 'valid_until') { $value = 'integer'; if (! property_exists($settings, $key)) { diff --git a/app/Utils/Traits/SettingsSaver.php b/app/Utils/Traits/SettingsSaver.php index fbcc7d44e1ad..764e18403145 100644 --- a/app/Utils/Traits/SettingsSaver.php +++ b/app/Utils/Traits/SettingsSaver.php @@ -52,7 +52,7 @@ trait SettingsSaver continue; } /*Separate loop if it is a _id field which is an integer cast as a string*/ - elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter') { + elseif (substr($key, -3) == '_id' || substr($key, -14) == 'number_counter' || $key == 'payment_terms' || $key == 'valid_until') { $value = 'integer'; if($key == 'gmail_sending_user_id') diff --git a/tests/Unit/ClientSettingsTest.php b/tests/Unit/ClientSettingsTest.php new file mode 100644 index 000000000000..ea224af9d914 --- /dev/null +++ b/tests/Unit/ClientSettingsTest.php @@ -0,0 +1,337 @@ +makeTestData(); + + $this->faker = \Faker\Factory::create(); + + } + + + public function testClientBaseline() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals("1", $arr['data']['settings']['currency_id']); + + } + + + public function testClientValidSettings() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => '1', + 'payment_terms' => '1', + 'valid_until' => '1', + 'default_task_rate' => 10, + 'send_reminders' => true + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(200); + + $arr = $response->json(); + + $this->assertEquals("1", $arr['data']['settings']['currency_id']); + $this->assertEquals("1", $arr['data']['settings']['language_id']); + $this->assertEquals("1", $arr['data']['settings']['payment_terms']); + $this->assertEquals(10, $arr['data']['settings']['default_task_rate']); + $this->assertEquals(true, $arr['data']['settings']['send_reminders']); + $this->assertEquals("1", $arr['data']['settings']['valid_until']); + + } + + public function testClientIllegalCurrency() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => 'a', + 'language_id' => '1', + 'payment_terms' => '1', + 'valid_until' => '1', + 'default_task_rate' => 10, + 'send_reminders' => true + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(302); + + } + + public function testClientIllegalLanguage() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => 'a', + 'payment_terms' => '1', + 'valid_until' => '1', + 'default_task_rate' => 10, + 'send_reminders' => true + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(302); + + } + + public function testClientIllegalPaymenTerms() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => '1', + 'payment_terms' => 'a', + 'valid_until' => '1', + 'default_task_rate' => 10, + 'send_reminders' => true + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(302); + + } + + + public function testClientIllegalValidUntil() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => '1', + 'payment_terms' => '1', + 'valid_until' => 'a', + 'default_task_rate' => 10, + 'send_reminders' => true + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(302); + + } + + public function testClientIllegalDefaultTaskRate() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => '1', + 'payment_terms' => '1', + 'valid_until' => '1', + 'default_task_rate' => "a", + 'send_reminders' => true + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(200); + $arr = $response->json(); + + $this->assertFalse(array_key_exists('default_task_rate', $arr)); + + } + + public function testClientIllegalSendReminderBool() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => '1', + 'payment_terms' => '1', + 'valid_until' => '1', + 'default_task_rate' => "a", + 'send_reminders' => "faaalse" + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(302); + + } + + public function testClientSettingBools() + { + + $data = [ + 'name' => $this->faker->firstName, + 'id_number' => 'Coolio', + 'settings' => [ + 'currency_id' => '1', + 'language_id' => '1', + 'payment_terms' => '1', + 'valid_until' => '1', + 'default_task_rate' => "a", + 'send_reminders' => "true" + ] + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/', $data); + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(200); + + + } + +}