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;