---|main| Initial commit
This commit is contained in:
@@ -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;
|
||||
Reference in New Issue
Block a user