Vueified salary calculator

This commit is contained in:
Eriks Karls 2022-12-15 14:27:05 +02:00
parent 16d57c39a1
commit 0d78421d81
7 changed files with 262 additions and 0 deletions

22
.editorconfig Normal file
View File

@ -0,0 +1,22 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 160
tab_width = 4
[*.vue]
indent_size = 2
tab_width = 2
[{*.cjs,*.js}]
indent_size = 2
tab_width = 2
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
indent_size = 2
tab_width = 2

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

9
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/salary-calculartor.iml" filepath="$PROJECT_DIR$/.idea/salary-calculartor.iml" />
</modules>
</component>
</project>

9
.idea/salary-calculartor.iml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

200
dynamic.html Normal file
View File

@ -0,0 +1,200 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Salary calculator for Latvians</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<form class="row" id="fromBrutto">
<div class="mb-3 col-12 col-md">
<label for="idBruttoInput" class="form-label text-bold">Brutto salary*:</label>
<div class="input-group">
<span class="input-group-text"></span>
<input id="idBruttoInput" type="number" class="form-control" v-model="bruttoSalary" placeholder="700" min="0" step="10">
<span class="input-group-text">.00</span>
</div>
<label for="idDependentsInput" class="form-label text-bold">Dependents:</label>
<select id="idDependentsInput" class="form-select" v-model="dependentCount">
<option value="0">0</option>
<option v-for="num in 6" :value="num">{{ num }}</option>
</select>
<label><input type="checkbox" id="idTaxBookSubmitted" v-model="taxBookSubmitted" checked> Salary tax book has been submitted to
the employer</label><br>
<label for="idExtraTaxDiscount" class="form-label text-bold">Extra tax-free amount:</label>
<div class="input-group">
<span class="input-group-text"></span>
<input type="number" class="form-control" id="idExtraTaxDiscount" v-model="extraTaxDiscount" placeholder="0" min="0" step="0.01">
</div>
</div>
<div class="col">
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Brutto salary</div>
</div>
<span id="idBruttoSalaryDisplay">{{bruttoSalary}}€</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Social security tax</div>
</div>
<span class="text-danger">{{socialInsuranceAmount}}€</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Income tax</div>
</div>
<span class="text-danger">{{incomeTax}}€</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Net salary</div>
</div>
<span class="text-primary">{{netSalary}}€</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Employer tax</div>
</div>
<span class="text-warning">{{employersSocialInsuranceAmount}}€</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">Employer total cost</div>
</div>
<span>{{employerTotalCost}}€</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<table class="table table-sm table-striped table-hover">
<thead>
<tr>
<th></th>
<th class="text-end">Hourly</th>
<th class="text-end">Daily</th>
<th class="text-end">Yearly</th>
</tr>
</thead>
<tbody>
<tr>
<th>Net</th>
<td class="text-end font-monospace">{{hourlyNet}}€</td>
<td class="text-end font-monospace">{{dailyNet}}€</td>
<td class="text-end font-monospace">{{yearlyNet}}€</td>
</tr>
<tr>
<th>Brutto</th>
<td class="text-end font-monospace">{{hourlyBrutto}}€</td>
<td class="text-end font-monospace">{{dailyBrutto}}€</td>
<td class="text-end font-monospace">{{yearlyBrutto}}€</td>
</tr>
<tr>
<th>Employer</th>
<td class="text-end font-monospace">{{hourlyEmployer}}€</td>
<td class="text-end font-monospace">{{dailyEmployer}}€</td>
<td class="text-end font-monospace">{{yearlyEmployer}}€</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const {createApp} = Vue
const round2 = fl => parseFloat(fl).toFixed(2)
const yearlySalaryLimit_1 = 20004,
yearlySalaryLimit_2 = 78100,
minTaxable = 500,
maxTaxable = 1800,
diffTaxable = minTaxable - maxTaxable,
minTaxFree = 0,
maxTaxFree = 500,
diffTaxFree = minTaxFree - maxTaxFree,
dependentsDiscount = 250,
halfPercent = 50 / 10000,
socialInsurancePercent = 1050 / 10000;
createApp({
data() {
return {
dependentCount: 0,
bruttoSalary: 6509,
extraTaxDiscount: 0,
taxBookSubmitted: true,
}
},
computed: {
socialInsuranceAmount() {
console.log(this.bruttoSalary * socialInsurancePercent, yearlySalaryLimit_2 / 12 * (socialInsurancePercent - halfPercent) + (this.bruttoSalary * halfPercent))
return round2(Math.min(this.bruttoSalary * socialInsurancePercent, yearlySalaryLimit_2 / 12 * (socialInsurancePercent - halfPercent) + (this.bruttoSalary * halfPercent)))
},
incomeTax() {
const taxRelief = this.taxBookSubmitted ? this.dependentCount * dependentsDiscount : 0,
actualTaxFreeAmount = (!this.taxBookSubmitted ? 0 : (this.bruttoSalary > maxTaxable ? minTaxFree : (this.bruttoSalary <= minTaxable ? maxTaxFree : (maxTaxFree - ((diffTaxFree / diffTaxable) * (this.bruttoSalary - minTaxable)))))),
incomeTaxBaseLow = Math.min(yearlySalaryLimit_1 / 12, this.bruttoSalary),
incomeTaxBaseMid = Math.max(Math.min(this.bruttoSalary - incomeTaxBaseLow, yearlySalaryLimit_2 / 12 - incomeTaxBaseLow), 0),
incomeTaxBaseTop = Math.max(this.bruttoSalary - incomeTaxBaseLow - incomeTaxBaseMid, 0),
incomeTaxLow = (incomeTaxBaseLow - this.socialInsuranceAmount - this.extraTaxDiscount - actualTaxFreeAmount - taxRelief) * (20 / 100),
incomeTaxMid = incomeTaxBaseMid * (2300 / 10000),
incomeTaxTop = incomeTaxBaseTop * (3100 / 10000);
return round2(Math.max(incomeTaxLow + incomeTaxMid + incomeTaxTop, 0))
},
netSalary() {
return round2(this.bruttoSalary - this.socialInsuranceAmount - this.incomeTax);
},
employersSocialInsuranceAmount() {
return round2(this.bruttoSalary * 2359 / 10000)
},
employerTotalCost() {
return round2(this.bruttoSalary + parseFloat(this.employersSocialInsuranceAmount))
},
hourlyNet() {
return round2(this.netSalary / 168)
},
hourlyBrutto() {
return round2(this.bruttoSalary / 168)
},
hourlyEmployer() {
return round2(this.employerTotalCost / 168)
},
dailyNet() {
return round2(this.netSalary / 21)
},
dailyBrutto() {
return round2(this.bruttoSalary / 21)
},
dailyEmployer() {
return round2(this.employerTotalCost / 21)
},
yearlyNet() {
return round2(this.netSalary * 12)
},
yearlyBrutto() {
return round2(this.bruttoSalary * 12)
},
yearlyEmployer() {
return round2(this.employerTotalCost * 12)
},
},
watch: {}
}).mount('#fromBrutto');
</script>
</body>
</html>