85 lines
3.5 KiB
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}".'€');
|
|
});
|