<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>