---|main| Initial commit

This commit is contained in:
Julien Gautier
2023-09-12 21:43:57 +02:00
commit 7e9599118e
42 changed files with 8015 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
var router = require('express').Router();
const auth = require('../auth');
//var ExceptionsHandler = require('../../middlewares/exceptions.handler');
//var UnknownRoutesHandler = require('../../middlewares/unknownRoutes.handler');
router.use('/', function (req, res, next) {
let taxationValues = ['cours_legaux', 'jetons', 'metaux_precieux'];
let errors = [];
if (req.body.taxationType == undefined || taxationValues.indexOf(req.body.taxationType) === -1) {
errors.push('La valeur du paramètre \'taxationType\' est incorrecte.');
}
if (req.body.purchasePrice == undefined || req.body.purchasePrice <= 0) {
errors.push('La valeur du paramètre \'purchasePrice\' est incorrecte.');
}
if (req.body.sellPrice == undefined || req.body.sellPrice <= 0) {
errors.push('La valeur du paramètre \'sellPrice\' est incorrecte.');
}
if (req.body.yearOwnership == undefined || req.body.yearOwnership < 0) {
errors.push('La valeur du paramètre \'yearOwnership\' est incorrecte.');
}
if (errors.length) {
return res.status(422).json({
errors: {
name: 'ValidationError',
message: 'La validation des données a échoué.',
messages: errors
}
});
}
return next();
});
router.post('/', function (req, res, next) {
const config = {
palierDetention: 2,
coeff: {
metaux_precieux: 0.115,
jetons: 0.065,
plus_value: 0.362
}
};
const params = {
taxationType: req.body.taxationType ? req.body.taxationType : null,
purchasePrice: req.body.purchasePrice ? req.body.purchasePrice : 0,
sellPrice: req.body.sellPrice ? req.body.sellPrice : 0,
yearOwnership: req.body.yearOwnership ? req.body.yearOwnership : 0
};
let results = {
capitalGain: 0,
capitalGainCoeff: 0,
lumpSum: 0,
lumpSumCoeff: 0,
isTaxable: false,
bestChoice: null, // valeurs possibles : 'lumpSum', 'gain' or null
messages: []
}
if(req.body.purchasePrice >= req.body.sellPrice) {
results.messages.push((req.body.purchasePrice > req.body.sellPrice) ? 'Vous êtes dans le cas d\'une moins-value.' : 'Vous êtes dans le cas d\'une plus-value nulle.');
}
if(req.body.yearOwnership >= 22) {
results.messages.push('Vous êtes dans le cas d\'une vente non imposable (à partir de 22 ans de détention).');
}
if (params.sellPrice <= 5000) {
if (params.taxationType == 'cours_legaux') {
results.messages.push('Vous êtes dans le cas d\'une vente non imposable sur le cours légal (inférieure à 5000 €).');
} else if (params.taxationType == 'jetons') {
results.messages.push('Vous êtes dans le cas d\'une vente non imposable sur les jetons (inférieure à 5000 €).');
}
}
if (results.messages.length) {
results.messages.push('La déclaration est inutile, il n\'y a pas d\'imposition.');
return res.json({
params: params,
results: results
});
}
results.isTaxable = true;
results.capitalGainCoeff = config.coeff.plus_value;
if (params.yearOwnership > config.palierDetention) {
/* A partir de la deuxième année, abattement de 5% sur le taux appliqué */
results.capitalGainCoeff = roundNumber((config.coeff.plus_value - (config.coeff.plus_value * (0.05 * (params.yearOwnership - config.palierDetention)))), 4);
results.capitalGain = Math.floor(results.capitalGainCoeff * (params.sellPrice - params.purchasePrice));
} else {
results.capitalGain = Math.floor(config.coeff.plus_value * (params.sellPrice - params.purchasePrice));
}
let value = roundNumber((results.capitalGainCoeff * 100), 2);
results.messages.push(`Le montant du régime des plus-value (${value}%) est de ${results.capitalGain} €.`);
results.bestChoice = 'gain';
if (params.taxationType != 'cours_legaux') {
results.lumpSum = Math.floor(params.sellPrice * config.coeff[params.taxationType]);
if (results.lumpSum < results.capitalGain) {
results.bestChoice = 'lumpSum';
}
results.lumpSumCoeff = config.coeff[params.taxationType];
value = (config.coeff[params.taxationType] * 100 );
results.messages.push(`Le montant de la taxe forfaitaire (${value}%) est de ${results.lumpSum} €.`);
results.messages.push(`La meilleure option pour vous est ${(results.bestChoice == 'lumpSum') ? 'la taxe forfaitaire' : 'la taxe sur le régime des plus values'}.`);
if (params.taxationType == 'jetons') {
results.messages.push(`À noter : pour une revente de produits de jetons en dessous du seuil des 5000€, aucune taxe n'est applicable.`);
}
} else {
results.messages.push('La taxe forfaitaire n\'est pas applicable pour les produits à cours légaux. Seule la taxe sur le régime des plus-values est applicable.');
results.messages.push('À noter : pour une revente de produits à cours légaux en dessous du seuil des 5000 €, aucune taxe n\'est applicable.');
}
return res.json({
params: params,
results: results
});
});
router.all('*', function (req, res, next) {
return res.status(404).json({
errors: {
name: 'UnknownRouteError',
message: 'La route API demandée est introuvable.'
}
});
});
function roundNumber(num, dec){
var num_sign = num >= 0 ? 1 : -1;
return parseFloat((Math.round((num * Math.pow(10, dec)) + (num_sign * 0.0001)) / Math.pow(10, dec)).toFixed(dec));
}
module.exports = router;