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