Catégorisation des platformes et application de la fiscalité adapté (Impact PSAN , régime micro-BIC)

This commit is contained in:
ocroguennec committed 2026-08-30 16:53:04 +02:00
1 parent 8953d0bb35
commit 33fee587aa
10 files changed
+610 -53

No files matched your search

+18 -14
View File
@@ -54,6 +54,7 @@ const Schema = z.object({
fiscalite: z.enum(['flat_tax', 'sans_fiscalite_locale', 'avec_fiscalite_locale']).default('flat_tax'),
taux_fiscalite_locale: z.number().min(0).max(100).nullable().optional(),
type_produit_fiscal: z.enum(['2TT', '2TR']).default('2TT'),
categorie_plateforme: z.enum(['psfp', 'psan']).default('psfp'),
methode_remboursement: z.enum(['portefeuille', 'compte_courant', 'choix_investisseur']).default('portefeuille'),
investisseur_id: z.number().int().positive().nullable().optional(),
date_ouverture: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
@@ -63,7 +64,7 @@ const Schema = z.object({
});
// Champs hérités du référentiel (comparés pour calculer overridden_fields)
const HERITABLE_FIELDS = ['nom', 'url', 'domiciliation', 'fiscalite', 'taux_fiscalite_locale', 'type_produit_fiscal', 'logo_filename', 'icone_filename', 'methode_remboursement', 'type_pret_defaut', 'freq_interets_defaut'];
const HERITABLE_FIELDS = ['nom', 'url', 'domiciliation', 'fiscalite', 'taux_fiscalite_locale', 'type_produit_fiscal', 'categorie_plateforme', 'logo_filename', 'icone_filename', 'methode_remboursement', 'type_pret_defaut', 'freq_interets_defaut'];
/**
* Calcule overridden_fields : champs dont la valeur diffère du référentiel.
@@ -222,7 +223,7 @@ function syncCategories(platId, catIds) {
router.get('/referentiel-list', (_req, res) => {
const rows = db.prepare(`
SELECT pr.id, pr.nom, pr.url, pr.domiciliation, pr.fiscalite,
pr.taux_fiscalite_locale, pr.type_produit_fiscal, pr.logo_filename, pr.icone_filename,
pr.taux_fiscalite_locale, pr.type_produit_fiscal, pr.categorie_plateforme, pr.logo_filename, pr.icone_filename,
pr.methode_remboursement, pr.type_pret_defaut, pr.freq_interets_defaut
FROM plateformes_referentiel pr
ORDER BY pr.nom
@@ -233,7 +234,7 @@ router.get('/referentiel-list', (_req, res) => {
router.get('/', (req, res) => {
const rows = db.prepare(`
SELECT p.id, p.nom, p.url, p.notes, p.domiciliation, p.fiscalite, p.taux_fiscalite_locale,
p.type_produit_fiscal,
p.type_produit_fiscal, p.categorie_plateforme,
p.methode_remboursement, p.investisseur_id, p.date_ouverture, p.logo_filename, p.icone_filename, p.created_at,
p.type_pret_defaut, p.freq_interets_defaut,
p.referentiel_id, p.overridden_fields,
@@ -283,15 +284,15 @@ router.post('/', (req, res, next) => {
const r = db.prepare(`
INSERT INTO plateformes
(user_id, nom, url, notes, domiciliation, fiscalite, taux_fiscalite_locale, type_produit_fiscal,
(user_id, nom, url, notes, domiciliation, fiscalite, taux_fiscalite_locale, type_produit_fiscal, categorie_plateforme,
methode_remboursement, investisseur_id, date_ouverture,
type_pret_defaut, freq_interets_defaut,
logo_filename, icone_filename,
referentiel_id, overridden_fields)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
`).run(
req.user.id, body.nom, body.url || null, body.notes || null,
body.domiciliation, fiscalite, taux, typeProduitFiscal,
body.domiciliation, fiscalite, taux, typeProduitFiscal, body.categorie_plateforme,
body.methode_remboursement, body.investisseur_id ?? null, body.date_ouverture || null,
body.type_pret_defaut ?? null, body.freq_interets_defaut ?? null,
logoFilename, iconeFilename,
@@ -358,6 +359,7 @@ router.get('/export', (req, res, next) => {
fiscalite: r.fiscalite,
taux_fiscalite_locale: r.taux_fiscalite_locale,
type_produit_fiscal: r.type_produit_fiscal,
categorie_plateforme: r.categorie_plateforme,
methode_remboursement: r.methode_remboursement,
date_ouverture: r.date_ouverture,
type_pret_defaut: r.type_pret_defaut,
@@ -426,6 +428,7 @@ router.get('/:id/export', (req, res, next) => {
domiciliation: withAll.domiciliation, fiscalite: withAll.fiscalite,
taux_fiscalite_locale: withAll.taux_fiscalite_locale,
type_produit_fiscal: withAll.type_produit_fiscal,
categorie_plateforme: withAll.categorie_plateforme,
methode_remboursement: withAll.methode_remboursement,
date_ouverture: withAll.date_ouverture,
type_pret_defaut: withAll.type_pret_defaut, freq_interets_defaut: withAll.freq_interets_defaut,
@@ -555,7 +558,7 @@ router.post('/import-zip', zipUpload.single('file'), async (req, res, next) => {
const fields = [
p.url || null, p.notes || null,
p.domiciliation || 'france', fiscalite, taux,
p.type_produit_fiscal || '2TT', p.methode_remboursement || 'portefeuille',
p.type_produit_fiscal || '2TT', p.categorie_plateforme || 'psfp', p.methode_remboursement || 'portefeuille',
investisseurId, p.date_ouverture || null,
p.type_pret_defaut || null, p.freq_interets_defaut || null,
p.logo_filename || null, p.icone_filename || null,
@@ -564,7 +567,7 @@ router.post('/import-zip', zipUpload.single('file'), async (req, res, next) => {
if (existing) {
db.prepare(`
UPDATE plateformes SET url=?, notes=?, domiciliation=?, fiscalite=?, taux_fiscalite_locale=?,
type_produit_fiscal=?, methode_remboursement=?, investisseur_id=?, date_ouverture=?,
type_produit_fiscal=?, categorie_plateforme=?, methode_remboursement=?, investisseur_id=?, date_ouverture=?,
type_pret_defaut=?, freq_interets_defaut=?,
logo_filename=?, icone_filename=?
WHERE id=? AND user_id=?
@@ -575,10 +578,10 @@ router.post('/import-zip', zipUpload.single('file'), async (req, res, next) => {
const r = db.prepare(`
INSERT INTO plateformes
(user_id, nom, url, notes, domiciliation, fiscalite, taux_fiscalite_locale,
type_produit_fiscal, methode_remboursement, investisseur_id, date_ouverture,
type_produit_fiscal, categorie_plateforme, methode_remboursement, investisseur_id, date_ouverture,
type_pret_defaut, freq_interets_defaut,
logo_filename, icone_filename, overridden_fields)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
`).run(req.user.id, p.nom, ...fields, '[]');
platId = r.lastInsertRowid;
created++;
@@ -629,6 +632,7 @@ router.put('/:id', (req, res, next) => {
fiscalite,
taux_fiscalite_locale: taux,
type_produit_fiscal: typeProduitFiscal,
categorie_plateforme: body.categorie_plateforme,
logo_filename: current.logo_filename, // logo géré séparément
methode_remboursement: body.methode_remboursement,
type_pret_defaut: body.type_pret_defaut ?? null,
@@ -640,13 +644,13 @@ router.put('/:id', (req, res, next) => {
const r = db.prepare(`
UPDATE plateformes
SET nom=?, url=?, notes=?, domiciliation=?, fiscalite=?, taux_fiscalite_locale=?,
type_produit_fiscal=?, methode_remboursement=?, investisseur_id=?, date_ouverture=?,
type_produit_fiscal=?, categorie_plateforme=?, methode_remboursement=?, investisseur_id=?, date_ouverture=?,
type_pret_defaut=?, freq_interets_defaut=?,
overridden_fields=?
WHERE id=? AND user_id=?
`).run(
body.nom, body.url || null, body.notes || null, body.domiciliation, fiscalite, taux,
typeProduitFiscal, body.methode_remboursement, body.investisseur_id ?? null, body.date_ouverture || null,
typeProduitFiscal, body.categorie_plateforme, body.methode_remboursement, body.investisseur_id ?? null, body.date_ouverture || null,
body.type_pret_defaut ?? null, body.freq_interets_defaut ?? null,
JSON.stringify(overriddenFields),
req.params.id, req.user.id
@@ -781,12 +785,12 @@ router.post('/:id/reset', (req, res, next) => {
db.prepare(`
UPDATE plateformes
SET nom=?, url=?, domiciliation=?, fiscalite=?, taux_fiscalite_locale=?,
type_produit_fiscal=?, logo_filename=?, methode_remboursement=?,
type_produit_fiscal=?, categorie_plateforme=?, logo_filename=?, methode_remboursement=?,
type_pret_defaut=?, freq_interets_defaut=?, overridden_fields='[]'
WHERE id=? AND user_id=?
`).run(
ref.nom, ref.url ?? null, ref.domiciliation, ref.fiscalite, ref.taux_fiscalite_locale ?? null,
ref.type_produit_fiscal, ref.logo_filename ?? null, ref.methode_remboursement || 'portefeuille',
ref.type_produit_fiscal, ref.categorie_plateforme || 'psfp', ref.logo_filename ?? null, ref.methode_remboursement || 'portefeuille',
ref.type_pret_defaut ?? null, ref.freq_interets_defaut ?? null,
req.params.id, req.user.id
);