158 lines
3.2 KiB
Svelte
158 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import type CalculatorValues from '$lib/calculator/type/CalculatorValues';
|
|
import {
|
|
refreshBasePrice,
|
|
refreshFinalPrice,
|
|
refreshVatAmount
|
|
} from '$lib/calculator/functions/RefreshFunctions';
|
|
|
|
let calcValues: CalculatorValues = {
|
|
basePrice: 0.0,
|
|
vatRate: 0.0,
|
|
vatAmount: 0.0,
|
|
finalPrice: 0.0
|
|
};
|
|
|
|
let calcValuesCache: CalculatorValues = {
|
|
...calcValues
|
|
};
|
|
|
|
function refreshCache(calcValues: CalculatorValues) {
|
|
calcValuesCache = {
|
|
...calcValues
|
|
};
|
|
}
|
|
|
|
function refreshPrices(calcValues: CalculatorValues) {
|
|
if (!validateCalculatorValues(calcValues)) {
|
|
// Calculator values are invalid, we don't want to refresh the prices.
|
|
return false;
|
|
}
|
|
|
|
if (
|
|
calcValues.basePrice !== calcValuesCache.basePrice ||
|
|
calcValues.vatRate !== calcValuesCache.vatRate
|
|
) {
|
|
refreshFinalPrice(calcValues);
|
|
} else if (calcValues.finalPrice !== calcValuesCache.finalPrice) {
|
|
refreshBasePrice(calcValues);
|
|
}
|
|
|
|
refreshVatAmount(calcValues);
|
|
refreshCache(calcValues);
|
|
}
|
|
|
|
function validateCalculatorValues(calcValues: CalculatorValues) {
|
|
let property: keyof typeof calcValues;
|
|
|
|
for (property in calcValues) {
|
|
if (calcValues[property] === null) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function handleFocus(event: Event) {
|
|
const element = event.target;
|
|
|
|
if (element instanceof HTMLInputElement) {
|
|
if (element.value === '0') {
|
|
element.value = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleBlur(event: Event) {
|
|
const element = event.target;
|
|
|
|
if (element instanceof HTMLInputElement) {
|
|
if (element.value === '') {
|
|
element.value = '0';
|
|
}
|
|
}
|
|
}
|
|
|
|
$: refreshPrices(calcValues);
|
|
|
|
const invalidNumberErrorText = 'Zadejte platné číslo.';
|
|
</script>
|
|
|
|
<form>
|
|
<label for="vatRate">Sazba DPH (%)</label>
|
|
<input
|
|
id="vatRate"
|
|
type="number"
|
|
min="0"
|
|
max="100"
|
|
bind:value={calcValues.vatRate}
|
|
class:invalid={calcValues.vatRate === null}
|
|
on:focus={handleFocus}
|
|
on:blur={handleBlur}
|
|
/>
|
|
{#if calcValues.vatRate === null}
|
|
<p class="invalid">{invalidNumberErrorText}</p>
|
|
{/if}
|
|
<label for="basePrice">Cena bez DPH (Kč)</label>
|
|
<input
|
|
id="basePrice"
|
|
type="number"
|
|
min="0"
|
|
bind:value={calcValues.basePrice}
|
|
class:invalid={calcValues.basePrice === null}
|
|
on:focus={handleFocus}
|
|
on:blur={handleBlur}
|
|
/>
|
|
{#if calcValues.basePrice === null}
|
|
<p class="invalid">{invalidNumberErrorText}</p>
|
|
{/if}
|
|
<label for="finalPrice">Cena s DPH (Kč)</label>
|
|
<input
|
|
id="finalPrice"
|
|
type="number"
|
|
min="0"
|
|
bind:value={calcValues.finalPrice}
|
|
class:invalid={calcValues.finalPrice === null}
|
|
on:focus={handleFocus}
|
|
on:blur={handleBlur}
|
|
/>
|
|
{#if calcValues.finalPrice === null}
|
|
<p class="invalid">{invalidNumberErrorText}</p>
|
|
{/if}
|
|
</form>
|
|
|
|
<div class="vatAmount">
|
|
Výše DPH: {calcValues.vatAmount} Kč
|
|
</div>
|
|
|
|
<style>
|
|
p.invalid {
|
|
color: var(--invalid-color);
|
|
}
|
|
|
|
input {
|
|
width: 100%;
|
|
margin: 0.25em 0 0.625em;
|
|
border: 2px solid gray;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
input:last-child {
|
|
margin-bottom: 1.25em;
|
|
}
|
|
|
|
input.invalid {
|
|
border: 4px solid var(--invalid-color);
|
|
}
|
|
|
|
input[type='number'] {
|
|
-moz-appearance: textfield;
|
|
appearance: textfield;
|
|
}
|
|
|
|
input[type='number']::-webkit-inner-spin-button {
|
|
-webkit-appearance: none;
|
|
}
|
|
</style>
|