'AT', 'phone' => '43', 'en' => 'Austria', 'de' => 'Österreich', 'es' => 'Austria', 'fr' => 'Autriche', 'it' => 'Austria', 'ru' => 'Австрия', 'eu_country' => true, ]); $shipping = Shipping::create(['name' => 'Österreich', 'active' => true]); $shippingCountry = ShippingCountry::create([ 'shipping_id' => $shipping->id, 'country_id' => $country->id, ]); $account = UserAccount::create(array_merge([ 'first_name' => 'Marlene', 'last_name' => 'Mathis', 'country_id' => $country->id, 'tax_identification_number' => 'ATU64282555', 'taxable_sales' => 1, ], $accountOverrides)); // reverse_charge* sind nicht fillable -> explizit setzen $account->forceFill(array_merge([ 'reverse_charge' => 1, 'reverse_charge_valid' => now(), 'reverse_charge_code' => 'AT', ], array_intersect_key($accountOverrides, array_flip(['reverse_charge', 'reverse_charge_valid', 'reverse_charge_code']))))->save(); $user = User::forceCreate([ 'account_id' => $account->id, 'email' => 'vat-'.uniqid('', true).'@example.com', 'password' => bcrypt('secret'), 'lang' => 'de', ]); return [$user->fresh(), $shippingCountry]; } beforeEach(function () { UserService::$user_reverse_charge = false; }); it('keeps tax free status when vies is unavailable', function () { // VIES_ENABLED=false in phpunit.xml -> CHECK_UNAVAILABLE -> gespeicherter Status gilt [$user, $shippingCountry] = makeVatCheckoutUser(); $result = UserService::performUserTaxShippingCountry($user, $shippingCountry); expect($result)->toBeTrue(); expect(UserService::$user_reverse_charge)->toBeTrue(); expect($user->account->fresh()->reverse_charge)->toBeTruthy(); }); it('revokes reverse charge for german vat ids', function () { [$user, $shippingCountry] = makeVatCheckoutUser([ 'tax_identification_number' => 'DE123456789', ]); $result = UserService::performUserTaxShippingCountry($user, $shippingCountry); expect($result)->toBeFalse(); expect(UserService::$user_reverse_charge)->toBeFalse(); $account = $user->account->fresh(); expect($account->reverse_charge)->toBeFalsy(); expect($account->reverse_charge_valid)->toBeNull(); }); it('revokes reverse charge for implausible vat ids', function () { [$user, $shippingCountry] = makeVatCheckoutUser([ 'tax_identification_number' => '53618009', ]); $result = UserService::performUserTaxShippingCountry($user, $shippingCountry); expect($result)->toBeFalse(); expect($user->account->fresh()->reverse_charge)->toBeFalsy(); }); it('revokes reverse charge when vies reports the id as invalid', function () { [$user, $shippingCountry] = makeVatCheckoutUser(); mock(VatIdService::class, function ($mock) { $mock->shouldReceive('qualifiesForReverseCharge')->andReturn(true); $mock->shouldReceive('checkViesCached')->andReturn(VatIdService::CHECK_INVALID); }); $result = UserService::performUserTaxShippingCountry($user, $shippingCountry); expect($result)->toBeFalse(); $account = $user->account->fresh(); expect($account->reverse_charge)->toBeFalsy(); expect($account->reverse_charge_valid)->toBeNull(); // Die USt-ID selbst bleibt erhalten, damit der User sie neu validieren kann expect($account->tax_identification_number)->toBe('ATU64282555'); }); it('grants tax free checkout when vies confirms the id', function () { [$user, $shippingCountry] = makeVatCheckoutUser(); mock(VatIdService::class, function ($mock) { $mock->shouldReceive('qualifiesForReverseCharge')->andReturn(true); $mock->shouldReceive('checkViesCached')->andReturn(VatIdService::CHECK_VALID); }); $result = UserService::performUserTaxShippingCountry($user, $shippingCountry); expect($result)->toBeTrue(); expect(UserService::$user_reverse_charge)->toBeTrue(); expect($user->account->fresh()->reverse_charge)->toBeTruthy(); }); it('does not run vies check when shipping country does not match reverse charge code', function () { [$user, $shippingCountry] = makeVatCheckoutUser([ 'reverse_charge_code' => 'ES', ]); $result = UserService::performUserTaxShippingCountry($user, $shippingCountry); expect($result)->toBeFalse(); // Kein Entzug: Der Status bleibt für passende Lieferländer bestehen expect($user->account->fresh()->reverse_charge)->toBeTruthy(); });