CluPilotCloud/tests/Feature/GrossPricingTest.php

85 lines
3.5 KiB
PHP

<?php
use App\Support\CompanyProfile;
use App\Support\Settings;
/**
* The public sheet quotes what a person pays, not what a business books.
*
* A private customer has no way to add 20 % in their head and no right to be
* surprised by it at checkout; a business gets the VAT back either way and
* needs the net figure on the invoice, not on the poster. So the big number is
* gross and the net one stands under it.
*/
it('quotes packages including VAT, with the net figure underneath', function () {
$content = $this->get('/')->assertOk()->getContent();
// start is 49 € net in the catalogue → 58,80 € at 20 %.
expect($content)->toContain('58,80'."\u{00A0}".'€')
->and($content)->toContain('49'."\u{00A0}".'€')
->and($content)->toContain('inkl. 20 % MwSt.');
});
it('follows the rate the operator set, not one written into the page', function () {
// The rate is console-editable (Finance page) and the same one an invoice
// uses. A percentage written into the template is the second source that
// makes the sheet and the invoice disagree.
Settings::set('company.tax_rate', 10.0);
$content = $this->get('/')->assertOk()->getContent();
expect($content)->toContain('53,90'."\u{00A0}".'€') // 49 € + 10 %
->and($content)->toContain('inkl. 10 % MwSt.')
->and($content)->not->toContain('58,80'."\u{00A0}".'€');
});
it('drops the fractional part of a rate that has none', function () {
// "20 %" — not "20,0 %". The label is read by a person, not parsed.
Settings::set('company.tax_rate', 20.0);
expect($this->get('/')->getContent())->not->toContain('20,0 %');
});
it('names what the setup costs instead of only announcing that it costs', function () {
// The sheet said "zzgl. einmaliger Einrichtung" for months without naming a
// figure, which leaves a visitor knowing only that there is one.
Settings::set('company.setup_fee_cents', 9900);
expect($this->get('/')->assertOk()->getContent())
->toContain('zzgl. Einrichtung einmalig')
->toContain('118,80'."\u{00A0}".'€'); // 99 € + 20 %
});
it('says nothing about a setup fee that is not charged', function () {
// Zero is not "0 €" on a price sheet — it is a sentence that should not be
// there at all.
Settings::set('company.setup_fee_cents', 0);
expect($this->get('/')->assertOk()->getContent())
->not->toContain('zzgl. Einrichtung einmalig');
});
it('reads the fee back in euro after an operator types it in euro', function () {
// The form is in euro and the store is in cents. Asking an operator to type
// 9900 for ninety-nine euro is how a fee ends up a hundred times too large.
Settings::set('company.setup_fee_cents', 9995);
expect(CompanyProfile::setupFeeCents())->toBe(9995)
->and(number_format(CompanyProfile::setupFeeCents() / 100, 2, '.', ''))->toBe('99.95');
});
it('does not admit to a setup cost the installation does not charge', function () {
// The comparison card listed "Einrichtung kostet einmalig" as the honest
// downside of the offer. With no fee configured that is a downside we do
// not have, stated on our own page.
Settings::set('company.setup_fee_cents', 0);
expect($this->get('/')->assertOk()->getContent())
->not->toContain('Einrichtung kostet einmalig');
Settings::set('company.setup_fee_cents', 9900);
expect($this->get('/')->assertOk()->getContent())
->toContain('Einrichtung kostet einmalig 118,80'."\u{00A0}".'€');
});