129 lines
5.6 KiB
JavaScript
129 lines
5.6 KiB
JavaScript
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; |