CluPilotCloud/app
nexxo 2277dfe4cb
tests / pest (push) Failing after 8m24s Details
tests / assets (push) Successful in 26s Details
tests / release (push) Has been skipped Details
Ask the EU register whether a VAT number is real
vat_id_verified_at was declared on the customer and read by TaxTreatment, and
set by no code anywhere. hasVerifiedVatId() therefore never returned true, so
reverse charge could not trigger for anybody - and every EU business customer was
invoiced Austrian VAT they cannot reclaim in their own country, which is not a
pass-through for them but a real cost until the invoice is corrected.

The check has THREE outcomes, and the third is why VatIdCheck exists. VIES is a
gateway onto twenty-seven national registers and any of them is regularly down.
Reading "I could not ask" as "not registered" would clear a verification that has
stood for months, move that customer onto the domestic rate, and change what
their next invoice says - because a register was asleep. Reading it as
"registered" would put reverse charge on an unchecked number, which is our
liability. So on UNAVAILABLE nothing at all is written.

Asked at the moment the number is entered, because that is when somebody is
looking at the field and can fix a typo. The save has already happened by then
and the check cannot undo it: a register that is down must not cost a customer
their address change.

Shape and membership are refused before a request is spent, and the fake refuses
on the same rule as the real verifier. A fake that answers where VIES would never
have been asked is not a simplification but a different product, and free text
normalises into a well-formed number more easily than it looks - "not a number"
becomes NOTANUMBER, which the shape rule alone reads as a Norwegian one.

clupilot:verify-vat-ids re-asks about the numbers reverse charge rests on, since
a registration can be withdrawn. Deliberately not scheduled: it queries a public
service with a concurrency limit on behalf of somebody else's tax position, and
the cadence is the owner's to set.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 22:42:29 +02:00
..
Actions Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Console Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Exceptions Refuse a portal login for an address that already belongs to an operator 2026-07-28 14:42:16 +02:00
Http Charge the price the website shows, and hand a withdrawal back in full 2026-07-29 22:42:02 +02:00
Jobs Let the export have as many destinations as somebody wants 2026-07-29 02:43:15 +02:00
Listeners Keep a register of what was sent, and answer the customer from here 2026-07-29 21:02:36 +02:00
Livewire Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Mail Keep a register of what was sent, and answer the customer from here 2026-07-29 21:02:36 +02:00
Models Charge the price the website shows, and hand a withdrawal back in full 2026-07-29 22:42:02 +02:00
Notifications Add the SSH identity to the vault, and give deployment config a console page 2026-07-29 00:52:44 +02:00
Observers Apply a bought plan change instead of only pricing it 2026-07-29 17:18:55 +02:00
Policies Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
Providers Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Provisioning Deliver the storage a customer actually buys 2026-07-29 19:13:10 +02:00
Services Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Support Show the customer, and write the answers once 2026-07-29 22:37:30 +02:00