diff --git a/VERSION.txt b/VERSION.txt index b1e2bc0661..2770eb1b0b 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.10.59 \ No newline at end of file +5.10.60 \ No newline at end of file diff --git a/app/Http/Controllers/Auth/ContactLoginController.php b/app/Http/Controllers/Auth/ContactLoginController.php index fd43096999..b9bf2246da 100644 --- a/app/Http/Controllers/Auth/ContactLoginController.php +++ b/app/Http/Controllers/Auth/ContactLoginController.php @@ -63,6 +63,9 @@ class ContactLoginController extends Controller return $company; } + if(Ninja::isSelfHost()) + return Company::first(); + return false; } diff --git a/app/Import/Transformer/Csv/ClientTransformer.php b/app/Import/Transformer/Csv/ClientTransformer.php index 5746589a29..b238ac4bff 100644 --- a/app/Import/Transformer/Csv/ClientTransformer.php +++ b/app/Import/Transformer/Csv/ClientTransformer.php @@ -34,6 +34,9 @@ class ClientTransformer extends BaseTransformer throw new ImportException('Client already exists'); } + if(!is_array($data)) + throw new ImportException('Empty row, or invalid data encountered.'); + $settings = ClientSettings::defaults(); $settings->currency_id = (string) $this->getCurrencyByCode($data); diff --git a/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php b/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php index be354c8fef..7efb418935 100644 --- a/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php +++ b/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php @@ -63,6 +63,22 @@ class RegisterOrLogin extends Component $this->state['initial_completed'] = true; + + if(!$this->subscription()->registration_required){ + + $service = new ClientRegisterService( + company: $this->subscription()->company, + additional: $this->additional_fields, + ); + + $client = $service->createClient([]); + $contact = $service->createClientContact(['email' => $this->email], $client); + auth()->guard('contact')->loginUsingId($contact->id, true); + $this->dispatch('purchase.next'); + return; + + } + if ($this->state['otp']) { return $this->withOtp(); } @@ -112,7 +128,6 @@ class RegisterOrLogin extends Component if ($contact === null) { $this->registerForm(); - return; } @@ -262,11 +277,10 @@ class RegisterOrLogin extends Component { if (auth()->guard('contact')->check()) { - // $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); $this->dispatch('purchase.next'); - return; } + } public function render() diff --git a/app/Livewire/BillingPortal/Cart/Cart.php b/app/Livewire/BillingPortal/Cart/Cart.php index d7624aa685..46b5c87d1e 100644 --- a/app/Livewire/BillingPortal/Cart/Cart.php +++ b/app/Livewire/BillingPortal/Cart/Cart.php @@ -26,6 +26,16 @@ class Cart extends Component public string $subscription_id; + public function mount() + { + + \Illuminate\Support\Facades\App::forgetInstance('translator'); + $t = app('translator'); + $t->replace(\App\Utils\Ninja::transformTranslations($this->subscription()->company->settings)); + \Illuminate\Support\Facades\App::setLocale($this->subscription()->company->locale()); + + } + #[Computed()] public function subscription() { diff --git a/app/Livewire/BillingPortal/Purchase.php b/app/Livewire/BillingPortal/Purchase.php index f6905ca5c1..44ea5f8445 100644 --- a/app/Livewire/BillingPortal/Purchase.php +++ b/app/Livewire/BillingPortal/Purchase.php @@ -12,18 +12,20 @@ namespace App\Livewire\BillingPortal; +use App\Utils\Ninja; +use Livewire\Component; use App\Libraries\MultiDB; -use App\Livewire\BillingPortal\Authentication\Login; -use App\Livewire\BillingPortal\Authentication\Register; -use App\Livewire\BillingPortal\Authentication\RegisterOrLogin; -use App\Livewire\BillingPortal\Cart\Cart; -use App\Livewire\BillingPortal\Payments\Methods; +use Illuminate\Support\Str; +use Livewire\Attributes\On; use App\Models\Subscription; use App\Utils\Traits\MakesHash; use Livewire\Attributes\Computed; -use Livewire\Attributes\On; -use Livewire\Component; -use Illuminate\Support\Str; +use Illuminate\Support\Facades\App; +use App\Livewire\BillingPortal\Cart\Cart; +use App\Livewire\BillingPortal\Payments\Methods; +use App\Livewire\BillingPortal\Authentication\Login; +use App\Livewire\BillingPortal\Authentication\Register; +use App\Livewire\BillingPortal\Authentication\RegisterOrLogin; class Purchase extends Component { @@ -115,7 +117,6 @@ class Purchase extends Component return "summary-{$this->id}"; } - #[Computed()] public function subscription() { @@ -166,7 +167,8 @@ class Purchase extends Component ->handleContext('hash', $this->hash) ->handleContext('quantity', 1) ->handleContext('request_data', $this->request_data) - ->handleContext('campaign', $this->campaign); + ->handleContext('campaign', $this->campaign) + ->handleContext('subcription_id', $this->subscription_id); } public function render() diff --git a/app/Livewire/BillingPortal/RFF.php b/app/Livewire/BillingPortal/RFF.php index 30ce571869..62ecb956d7 100644 --- a/app/Livewire/BillingPortal/RFF.php +++ b/app/Livewire/BillingPortal/RFF.php @@ -13,12 +13,16 @@ namespace App\Livewire\BillingPortal; use App\Models\CompanyGateway; +use App\Models\Subscription; +use App\Utils\Traits\MakesHash; use Illuminate\Support\Facades\Cache; use Livewire\Attributes\On; use Livewire\Component; class RFF extends Component { + use MakesHash; + public array $context; public string $contact_first_name; @@ -70,6 +74,7 @@ class RFF extends Component $gateway = CompanyGateway::find($this->context['form']['company_gateway_id']); $countries = Cache::get('countries'); + if ($gateway === null) { return view('billing-portal.v3.rff-basic'); } diff --git a/app/Livewire/BillingPortal/Summary.php b/app/Livewire/BillingPortal/Summary.php index b40dca545c..596e8d5e19 100644 --- a/app/Livewire/BillingPortal/Summary.php +++ b/app/Livewire/BillingPortal/Summary.php @@ -12,13 +12,15 @@ namespace App\Livewire\BillingPortal; -use App\Models\RecurringInvoice; -use App\Models\Subscription; +use App\Utils\Ninja; use App\Utils\Number; -use App\Utils\Traits\MakesHash; -use Livewire\Attributes\Computed; -use Livewire\Attributes\On; use Livewire\Component; +use Livewire\Attributes\On; +use App\Models\Subscription; +use App\Utils\Traits\MakesHash; +use App\Models\RecurringInvoice; +use Livewire\Attributes\Computed; +use Illuminate\Support\Facades\App; class Summary extends Component { @@ -38,6 +40,11 @@ class Summary extends Component { $subscription = Subscription::find($this->decodePrimaryKey($this->subscription_id)); + App::forgetInstance('translator'); + $t = app('translator'); + $t->replace(Ninja::transformTranslations($subscription->company->settings)); + App::setLocale($subscription->company->locale()); + $bundle = $this->context['bundle'] ?? [ 'recurring_products' => [], 'optional_recurring_products' => [], @@ -190,7 +197,7 @@ class Summary extends Component foreach ($this->context['bundle']['recurring_products'] as $key => $item) { $products[] = [ 'product_key' => $item['product']['product_key'], - 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'])), + 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'] ?? '')), 'quantity' => $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'], 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription()->frequency_id), @@ -200,7 +207,7 @@ class Summary extends Component foreach ($this->context['bundle']['optional_recurring_products'] as $key => $item) { $products[] = [ 'product_key' => $item['product']['product_key'], - 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'])), + 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'] ?? '')), 'quantity' => $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'], 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription()->frequency_id), @@ -210,7 +217,7 @@ class Summary extends Component foreach ($this->context['bundle']['one_time_products'] as $key => $item) { $products[] = [ 'product_key' => $item['product']['product_key'], - 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'])), + 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'] ?? '')), 'quantity' => $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'], 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company), @@ -220,7 +227,7 @@ class Summary extends Component foreach ($this->context['bundle']['optional_one_time_products'] as $key => $item) { $products[] = [ 'product_key' => $item['product']['product_key'], - 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'])), + 'notes' => strip_tags(\Illuminate\Support\Str::markdown($item['product']['notes'] ?? '')), 'quantity' => $item['quantity'], 'total_raw' => $item['product']['price'] * $item['quantity'], 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription()->company), @@ -235,17 +242,6 @@ class Summary extends Component #[On('summary.refresh')] public function refresh() { - // nlog("am i refreshing here?"); - - // $this->oneTimePurchasesTotal = $this->oneTimePurchasesTotal(); - // $this->recurringPurchasesTotal = $this->recurringPurchasesTotal(); - // $this->discount = $this->discount(); - - // nlog($this->oneTimePurchasesTotal); - // nlog($this->recurringPurchasesTotal); - // nlog($this->discount); - - } diff --git a/app/Models/Presenters/UserPresenter.php b/app/Models/Presenters/UserPresenter.php index 59211278e1..d6a83235cc 100644 --- a/app/Models/Presenters/UserPresenter.php +++ b/app/Models/Presenters/UserPresenter.php @@ -73,7 +73,7 @@ class UserPresenter extends EntityPresenter return 'No First Name Available'; } - return $this->entity->first_name ?? 'First Name'; + return $this->entity->first_name ?? ' '; } diff --git a/app/PaymentDrivers/Blockonomics/Blockonomics.php b/app/PaymentDrivers/Blockonomics/Blockonomics.php index 35f430da92..87f2aa26c1 100644 --- a/app/PaymentDrivers/Blockonomics/Blockonomics.php +++ b/app/PaymentDrivers/Blockonomics/Blockonomics.php @@ -76,7 +76,7 @@ class Blockonomics implements LivewireMethodInterface } else { return ['success' => false, 'message' => "Could not generate new address (This may be a temporary error. Please try again). \n\n

If this continues, please ask website administrator to check blockonomics registered email address for error messages"]; } - return ['success' => false, 'message' => 'Something went wrong']; + } public function getBTCPrice() diff --git a/app/PaymentDrivers/BlockonomicsPaymentDriver.php b/app/PaymentDrivers/BlockonomicsPaymentDriver.php index dfa717f3f9..8fc5743f32 100644 --- a/app/PaymentDrivers/BlockonomicsPaymentDriver.php +++ b/app/PaymentDrivers/BlockonomicsPaymentDriver.php @@ -12,18 +12,19 @@ namespace App\PaymentDrivers; -use App\Utils\Traits\MakesHash; -use App\Models\PaymentHash; -use App\Models\GatewayType; -use App\PaymentDrivers\Blockonomics\Blockonomics; -use App\Models\SystemLog; -use App\Models\Payment; -use App\Models\Gateway; use App\Models\Client; -use App\Exceptions\PaymentFailed; -use App\Models\PaymentType; -use App\Http\Requests\Payments\PaymentWebhookRequest; +use App\Models\Gateway; use App\Models\Invoice; +use App\Models\Payment; +use App\Models\SystemLog; +use App\Models\GatewayType; +use App\Models\PaymentHash; +use App\Models\PaymentType; +use App\Utils\Traits\MakesHash; +use App\Exceptions\PaymentFailed; +use Illuminate\Support\Facades\Http; +use App\PaymentDrivers\Blockonomics\Blockonomics; +use App\Http\Requests\Payments\PaymentWebhookRequest; class BlockonomicsPaymentDriver extends BaseDriver { @@ -147,8 +148,8 @@ class BlockonomicsPaymentDriver extends BaseDriver public function auth(): bool { try { - // TODO: Add check /api/new_address?reset=1 to see if the API key is valid - $this->company_gateway->getConfigField('apiKey'); + + $api_key = $this->company_gateway->getConfigField('apiKey'); $url = $this->NEW_ADDRESS_URL . '?reset=1'; $response = Http::withToken($api_key) ->post($url, []); @@ -159,6 +160,6 @@ class BlockonomicsPaymentDriver extends BaseDriver } catch (\Exception $e) { return false; } - return false; + } } diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index fc430800b2..3282eb4fab 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -815,7 +815,7 @@ class Peppol extends AbstractService $lea = new LineExtensionAmount(); $lea->currencyID = $this->invoice->client->currency()->code; - $lea->amount = $this->invoice->uses_inclusive_taxes ? $item->line_total - $this->calcInclusiveLineTax($item->tax_rate1, $item->line_total) : $item->line_total; + $lea->amount = $this->invoice->uses_inclusive_taxes ? round($item->line_total - $this->calcInclusiveLineTax($item->tax_rate1, $item->line_total),2) : round($item->line_total,2); $line->LineExtensionAmount = $lea; $line->Item = $_item; diff --git a/composer.lock b/composer.lock index 4eaee2a826..a629a09807 100644 --- a/composer.lock +++ b/composer.lock @@ -535,16 +535,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.332.0", + "version": "3.334.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "3b4972a465b66fe3da461a3febdcc363954a0969" + "reference": "8afe50cb2a93051dafef21eb616e297a449764aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3b4972a465b66fe3da461a3febdcc363954a0969", - "reference": "3b4972a465b66fe3da461a3febdcc363954a0969", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8afe50cb2a93051dafef21eb616e297a449764aa", + "reference": "8afe50cb2a93051dafef21eb616e297a449764aa", "shasum": "" }, "require": { @@ -627,9 +627,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.332.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.334.0" }, - "time": "2024-12-02T03:48:16+00:00" + "time": "2024-12-04T19:09:04+00:00" }, { "name": "babenkoivan/elastic-adapter", @@ -2902,16 +2902,16 @@ }, { "name": "google/auth", - "version": "v1.43.0", + "version": "v1.44.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "b6a80acd906492086db59aada9196dcfb9c512fe" + "reference": "5670e56307d7a2eac931f677c0e59a4f8abb2e43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/b6a80acd906492086db59aada9196dcfb9c512fe", - "reference": "b6a80acd906492086db59aada9196dcfb9c512fe", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/5670e56307d7a2eac931f677c0e59a4f8abb2e43", + "reference": "5670e56307d7a2eac931f677c0e59a4f8abb2e43", "shasum": "" }, "require": { @@ -2956,9 +2956,9 @@ "support": { "docs": "https://googleapis.github.io/google-auth-library-php/main/", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.43.0" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.44.0" }, - "time": "2024-11-07T19:35:20+00:00" + "time": "2024-12-04T15:34:58+00:00" }, { "name": "graham-campbell/result-type", @@ -3667,16 +3667,16 @@ }, { "name": "horstoeko/mimedb", - "version": "v1.0.7", + "version": "v1.0.8", "source": { "type": "git", "url": "https://github.com/horstoeko/mimedb.git", - "reference": "5242e42662848be5dcee3dd87a915d34fa9f61df" + "reference": "2d50f2b6bf63f14741514682869b53fc97232308" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/horstoeko/mimedb/zipball/5242e42662848be5dcee3dd87a915d34fa9f61df", - "reference": "5242e42662848be5dcee3dd87a915d34fa9f61df", + "url": "https://api.github.com/repos/horstoeko/mimedb/zipball/2d50f2b6bf63f14741514682869b53fc97232308", + "reference": "2d50f2b6bf63f14741514682869b53fc97232308", "shasum": "" }, "require": { @@ -3716,9 +3716,9 @@ ], "support": { "issues": "https://github.com/horstoeko/mimedb/issues", - "source": "https://github.com/horstoeko/mimedb/tree/v1.0.7" + "source": "https://github.com/horstoeko/mimedb/tree/v1.0.8" }, - "time": "2024-11-22T10:02:51+00:00" + "time": "2024-12-03T10:57:28+00:00" }, { "name": "horstoeko/orderx", @@ -3886,16 +3886,16 @@ }, { "name": "horstoeko/zugferd", - "version": "v1.0.89", + "version": "v1.0.90", "source": { "type": "git", "url": "https://github.com/horstoeko/zugferd.git", - "reference": "f728e974d7a1c2593d11357eabe4b0686263a69c" + "reference": "2dfebcb9c3acbfd62dd20214de817fd764365d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/f728e974d7a1c2593d11357eabe4b0686263a69c", - "reference": "f728e974d7a1c2593d11357eabe4b0686263a69c", + "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/2dfebcb9c3acbfd62dd20214de817fd764365d7e", + "reference": "2dfebcb9c3acbfd62dd20214de817fd764365d7e", "shasum": "" }, "require": { @@ -3952,9 +3952,9 @@ ], "support": { "issues": "https://github.com/horstoeko/zugferd/issues", - "source": "https://github.com/horstoeko/zugferd/tree/v1.0.89" + "source": "https://github.com/horstoeko/zugferd/tree/v1.0.90" }, - "time": "2024-12-02T16:48:08+00:00" + "time": "2024-12-03T04:52:07+00:00" }, { "name": "horstoeko/zugferdvisualizer", @@ -4408,12 +4408,12 @@ "type": "library", "extra": { "laravel": { - "providers": [ - "InvoiceNinja\\Inspector\\InspectorServiceProvider" - ], "aliases": { "Inspector": "InvoiceNinja\\Inspector\\InspectorFacade" - } + }, + "providers": [ + "InvoiceNinja\\Inspector\\InspectorServiceProvider" + ] } }, "autoload": { @@ -5200,13 +5200,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "10.x-dev" - }, "laravel": { "providers": [ "Laravel\\Scout\\ScoutServiceProvider" ] + }, + "branch-alias": { + "dev-master": "10.x-dev" } }, "autoload": { @@ -7913,12 +7913,12 @@ "type": "library", "extra": { "laravel": { - "providers": [ - "Nwidart\\Modules\\LaravelModulesServiceProvider" - ], "aliases": { "Module": "Nwidart\\Modules\\Facades\\Module" - } + }, + "providers": [ + "Nwidart\\Modules\\LaravelModulesServiceProvider" + ] }, "branch-alias": { "dev-master": "11.0-dev" diff --git a/config/mail.php b/config/mail.php index a9a86b08ac..a2ec64e79b 100644 --- a/config/mail.php +++ b/config/mail.php @@ -44,6 +44,7 @@ return [ 'timeout' => null, 'local_domain' => env('MAIL_EHLO_DOMAIN'), 'verify_peer' => env('MAIL_VERIFY_PEER', true), + 'scheme' => env('MAIL_SCHEME', 'smtp'), // smtp or smtps ], 'ses' => [ diff --git a/config/ninja.php b/config/ninja.php index 09ab84b61c..5a0b912ab0 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.10.59'), - 'app_tag' => env('APP_TAG', '5.10.59'), + 'app_version' => env('APP_VERSION', '5.10.60'), + 'app_tag' => env('APP_TAG', '5.10.60'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), diff --git a/config/services.php b/config/services.php index ad9091498d..af4999f6d0 100644 --- a/config/services.php +++ b/config/services.php @@ -45,6 +45,13 @@ return [ ], ], + 'postmark-broadcast' => [ + 'token' => env('POSTMARK_BROADCAST_SECRET', ''), + 'from' => [ + 'address' => env('POSTMARK_BROADCAST_FROM_ADDRESS', 'community@invoiceninja.com') + ], + ], + 'microsoft' => [ 'client_id' => env('MICROSOFT_CLIENT_ID'), 'client_secret' => env('MICROSOFT_CLIENT_SECRET'), diff --git a/tests/Feature/EInvoice/PeppolTest.php b/tests/Feature/EInvoice/PeppolTest.php index 03bd7c094f..7778243347 100644 --- a/tests/Feature/EInvoice/PeppolTest.php +++ b/tests/Feature/EInvoice/PeppolTest.php @@ -382,7 +382,7 @@ class PeppolTest extends TestCase } - public function testEntityValidation() + public function testEntityValidationShouldFailForFRBusiness() { $scenario = [ 'company_vat' => 'DE923356489', @@ -398,6 +398,57 @@ class PeppolTest extends TestCase ]; + $entity_data = $this->setupTestData($scenario); + + $invoice = $entity_data['invoice']; + $company = $entity_data['company']; + $settings = $company->settings; + + $settings->address1 = 'some address'; + $settings->city = 'some city'; + $settings->postal_code = '102394'; + + $company->settings = $settings; + $company->save(); + + $data = [ + 'entity' => 'invoices', + 'entity_id' => $invoice->hashed_id + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/einvoice/validateEntity', $data); + + if($response->getStatusCode() !== 422){ + + $p = new Peppol($invoice); + nlog($p->run()->toXml()); + nlog($invoice->withoutRelations()->toArray()); + nlog($response->json()); + } + + $response->assertStatus(422); + + } + + public function testEntityValidation() + { + $scenario = [ + 'company_vat' => 'DE923356489', + 'company_country' => 'DE', + 'client_country' => 'FR', + 'client_vat' => 'FRAA123456789', + 'client_id_number' => '123456789', + 'classification' => 'government', + 'has_valid_vat' => true, + 'over_threshold' => true, + 'legal_entity_id' => 290868, + 'is_tax_exempt' => false, + ]; + + $entity_data = $this->setupTestData($scenario); $invoice = $entity_data['invoice'];