<script lang="ts"> import * as H from '../../../helpers' import type { Sample } from '../../../plot' import { Derived } from './calcul' import type { PVGIS } from './calcul' import { getContext } from 'svelte' import type { Writable } from 'svelte/store' import { onMount } from 'svelte' const _simulation: Derived = getContext("simulation") const soleil: Writable<Sample> = getContext("soleil") const pvgis: Writable<{ pvgis: PVGIS | null, loading: boolean }> = getContext("pvgis") let maxProd = 0 onMount(() => { soleil.subscribe((value) => { for(let v of value.weekly.y) { maxProd = Math.max(maxProd, v) } }) }); const fmt2 = Intl.NumberFormat('fr-FR', { maximumFractionDigits: 2 }) const fmt0 = Intl.NumberFormat('fr-FR', { maximumFractionDigits: 0 }) const tarifLocal = _simulation.tarifLocal const chiffreAffaires = _simulation.chiffreAffaires const N = _simulation.N const investissement = _simulation.investissement const charges = _simulation.charges const interetsDetteSenior = _simulation.interetsDetteSenior const banque = _simulation.banque.resultat const resultatNet = _simulation.resultatNet const _coutElec = _simulation.p.cout_elec const inflationElec = _simulation.p.inflation_elec const autoprod = _simulation.p.autoprod const productible = _simulation.p.productible const puissance = _simulation.p.puissance const degradation = _simulation.p.degradation const _consoMoyenneFoyer = _simulation.p.conso_moyenne_foyer let an = new Date().getFullYear() const arr = 0 let resultatNetData: { id: string; data: { x: number; y: number }[] }[] = [ { id: '', data: [] }, ] $: { resultatNetData[0] = { id: '', data: new Array($N).fill(0).map((_, i) => { return { x: an + i, y: $resultatNet[i] } }), } } // Synthèse $: consoMoyenneFoyer = (i: number) => Math.min($_consoMoyenneFoyer, H.productionAnnuelle($productible, $puissance, $degradation, i) / $autoprod) $: coutElec = () => { let cout = 0 for (let i = 0; i < $N; i++) { cout += $_coutElec * Math.pow(1 + $inflationElec / 100, i) * consoMoyenneFoyer(i) } return cout } $: coutElecAuto = () => { let cout = 0 for (let i = 0; i < $N; i++) { cout += ($tarifLocal[i] * consoMoyenneFoyer(i) * $autoprod) / 100 + ($_coutElec * Math.pow(1 + $inflationElec / 100, i) * consoMoyenneFoyer(i) * (100 - $autoprod)) / 100 } return cout } $: coutElec_ = coutElec() $: coutElecAuto_ = coutElecAuto() function sum_(x: number[], n: number) { let sum = 0; for(let i = 0; i < n; i++) { sum += x[i] } return sum } function format(x: number) { let f = 0 let s = '' if (Math.abs(x) <= 1000) { s = ' €' f = x } else if (Math.abs(x) < 1000000) { s = ' k€' f = x / 1000 } else if (Math.abs(x) < 1000000000) { s = ' M€' f = x / 1000000 } else { s = ' mds€' f = x / 1000000000 } return fmt2.format(f) + s } function rentabiliteTaux(resultat: number): string { return ( fmt0.format( $investissement ? (resultat * 100) / $investissement - 100 : 0 ) + '%' ) } let maxa = 0 let mina = 0 let margin = 1 function traceArray(f: Array<number>, n: number) { let c = '' let ai = 0 maxa = -1 / 0 mina = 1 / 0 for (let i = 0; i < n; i++) { ai += f[i] maxa = Math.max(maxa, ai) mina = Math.min(mina, ai) c += ` ${c ? 'L' : 'M'} ${i.toFixed(arr)}, ${-ai.toFixed(arr)}` } if (maxa == -1 / 0) { maxa = 0 mina = 0 } margin = Math.max(1, (maxa - mina) / 20) return c } $: roiDate = () => { let sum = 0 let lastNeg = 0 for (let i = 0; i < $N; i += 1) { sum += $resultatNet[i] if (sum < 0) lastNeg = i } lastNeg += 1 if (lastNeg < $N) { if (lastNeg <= 1 && sum >= 0) { return `Tout de suite` } else if (lastNeg == 1) { return `1 an` } else { return `${lastNeg} ans` } } else { return 'À la saint Glinglin' } } $: rembPret = (n: number) => { let totalRembAnnuel_n = $banque.remboursementAnnuel .slice(0, n) .reduce((a, b) => a + b, 0) let totalInteret_n = sum_($interetsDetteSenior, n) let totalRembAnnuel = $banque.remboursementAnnuel.reduce((a, b) => a + b, 0) let totalInteret = sum_($interetsDetteSenior, n) return fmt0 .format( totalRembAnnuel + totalInteret ? ((totalRembAnnuel_n + totalInteret_n) * 100) / (totalRembAnnuel + totalInteret) : 0 ) } $: economieFoyerMois = fmt2.format( coutElec_ ? (coutElec_ - coutElecAuto_) / (coutElec_ / ($N * 12)) : 0 ) </script> <div class="tab-content" id="syntheseTabContent"> <div class="tab-pane fade show active p-3" id="synthese-tab-pane" role="tabpanel" aria-labelledby="synthese-tab" tabindex="0"> <h3 class="my-3 text-body fs-1 fw-bold"> En un regard, <span class="text-primary">tout</span> votre projet. </h3> <div class="my-5 py-2 total"> <h5>Synthèse durée totale {$N} ans</h5> <div class="row px-4"> <div class="d-flex justify-content-between p-5"> <div class="flex-column text-center"> <div class="donnee"> {format(sum_($chiffreAffaires, $N))} </div> <div>Chiffre d'affaire</div> </div> <div class="mx-3 flex-column text-center"> <div class="donnee"> {format(sum_($charges, $N))} </div> <div>Charges d'exploitation</div> </div> <div class="flex-column text-center"> <div class="donnee"> {format(sum_($resultatNet, $N))} </div> <div>Résultat net</div> </div> </div> </div> <div class="row px-4"> <div class="d-flex justify-content-between p-5"> <div class="flex-column text-center"> <div class="donnee"> {format($investissement)} </div> <div>Montant de l'investissement</div> </div> <div class="mx-3 flex-column text-center"> <div class="donnee"> {rentabiliteTaux(sum_($resultatNet, $N))} </div> <div>Retour sur investissement</div> </div> <div class="flex-column text-center"> <div class="donnee">{roiDate()}</div> <div>Point de rentabilité</div> </div> </div> </div> <div class="row flex-row-reverse px-4"> <div class="d-flex justify-content-around p-5"> <div class="d-flex flex-column justify-content-between text-center me-3"> <div class="py-3 my-auto"> <svg viewBox="{Math.floor( -$N * 0.05 )} {Math.floor( -maxa - margin )} {Math.ceil($N * 1.1)} {Math.ceil( maxa - mina + 2 * margin )}" xmlns="http://www.w3.org/2000/svg" width="250px" height="100px" preserveAspectRatio="none"> <path d={traceArray($resultatNet, $N)} fill="transparent" stroke-width="2" vector-effect="non-scaling-stroke" stroke="#b71515" /> </svg> </div> <div>Résultat net</div> </div> <div class="d-flex flex-column justify-content-between text-center ms-3"> <div style="width:250px" class="py-3 my-auto"> <div class="spinner-border ms-3 loading" class:d-none={!$pvgis.loading} /> <svg class:d-none={$pvgis.loading || !maxProd} viewBox="-10 0 270 {maxProd}" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" width="250px" height="100px"> {#each $soleil.weekly.y as p, i} <path d="M {i * 5}, {maxProd} L {i * 5}, {maxProd - p}" fill="transparent" stroke-width="2" stroke="#ffbf00" /> {/each} </svg> <svg class="donnee" class:d-none={$pvgis.loading || maxProd} xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" viewBox="0 0 16 16"> <path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278" /> </svg> </div> <div>Production annuelle</div> </div> </div> </div> <div class="row flex-row-reverse px-4"> <div class="d-flex justify-content-around p-5"> <div class="me-3 flex-column text-center"> <div class="donnee"> {$N ? format(sum_($resultatNet, $N) / $N) : '0€'} </div> <div>Bénéfice annuel moyen</div> </div> <div class="ms-3 flex-column text-center"> <div class="donnee"> {#if coutElec() - coutElecAuto() > 0} {format( coutElec() - coutElecAuto() )} ({economieFoyerMois} mois) {:else} Aucune 😢 {/if} </div> <div>Economies consommateur</div> </div> </div> </div> </div> <div class="my-5 py-2 dix"> <h5>Synthèse 10 ans</h5> <div class="row flex-row-reverse px-4"> <div class="d-flex justify-content-between p-5"> <div class="flex-column text-center"> <div class="donnee"> {format(sum_($chiffreAffaires, 10))} </div> <div>Chiffre d'affaire</div> </div> <div class="mx-3 flex-column text-center"> <div class="donnee"> {format(sum_($charges, 10))} </div> <div>Coût total</div> </div> <div class="flex-column text-center"> <div class="donnee"> {format(sum_($resultatNet, 10))} </div> <div>Résultat net</div> </div> </div> </div> <div class="row flex-row-reverse px-4 dix"> <div class="d-flex justify-content-around p-5"> <div class="flex-column justify-content-between text-center"> <div class="donnee">{rembPret(10)}%</div> <div>Prêt remboursé</div> </div> <div class="flex-column justify-content-between text-center"> <div class="donnee"> {rentabiliteTaux(sum_($resultatNet, 10))} </div> <div>Rentabilité</div> </div> </div> </div> </div> <div class="my-5 py-2 cinq"> <h5>Synthèse 5 ans</h5> <div class="row flex-row-reverse px-4"> <div class="d-flex justify-content-between p-5"> <div class="flex-column text-center"> <div class="donnee"> {format(sum_($chiffreAffaires, 5))} </div> <div>Chiffre d'affaire</div> </div> <div class="mx-3 flex-column text-center"> <div class="donnee"> {format(sum_($charges, 5))} </div> <div>Coût total</div> </div> <div class="flex-column text-center"> <div class="donnee"> {format(sum_($resultatNet, 5))} </div> <div>Résultat net</div> </div> </div> </div> <div class="row flex-row-reverse px-4"> <div class="d-flex justify-content-around p-5"> <div class="flex-column text-center"> <div class="donnee">{rembPret(5)}%</div> <div>Prêt remboursé</div> </div> <div class="flex-column text-center"> <div class="donnee"> {rentabiliteTaux(sum_($resultatNet, 5))} </div> <div>Rentabilité</div> </div> </div> </div> </div> <div class="my-5 py-2 moyenne"> <h5>Synthèse année moyenne</h5> <div class="row flex-row flex-wrap px-4"> <div class="d-flex justify-content-between py-5"> <div class="flex-column text-center mx-3"> <div class="donnee"> {format(sum_($resultatNet, $N) / $N)} </div> <div>Bénéfices moyen</div> </div> <div class="flex-column text-center mx-3"> <div class="donnee"> {format(sum_($chiffreAffaires, $N) / $N)} </div> <div>Chiffre d'affaire</div> </div> <div class="flex-column text-center mx-3"> <div class="donnee"> {fmt2.format( ($investissement ? (sum_($resultatNet, $N) * 100) / $investissement - 100 : 0) / $N )}% </div> <div>Rentabilité annuelle</div> </div> <div class="flex-column text-center mx-3"> <div class="donnee"> {#if coutElec() - coutElecAuto() > 0} {fmt0.format( ((coutElec() - coutElecAuto()) * 100) / coutElec() )}% {:else} Aucune 😢 {/if} </div> <div>Économies consommateur</div> </div> </div> </div> </div> </div> </div> <style lang="scss"> .loading { color: #ffbf00; } h5 { font-size: 1.5rem; font-weight: bold; } #syntheseTabContent h5 { border-bottom: 3px solid; font-size: 1.75rem; padding-bottom: 5px; } .donnee { font-size: 2rem; font-weight: bold; } .total .donnee { color: $gp-1; } .total h5 { color: $gp-1; border-color: $gp-1; } .dix .donnee { color: $gp-2; } .dix h5 { color: $gp-2; border-color: $gp-2; } .cinq .donnee { color: $gp-3; } .cinq h5 { color: $gp-3; border-color: $gp-3; } .moyenne .donnee { color: $gs-1; } .moyenne h5 { color: $gs-1; border-color: $gs-1; } </style>