diff --git a/src/VatCalculator.php b/src/VatCalculator.php index 74e3c15..6f478e2 100644 --- a/src/VatCalculator.php +++ b/src/VatCalculator.php @@ -4,6 +4,7 @@ use Illuminate\Contracts\Config\Repository; use Mpociot\VatCalculator\Exceptions\VATCheckUnavailableException; +use Mpociot\VatCalculator\Util\ConfigWrapper; use SoapClient; use SoapFault; @@ -521,7 +522,7 @@ class VatCalculator protected $postalCode = ''; /** - * @var Repository + * @var array */ protected $config; @@ -558,16 +559,14 @@ class VatCalculator protected $ukValidationEndpoint = 'https://api.service.hmrc.gov.uk'; /** - * @param \Illuminate\Contracts\Config\Repository + * @param \Illuminate\Contracts\Config\Repository|array */ - public function __construct($config = null) + public function __construct($config = []) { - $this->config = $config; - - $businessCountryKey = 'vat_calculator.business_country_code'; + $this->config = $config instanceof Repository ? $config->get('vat_calculator', []) : $config; - if (isset($this->config) && $this->config->has($businessCountryKey)) { - $this->setBusinessCountryCode($this->config->get($businessCountryKey, '')); + if (isset($this->config['business_country_code'])) { + $this->setBusinessCountryCode($this->config['business_country_code']); } } @@ -579,9 +578,9 @@ public function __construct($config = null) */ public function shouldCollectVAT($countryCode) { - $taxKey = 'vat_calculator.rules.'.strtoupper($countryCode); + $countryCode = strtoupper($countryCode); - return isset($this->taxRules[strtoupper($countryCode)]) || (isset($this->config) && $this->config->has($taxKey)); + return isset($this->taxRules[$countryCode]) || isset($this->config['rules'][$countryCode]); } /** @@ -749,15 +748,16 @@ public function getTaxRateForCountry($countryCode, $company = false, $type = nul */ public function getTaxRateForLocation($countryCode, $postalCode = null, $company = false, $type = null) { - if ($company && strtoupper($countryCode) !== strtoupper($this->businessCountryCode)) { + $countryCode = strtoupper($countryCode); + + if ($company && $countryCode !== strtoupper($this->businessCountryCode)) { return 0; } $taxRules = $this->taxRules; - $taxKey = 'vat_calculator.rules.'.strtoupper($countryCode); - if (isset($this->config) && $this->config->has($taxKey)) { - $configTax = $this->config->get($taxKey, 0); + if (isset($this->config['rules'][$countryCode])) { + $configTax = $this->config['rules'][$countryCode]; if (is_array($configTax)) { $taxRules[$countryCode] = $configTax; @@ -876,7 +876,7 @@ public function getVATDetails($vatNumber) 'vatNumber' => $vatNumber, ]); } catch (SoapFault $e) { - if (isset($this->config) && $this->config->get('vat_calculator.forward_soap_faults')) { + if ($this->config['forward_soap_faults'] ?? false) { throw new VATCheckUnavailableException($e->getMessage(), $e->getCode(), $e->getPrevious()); } @@ -902,8 +902,8 @@ public function initSoapClient() // Set's default timeout time. $timeout = 30; - if (isset($this->config) && $this->config->has('vat_calculator.soap_timeout')) { - $timeout = $this->config->get('vat_calculator.soap_timeout'); + if (isset($this->config['soap_timeout'])) { + $timeout = $this->config['soap_timeout']; } $context = stream_context_create(['http' => ['timeout' => $timeout]]); @@ -911,7 +911,7 @@ public function initSoapClient() try { $this->soapClient = new SoapClient(self::VAT_SERVICE_URL, ['stream_context' => $context]); } catch (SoapFault $e) { - if (isset($this->config) && $this->config->get('vat_calculator.forward_soap_faults')) { + if ($this->config['forward_soap_faults'] ?? false) { throw new VATCheckUnavailableException($e->getMessage(), $e->getCode(), $e->getPrevious()); } diff --git a/tests/VatCalculatorTest.php b/tests/VatCalculatorTest.php index 50e048f..6c2d8ea 100644 --- a/tests/VatCalculatorTest.php +++ b/tests/VatCalculatorTest.php @@ -23,15 +23,10 @@ public function testCalculateVatWithoutCountry() { $config = m::mock(Repository::class); - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); - - $config->shouldReceive('has') + $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $net = 25.00; @@ -56,17 +51,16 @@ public function testCalculateVatWithPredefinedRules() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.rules.DE') - ->andReturn(false); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => [ + 'rate' => 0.19, + 'exceptions' => [], + ], + ], + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculate($net, $countryCode); @@ -97,18 +91,12 @@ public function testCalculateVatWithPredefinedRulesOverwrittenByConfiguration() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with($taxKey, 0) - ->andReturn(0.50); - - $config->shouldReceive('has') - ->once() - ->with($taxKey) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.50, + ] + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculate($net, $countryCode); @@ -125,18 +113,12 @@ public function testCalculatVatWithCountryDirectSet() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.'.$countryCode, 0) - ->andReturn(0.19); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.'.$countryCode) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.19, + ] + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculate($net, $countryCode); @@ -165,18 +147,12 @@ public function testCalculatVatWithCountryPreviousSet() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.'.$countryCode, 0) - ->andReturn(0.19); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.'.$countryCode) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.19, + ] + ]); $vatCalculator = new VatCalculator($config); $vatCalculator->setCountryCode($countryCode); @@ -196,12 +172,9 @@ public function testCalculatVatWithCountryAndCompany() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculate($net, $countryCode, $postalCode, $company); @@ -218,12 +191,9 @@ public function testCalculatVatWithCountryAndCompanySet() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $vatCalculator->setCompany($company); @@ -242,12 +212,9 @@ public function testCalculatVatWithCountryAndCompanyBothSet() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $vatCalculator->setCountryCode($countryCode); @@ -265,18 +232,12 @@ public function testGetTaxRateForLocationWithCountry() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.'.$countryCode, 0) - ->andReturn(0.19); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.'.$countryCode) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.19, + ], + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->getTaxRateForLocation($countryCode); @@ -290,18 +251,12 @@ public function testGetTaxRateForCountry() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.'.$countryCode, 0) - ->andReturn(0.19); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.'.$countryCode) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.19, + ], + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->getTaxRateForCountry($countryCode); @@ -315,12 +270,9 @@ public function testGetTaxRateForLocationWithCountryAndCompany() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->getTaxRateForLocation($countryCode, null, $company); @@ -334,12 +286,9 @@ public function testGetTaxRateForCountryAndCompany() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->getTaxRateForCountry($countryCode, $company); @@ -349,11 +298,10 @@ public function testGetTaxRateForCountryAndCompany() public function testCanValidateValidVATNumber() { $config = m::mock(Repository::class); - - $config->shouldReceive('has') + $config->shouldReceive('get') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $result = new \stdClass(); $result->valid = true; @@ -425,14 +373,10 @@ public function testValidateVATNumberReturnsFalseOnSoapFailureWithoutForwarding( ->willThrowException(new \SoapFault('Server', 'Something went wrong')); $config = m::mock(Repository::class); - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); $config->shouldReceive('get') ->once() - ->with('vat_calculator.forward_soap_faults') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatNumber = 'SomeInvalidNumber'; $vatCalculator = new VatCalculator($config); @@ -455,14 +399,10 @@ public function testValidateVATNumberThrowsExceptionOnSoapFailure() ->willThrowException(new \SoapFault('Server', 'Something went wrong')); $config = m::mock(Repository::class); - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); $config->shouldReceive('get') ->once() - ->with('vat_calculator.forward_soap_faults') - ->andReturn(true); + ->with('vat_calculator', []) + ->andReturn(['forward_soap_faults' => true]); $vatNumber = 'SomeInvalidNumber'; $vatCalculator = new VatCalculator($config); @@ -486,11 +426,10 @@ public function testCannotValidateVATNumberWhenServiceIsDown() public function testCanValidateValidUKVATNumber() { $config = m::mock(Repository::class); - - $config->shouldReceive('has') + $config->shouldReceive('get') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $result = new \stdClass(); $result->valid = true; @@ -504,11 +443,10 @@ public function testCanValidateValidUKVATNumber() public function testCanValidateInvalidUKVATNumber() { $config = m::mock(Repository::class); - - $config->shouldReceive('has') + $config->shouldReceive('get') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $result = new \stdClass(); $result->valid = true; @@ -526,22 +464,9 @@ public function testCompanyInBusinessCountryGetsValidVATRate() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.rules.DE') - ->andReturn(false); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(true); - - $config->shouldReceive('get') - ->once() - ->with('vat_calculator.business_country_code', '') - ->andReturn($countryCode); + ->with('vat_calculator', []) + ->andReturn(['business_country_code' => 'DE']); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculate($net, $countryCode, null, true); @@ -649,24 +574,18 @@ public function testPostalCodesWithoutExceptionsOverwrittenByConfiguration() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with($taxKey, 0) + ->with('vat_calculator', []) ->andReturn([ - 'rate' => 0.19, - 'exceptions' => [ - 'Heligoland' => 0.05, + 'rules' => [ + 'DE' => [ + 'rate' => 0.19, + 'exceptions' => [ + 'Heligoland' => 0.05, + ], + ], ], ]); - $config->shouldReceive('has') - ->once() - ->with($taxKey) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); - $vatCalculator = new VatCalculator($config); $postalCode = '27498'; // Heligoland $result = $vatCalculator->calculate($net, 'DE', $postalCode, false); @@ -690,15 +609,14 @@ public function testShouldCollectVATFromConfig() $taxKey = 'vat_calculator.rules.'.strtoupper($countryCode); $config = m::mock(Repository::class); - - $config->shouldReceive('has') - ->with($taxKey) - ->andReturn(true); - - $config->shouldReceive('has') + $config->shouldReceive('get') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'TEST' => 0.19, + ] + ]); $vatCalculator = new VatCalculator($config); $this->assertTrue($vatCalculator->shouldCollectVAT($countryCode)); @@ -707,16 +625,10 @@ public function testShouldCollectVATFromConfig() public function testCalculateNetPriceWithoutCountry() { $config = m::mock(Repository::class); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); - - $config->shouldReceive('has') + $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $gross = 25.00; @@ -741,17 +653,9 @@ public function testCalculateNetPriceWithPredefinedRules() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.DE') - ->andReturn(false); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculateNet($gross, $countryCode); @@ -782,18 +686,12 @@ public function testCalculateNetPriceWithPredefinedRulesOverwrittenByConfigurati $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with($taxKey, 0) - ->andReturn(0.50); - - $config->shouldReceive('has') - ->once() - ->with($taxKey) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.50, + ] + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculateNet($gross, $countryCode); @@ -810,18 +708,12 @@ public function testCalculateNetPriceWithCountryDirectSet() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.'.$countryCode, 0) - ->andReturn(0.19); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.'.$countryCode) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.19, + ] + ]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculateNet($gross, $countryCode); @@ -851,18 +743,12 @@ public function testCalculateNetPriceWithCountryPreviousSet() $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with('vat_calculator.rules.'.$countryCode, 0) - ->andReturn(0.19); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.rules.'.$countryCode) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([ + 'rules' => [ + 'DE' => 0.19, + ] + ]); $vatCalculator = new VatCalculator($config); $vatCalculator->setCountryCode($countryCode); @@ -882,12 +768,9 @@ public function testCalculateNetPriceWithCountryAndCompany() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculateNet($gross, $countryCode, $postalCode, $company); @@ -904,12 +787,9 @@ public function testCalculateNetPriceWithCountryAndCompanySet() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $vatCalculator->setCompany($company); @@ -928,12 +808,9 @@ public function testCalculateNetPriceWithCountryAndCompanyBothSet() $config = m::mock(Repository::class); $config->shouldReceive('get') - ->never(); - - $config->shouldReceive('has') ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); + ->with('vat_calculator', []) + ->andReturn([]); $vatCalculator = new VatCalculator($config); $vatCalculator->setCountryCode($countryCode); @@ -982,25 +859,17 @@ public function testCalculateLowVatVatWithPredefinedRulesOverwrittenByConfigurat $config = m::mock(Repository::class); $config->shouldReceive('get') ->once() - ->with($taxKey, 0) + ->with('vat_calculator', []) ->andReturn([ - 'rate' => 0.19, - 'rates' => [ - 'high' => 0.19, - 'low' => 0.07, + 'DE' => [ + 'rate' => 0.19, + 'rates' => [ + 'high' => 0.19, + 'low' => 0.07, + ], ], ]); - $config->shouldReceive('has') - ->once() - ->with($taxKey) - ->andReturn(true); - - $config->shouldReceive('has') - ->once() - ->with('vat_calculator.business_country_code') - ->andReturn(false); - $vatCalculator = new VatCalculator($config); $result = $vatCalculator->calculate($net, $countryCode, null, null, 'low'); $this->assertEquals(25.68, $result);