Skip to content

Instantly share code, notes, and snippets.

@jnpn
Last active June 20, 2019 19:29
Show Gist options
  • Save jnpn/320abc357da8d1f28395cc3447fd95ff to your computer and use it in GitHub Desktop.
Save jnpn/320abc357da8d1f28395cc3447fd95ff to your computer and use it in GitHub Desktop.
calcul les impots par tranche (fr_FR)
// une tranche est un intervalle et un pourcentage
var defaut = {
tranches: [
{lo:0, hi:9964, percent:0},
{lo:9964, hi:27519, percent:14},
{lo:27519, hi:73779, percent:30},
{lo:73779, hi:156244, percent:41},
{lo:156244, hi:999999999999, percent:45}
]
}
// prelude
let ratio = (a,b) => (b/a)*100
let add = (a,b) => a+b
let percentage = x => x/100
// fonction qui determine la part imposable
// d'un salaire pour une tranche [lo,hi]
//
// value hi lo
// >>> part(3000, 1000, 2000) => 1000 (hi - lo) see rule 1
// >>> part(999, 1000, 2000) => 999 see rule 0
// >>> part(1500, 1000, 2000) => 500 see rule @
function part(value,lo,hi) {
if (value <= lo) { // rule 0
return value;
} else if (hi <= value) { // rule 1
return hi - lo;
} else {
return value - lo; // rule 2
}
}
// Etends chaque tranche t <= revenu r
// pour y ajouter la part imposable definie par t sur r
//
// e.g:
// revenu , tranche
// 40000 , {lo:0, hi:9964, percent:0} => base: 9964, du: base * 0%
// 40000 , {lo:9964, hi:27519, percent:14} => base: 17555, du: base * 14%
// 40000 , {lo:27519, hi:73779, percent:30} => base: 12481, du: base * 30%
// 40000 , {lo:73779, hi:156244, percent:41} => filtered out
// 40000 , {lo:156244, hi:999999999999, percent:45} => filtered out
//
// [
// {...., base, du, ... } *
// ]
//
function impots(revenu,tranches) {
let ponction = ({lo:lo,hi:hi,percent:percent}) => {
let base = part(revenu,lo,hi)
let ratio = percentage(revenu,base)
let du = base*percent/100
let augmentee = { lo:lo, hi:hi, percent:percent, base:base, ratio:ratio, du:du }
return augmentee
}
return _.chain(tranches)
.takeWhile(({lo:lo}) => lo <= revenu) // pour chaque tranche t dont la borne inf <= revenu
.map(ponction) // augmente t avec la part, taux et somme
.value()
}
let reference = (revenu,is_frais,reduction) => is_frais ? revenu-(revenu*percentage(reduction)) : revenu
// main
var app = new Vue({
el: "#app",
data: {
revenu: 40000,
frais: true,
reduction: 10,
},
computed: {
ref: function () {
return reference(this.revenu, this.frais, this.reduction)
},
imp: function () {
return impots(this.revenu, defaut.tranches);
},
tot: function () {
let revenu = reference(this.revenu, this.frais, this.reduction)
return impots(revenu, defaut.tranches)
.map(({du:du}) => du)
.reduce(add)
}
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<div class="container" id="app">
<div class="form-group">
<label class="form-label" for="revenu">Revenu</label>
<input id="revenu"
class="form-control form-control-sm"
placeholder="revenu"
v-model="revenu">
</div>
<div class="form-group form-check">
<input class="form-check-input" id="frais" type="checkbox" v-model="frais">
<label class="form-check-label" for="frais">-10% de frais</label>
</div>
<hr>
<table class="table-sm table-borderless">
<caption>impots par tranche</caption>
<thead class="thead-light">
<tr>
<td>tranche</td>
<td>base</td>
<td>taux</td>
<td>montant</td>
</tr>
</thead>
<tbody>
<tr v-for="t in imp">
<td>{{ t.hi }}</td>
<td>{{ t.base }}</td>
<td>{{ t.percent }}</td>
<td>€{{ t.du.toFixed(2) }}</td>
</tr>
<tfoot>
<tr>
<td>reference</td>
<td>{{ ref }}</td>
<td>total</td>
<td>€{{ tot }}</td>
</tr>
</tfoot>
</tbody>
</table>
<hr>
<!--div class="alert alert-primary">impots par tranche</div-->
<footer><code>(current-year) &copy; (user)</code></footer>
</div>
</body>
</html>
table { width: 100% }
thead {
font-weight: bold;
background-color: ghostwhite;
border-bottom: thin solid gainsboro;
}
tfoot {
color: crimson;
border-top: thin solid gainsboro;
}
tr:hover {
background-color: ghostwhite;
}
td {
text-align: right;
}
footer {
text-align: center;
}
code {
display: block;
width: 100%;
color: white;
background: #000;
}
@jnpn
Copy link
Author

jnpn commented Jun 20, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment