Vueified salary calculator
This commit is contained in:
parent
16d57c39a1
commit
0d78421d81
22
.editorconfig
Normal file
22
.editorconfig
Normal 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
8
.idea/.gitignore
generated
vendored
Normal 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
9
.idea/misc.xml
generated
Normal 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
8
.idea/modules.xml
generated
Normal 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
9
.idea/salary-calculartor.iml
generated
Normal 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
6
.idea/vcs.xml
generated
Normal 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
200
dynamic.html
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user