refonte de monaa pour remplacer caotek.fr
@@ -29,10 +29,18 @@ def get_docs(request, doc_id):
|
||||
|
||||
def get_docs_bytheme(request, theme):
|
||||
"""Lire les doc"""
|
||||
query = "SELECT * FROM docs WHERE theme=:theme ORDER BY intitule;"
|
||||
if theme == 'BLOG':
|
||||
query = "SELECT * FROM docs WHERE theme=:theme ORDER BY cree_le DESC LIMIT 10;"
|
||||
else:
|
||||
query = "SELECT * FROM docs WHERE theme=:theme ORDER BY intitule;"
|
||||
results = request.dbsession.execute(query, {'theme': theme}).fetchall()
|
||||
return results
|
||||
|
||||
def get_blog_themes(request):
|
||||
query = "SELECT * FROM blog_themes;"
|
||||
results = request.dbsession.execute(query).fetchall()
|
||||
return results
|
||||
|
||||
def update_doc(request, doc_id, intitule, texte, theme):
|
||||
"""créér ou modifier le doc"""
|
||||
if doc_id == '0':
|
||||
|
||||
@@ -10,6 +10,7 @@ def includeme(config):
|
||||
config.add_route('allocation_edit', '/allocation_edit/{no_cat}')
|
||||
config.add_route('histo_list', '/histo_list')
|
||||
config.add_route('histo_edit', '/histo_edit/{no_id}')
|
||||
config.add_route('portfolio', '/portfolio')
|
||||
# members
|
||||
config.add_route('changer_mdp', '/changer_mdp')
|
||||
config.add_route('envoyer_mdp', '/envoyer_mdp')
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
.navbar {
|
||||
margin-bottom: 0;
|
||||
color: #404040 !important;
|
||||
color: #000000 !important;
|
||||
background-color: #ffffff !important;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
font-size: 20px !important;
|
||||
letter-spacing: 4px;
|
||||
}
|
||||
|
||||
.navbar li a, .navbar .navbar-brand {
|
||||
color: #404040 !important;
|
||||
color: #000000 !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
transform: translateX(-50%);
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* Dropdown */
|
||||
.open .dropdown-toggle {
|
||||
color: #000000 ;
|
||||
@@ -43,6 +49,12 @@
|
||||
color: #000000 !important;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.container{
|
||||
max-width: 900px;
|
||||
}
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
padding-top: 2em;
|
||||
padding-bottom: 1em;
|
||||
@@ -54,7 +66,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#doc-text {
|
||||
.monospace-font {
|
||||
font-family: Monaco, "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
@@ -79,9 +91,6 @@
|
||||
.bg-grey {
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
.logo {
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.logo-primary {
|
||||
font-size: 50px;
|
||||
|
||||
BIN
caotek_mesavoirs/static/img/blog/vpn_1.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
caotek_mesavoirs/static/img/blog/vpn_2.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
caotek_mesavoirs/static/img/blog/vpn_3.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
caotek_mesavoirs/static/img/blog/wonders_cao.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
caotek_mesavoirs/static/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
caotek_mesavoirs/static/img/logo-caotek.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
@@ -12,7 +12,7 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="classe">Classe</label>
|
||||
<div class="col-xs-3">
|
||||
<div class="col-xs-8">
|
||||
<select class="form-control" id="classe" name="classe">
|
||||
<div tal:repeat="item allocation_list">
|
||||
<option value="${item.classe}" tal:attributes="selected actif.classe==item.classe and 'selected' or None">${item.classe}</option>
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-xs-2 control-label">Identifiant</label>
|
||||
<div class="col-xs-3">
|
||||
<div class="col-xs-8">
|
||||
<input class="form-control" type="text" name="symbole"
|
||||
value="${actif.symbole}" placeholder="15 caractères maximum"
|
||||
data-fv-notempty="true"
|
||||
@@ -34,7 +34,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-xs-2 control-label">Libellé</label>
|
||||
<div class="col-xs-3">
|
||||
<div class="col-xs-8">
|
||||
<input class="form-control" type="text" name="libelle"
|
||||
value="${actif.libelle}" placeholder="45 caractères maximum"
|
||||
data-fv-notempty="true"
|
||||
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="pru">Total investi</label>
|
||||
<div class="col-xs-2">
|
||||
<div class="col-xs-6">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">K€</div>
|
||||
<input class="form-control" type="text" id="pru" name="pru" value="${actif.pru}"
|
||||
@@ -57,7 +57,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="cours">Total valeur</label>
|
||||
<div class="col-xs-2">
|
||||
<div class="col-xs-6">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">K€</div>
|
||||
<input class="form-control" type="text" id="cours" name="cours" value="${actif.cours}"
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="pc_rdt">% Rendement</label>
|
||||
<div class="col-xs-2">
|
||||
<div class="col-xs-6">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">%</div>
|
||||
<input class="form-control" type="text" id="rdt" name="pc_rdt" value="${actif.pc_rdt}"
|
||||
@@ -79,14 +79,14 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2">Dernière modif.</label>
|
||||
<div class="col-xs-7">
|
||||
<div class="col-xs-8">
|
||||
<p class="form-control-static" tal:condition="actif.modif_le">${actif.modif_le.strftime('%d/%m/%Y - %H:%M')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-xs-offset-2 col-xs-10">
|
||||
<div class="form-group">
|
||||
<a class="btn btn-default" href="${request.application_url}/">
|
||||
<a class="btn btn-default" href="${request.application_url}/portfolio">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
|
||||
<button class="btn btn-primary" type="submit" name="form.submitted">
|
||||
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="classe">Classe</label>
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-8">
|
||||
<select class="form-control" id="classe" name="classe">
|
||||
<div tal:repeat="item allocation_list">
|
||||
<option value="${item.classe}" tal:attributes="selected actif.classe==item.classe and 'selected' or None">${item.classe}</option>
|
||||
@@ -21,8 +21,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-xs-2 control-label">Symbole FT</label>
|
||||
<div class="col-xs-4">
|
||||
<label class="col-xs-2 control-label">Symbole Yahoo</label>
|
||||
<div class="col-xs-8">
|
||||
<input class="form-control" type="text" name="symbole"
|
||||
value="${actif.symbole}" placeholder="15 caractères maximum"
|
||||
data-fv-notempty="true"
|
||||
@@ -37,7 +37,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="nombre">Nombre</label>
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-8">
|
||||
<input class="form-control" type="text" id="nombre" name="nombre" value="${actif.nombre}"
|
||||
data-fv-digits="true"
|
||||
data-fv-digits-message="Le nombre doit être composé que de chiffres" />
|
||||
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="pru">PRU</label>
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-8">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">€</div>
|
||||
<input class="form-control" type="text" id="pru" name="pru" value="${actif.pru}"
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="ter">TER</label>
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-8">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">%</div>
|
||||
<input class="form-control" type="text" id="ter" name="ter" value="${actif.ter}"
|
||||
@@ -67,7 +67,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="pc_rdt">% Rendement</label>
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-8">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">%</div>
|
||||
<input class="form-control" type="text" id="pc_rdt" name="pc_rdt" value="${actif.pc_rdt}"
|
||||
@@ -78,7 +78,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2">Devise</label>
|
||||
<div class="col-xs-7">
|
||||
<div class="col-xs-8">
|
||||
<p class="form-control-static">${actif.devise}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,7 +94,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2">Dernière modif.</label>
|
||||
<div class="col-xs-7">
|
||||
<div class="col-xs-8">
|
||||
<p class="form-control-static" tal:condition="actif.modif_le">${actif.modif_le.strftime('%d/%m/%Y - %H:%M')}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -102,7 +102,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-xs-offset-2 col-xs-10">
|
||||
<div class="form-group">
|
||||
<a class="btn btn-default" href="${request.application_url}/">
|
||||
<a class="btn btn-default" href="${request.application_url}/portfolio">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
|
||||
<button class="btn btn-primary" type="submit" name="form.submitted">
|
||||
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
<div metal:fill-slot="content">
|
||||
|
||||
<p>
|
||||
<a href="${request.application_url}/" class="btn btn-default" role="button">
|
||||
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
|
||||
<a href="histo_edit/0" class="btn btn-success" role="button">
|
||||
<span class="glyphicon glyphicon-plus"></span> Entrée / Sortie cash</a>
|
||||
</p>
|
||||
|
||||
232
caotek_mesavoirs/templates/actifs/portfolio.pt
Normal file
@@ -0,0 +1,232 @@
|
||||
<metal:block use-macro="main_template">
|
||||
<div metal:fill-slot="content">
|
||||
|
||||
<div tal:condition="message" tal:content="message" class="alert alert-success" />
|
||||
|
||||
<p>
|
||||
<a href="allocation_edit/0" class="btn btn-success" role="button">
|
||||
<span class="glyphicon glyphicon-plus"></span> Nouvelle classe</a>
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table id="categories_list" class="table table-condensed table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Classe</th>
|
||||
<th class="text-right">% cible</th>
|
||||
<th class="text-right">% actuel</th>
|
||||
<th class="text-right">Ecart</th>
|
||||
<th class="text-right">Valeur</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr tal:repeat="item items">
|
||||
<td class="${item.bg_color}">${item.classe}</td>
|
||||
<td class="text-right"><a href="allocation_edit/${item.no_cat}">${item.pc_cible} %</a></td>
|
||||
<td class="text-right">${layout.to_percent(item.pc_atteint,1)}</td>
|
||||
<td tal:condition="(item.pc_atteint - item.pc_cible)>=0" class="text-right" style="color: green;">${layout.to_percent(item.pc_atteint - item.pc_cible,1)}</td>
|
||||
<td tal:condition="(item.pc_atteint - item.pc_cible) <0" class="text-right" style="color: red;">${layout.to_percent(item.pc_atteint - item.pc_cible,1)}</td>
|
||||
<td class="text-right">${layout.to_euro(item.valeur)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table id="portfolio" class="table table-condensed table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Portefeuille</th>
|
||||
<th class="text-right">Montant</th>
|
||||
<th class="text-right">%</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Valorisation</td>
|
||||
<td class="text-right">${layout.to_euro(member.pf_valeur)}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Plus value</td>
|
||||
<td class="text-right">${layout.to_euro(member.pf_plusvalue)}</td>
|
||||
<td class="text-right">${layout.to_percent(member.pf_plusvalue_pc, 1)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rendemant brut</td>
|
||||
<td class="text-right">${layout.to_euro(member.pf_rendement)}</td>
|
||||
<td class="text-right">${layout.to_percent(member.pf_rdt_pc, 1)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
<b>Allocation globale</b> : 60% actions + 5% REITS + 35% obligations<br />
|
||||
<b>Allocation actions D</b> (1/2) : 60% US (18%) + 30% Europe (12%)<br />
|
||||
<b>Allocation actions C</b> (1/2) : 100% World (30%) <br />
|
||||
[Cette allocation est inspirée de celle du <a href="https://www.nbim.no/en/the-fund/how-we-invest/benchmark-index/">Fond souverain Norvégien</a>]
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<!-- graphique donut cible -->
|
||||
<div id="donutchart_cible" style="width: 100%; height: 500px;"></div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<!-- graphique donut actuel -->
|
||||
<div id="donutchart_actuel" style="width: 100%; height: 500px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<h3>Mes actifs</h3>
|
||||
<p>"<i>Diversification is not determined by the number of securities held.</i>"
|
||||
<a href="http://www.etf.com/sections/index-investor-corner" target="_blank">Larry Swedroe</a></p>
|
||||
|
||||
<form id="actif_list-form" action="${url}" method="post">
|
||||
<div class="form-group">
|
||||
<button id="updateButton" class="btn btn-primary" type="submit" name="form.submitted">
|
||||
<i class="glyphicon glyphicon-refresh"></i> MAJ du portefeuille</button>
|
||||
<a href="#" class="btn btn-success" role="button"
|
||||
data-toggle="modal" data-target="#choixTypeActif"><span class="glyphicon glyphicon-plus"></span> Nouvel actif</a>
|
||||
<a href="${request.application_url}/histo_list" class="btn btn-default" role="button">
|
||||
<span class="glyphicon glyphicon-stats"></span> Historique</a>
|
||||
<a href="${request.application_url}/doc_view/2" class="btn btn-default" role="button">
|
||||
<span class="glyphicon glyphicon-folder-close"></span> Mouvements</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table id="actifs_list" class="table table-condensed table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Classe</th>
|
||||
<th>Libellé</th>
|
||||
<th class="text-right">Cours</th>
|
||||
<th class="text-right">Nb</th>
|
||||
<th class="text-right">Valeur</th>
|
||||
<th class="text-right">+/- Valeur</th>
|
||||
<th class="text-right">% de +/-</th>
|
||||
<th class="text-right">Rdt brut</th>
|
||||
<th class="text-right">% Rdt</th>
|
||||
<th class="text-right">% PF</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr tal:repeat="ligne actifs">
|
||||
<td class="${ligne.bg_color}">${ligne.classe}</td>
|
||||
<td tal:condition="ligne.type=='ACTION'"><a href="actif_edit/${ligne.no_id}">${ligne.libelle}</a></td>
|
||||
<td tal:condition="ligne.type!='ACTION'"><a href="actif2_edit/${ligne.no_id}">${ligne.libelle}</a></td>
|
||||
<td tal:condition="ligne.devise=='EUR'" class="text-right">${layout.to_euro(ligne.cours)}</td>
|
||||
<td tal:condition="ligne.devise=='USD'" class="text-right">${layout.to_usd(ligne.cours)}</td>
|
||||
<td class="text-right">${ligne.nombre}</td>
|
||||
<td class="text-right">${layout.to_euro(ligne.valeur)}</td>
|
||||
<td tal:condition="ligne.plus_value>=0" class="text-right" style="color: green;">${layout.to_euro(ligne.plus_value)}</td>
|
||||
<td tal:condition="ligne.plus_value <0" class="text-right" style="color: red;">${layout.to_euro(ligne.plus_value)}</td>
|
||||
<td tal:condition="ligne.pc_plusvalue>=0" class="text-right" style="color: green;">${layout.to_percent(ligne.pc_plusvalue,1)}</td>
|
||||
<td tal:condition="ligne.pc_plusvalue <0" class="text-right" style="color: red;">${layout.to_percent(ligne.pc_plusvalue,1)}</td>
|
||||
<td class="text-right">${u'%.0f €' % (ligne.rendement)}</td>
|
||||
<td class="text-right">${layout.to_percent(ligne.pc_rdt,1)}</td>
|
||||
<td class="text-right">${ligne.pc_allocation} %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-right" colspan="4"><b>Total</b></td>
|
||||
<td tal:condition="total_valeur>=0" class="text-right" style="color: green;"><b>${layout.to_euro(total_valeur)}</b></td>
|
||||
<td tal:condition="total_valeur <0" class="text-right" style="color: red;"><b>${layout.to_euro(total_valeur)}</b></td>
|
||||
<td tal:condition="total_pv>=0" class="text-right" style="color: green;"><b>${layout.to_euro(total_pv)}</b></td>
|
||||
<td tal:condition="total_pv <0" class="text-right" style="color: red;"><b>${layout.to_euro(total_pv)}</b></td>
|
||||
<td class="text-right"><b>${layout.to_percent(total_pc_value, 1)}</b></td>
|
||||
<td class="text-right"><b>${total_rdt} €</b></td>
|
||||
<td></td>
|
||||
<td class="text-right"><b>100.0 %</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>
|
||||
<!-- graphique evolution -->
|
||||
<div id="curve_chart" style="width: 100%; height: 500px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODAL POPUP : Affichage de la FAQ -->
|
||||
<div class="modal fade" id="choixTypeActif" tabindex="-1" role="dialog" aria-labelledby="choixTypeActif" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span class="glyphicon glyphicon-remove"></span></button>
|
||||
<h4 class="modal-title" id="choixTypeActif">Choix du type d'actif à créer</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Voulez-vous créer un actif de type <br />
|
||||
<br />
|
||||
<a href="${request.application_url}/actif_edit/0" class="btn btn-primary" role="button">
|
||||
ACTION</a> ou
|
||||
<a href="${request.application_url}/actif2_edit/0" class="btn btn-warning" role="button">
|
||||
AUTRE</a>
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#updateButton').on('click', function(){
|
||||
$('i.gly-spin').removeClass('gly-spin');
|
||||
$('i').addClass('gly-spin');
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
google.charts.load("current", {packages:["corechart"]});
|
||||
google.charts.setOnLoadCallback(drawChart);
|
||||
var dataSet_cible = ${donut_cible};
|
||||
var dataSet_actuel = ${donut_actuel};
|
||||
var dataSet_evoln = ${courbe_evoln};
|
||||
|
||||
function drawChart() {
|
||||
var data_cible = google.visualization.arrayToDataTable(dataSet_cible);
|
||||
var data_actuel = google.visualization.arrayToDataTable(dataSet_actuel);
|
||||
var data_evoln = google.visualization.arrayToDataTable(dataSet_evoln);
|
||||
|
||||
var options_cible = {
|
||||
title: 'Allocation cible',
|
||||
pieHole: 0.4,
|
||||
slices: {
|
||||
0: {color: 'SteelBlue'}, 1: {color: 'LightSteelBlue'},
|
||||
2: {color: 'Maroon'}, 3: {color: 'Brown'},
|
||||
5: {offset: 0.2, color: 'DarkGreen'}, 6: {offset: 0.3, color: 'Green'},
|
||||
},
|
||||
};
|
||||
var options_actuel = {
|
||||
title: 'Allocation actuelle',
|
||||
pieHole: 0.4,
|
||||
slices: {
|
||||
0: {color: 'SteelBlue'}, 1: {color: 'LightSteelBlue'},
|
||||
2: {color: 'Maroon'}, 3: {color: 'Brown'},
|
||||
5: {offset: 0.2, color: 'DarkGreen'}, 6: {offset: 0.3, color: 'Green'},
|
||||
},
|
||||
};
|
||||
var options_evoln = {
|
||||
title: 'Evolution du portefeuille VS fond Carmignac Investissement',
|
||||
curveType: 'function',
|
||||
legend: { position: 'top' }
|
||||
};
|
||||
|
||||
var chart_cible = new google.visualization.PieChart(document.getElementById('donutchart_cible'));
|
||||
chart_cible.draw(data_cible, options_cible);
|
||||
var chart_actuel = new google.visualization.PieChart(document.getElementById('donutchart_actuel'));
|
||||
chart_actuel.draw(data_actuel, options_actuel);
|
||||
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
|
||||
chart.draw(data_evoln, options_evoln);
|
||||
}
|
||||
</script>
|
||||
|
||||
</div><!-- content -->
|
||||
</metal:block>
|
||||
|
||||
@@ -8,30 +8,29 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="intitule">Intitulé</label>
|
||||
<div class="col-xs-8">
|
||||
<div class="col-xs-10">
|
||||
<input class="form-control" type="text" id="intitule" name="intitule" value="${intitule}"
|
||||
placeholder="40 caractères maximum"
|
||||
data-fv-notempty="true"
|
||||
data-fv-notempty-message="L'intitule est obligatoire"
|
||||
data-fv-stringlength="true"
|
||||
data-fv-stringlength-max="40"
|
||||
data-fv-stringlength-message="40 caractères maximum" />
|
||||
data-fv-stringlength-max="100"
|
||||
data-fv-stringlength-message="100 caractères maximum" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="texte">Texte</label>
|
||||
<div class="col-xs-8">
|
||||
<textarea class="form-control" rows="15" cols="40" id="texte" name="texte">${texte}</textarea>
|
||||
<div class="col-xs-10">
|
||||
<textarea class="form-control monospace-font" rows="15" cols="40" id="texte" name="texte">${texte}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2" for="theme">Thème</label>
|
||||
<div class="col-xs-4">
|
||||
<div class="col-xs-6">
|
||||
<select class="form-control" id="theme" name="theme">
|
||||
<div tal:repeat="item themes">
|
||||
<option value="${item}" tal:attributes="selected theme==item and 'selected' or None">${item}</option>
|
||||
<option value="${item.theme}" tal:attributes="selected theme==item.theme and 'selected' or None">${item.theme}</option>
|
||||
</div>
|
||||
</select>
|
||||
</div>
|
||||
@@ -66,16 +65,6 @@ $(document).ready(function() {
|
||||
invalid: 'glyphicon glyphicon-remove',
|
||||
validating: 'glyphicon glyphicon-refresh'
|
||||
},
|
||||
fields: {
|
||||
texte: {
|
||||
validators: {
|
||||
stringLength: {
|
||||
max: 30000,
|
||||
message: '30000 caractères maximum'
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
$('form input').on('keypress', function(e) {
|
||||
return e.which !== 13;
|
||||
|
||||
@@ -7,35 +7,24 @@
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
Créér une nouvelle doc</a>
|
||||
</p>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-6">
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
<tr>
|
||||
<th>FINANCE</th>
|
||||
<th>MEMOS</th>
|
||||
</tr>
|
||||
|
||||
<tr tal:repeat="ligne docs_finance">
|
||||
<tr tal:repeat="ligne memos">
|
||||
<td><a href="doc_view/${ligne.doc_id}">${ligne.intitule}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-6">
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
<tr>
|
||||
<th>VOITURE</th>
|
||||
<th>DOCUMENTS</th>
|
||||
</tr>
|
||||
|
||||
<tr tal:repeat="ligne docs_voiture">
|
||||
<td><a href="doc_view/${ligne.doc_id}">${ligne.intitule}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<table class="table table-condensed table-striped table-bordered">
|
||||
<tr>
|
||||
<th class="text-center">MAISON</th>
|
||||
</tr>
|
||||
|
||||
<tr tal:repeat="ligne docs_maison">
|
||||
<tr tal:repeat="ligne docs">
|
||||
<td><a href="doc_view/${ligne.doc_id}">${ligne.intitule}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,232 +1,31 @@
|
||||
<metal:block use-macro="main_template">
|
||||
<div metal:fill-slot="content">
|
||||
|
||||
<div tal:condition="message" tal:content="message" class="alert alert-success" />
|
||||
|
||||
<p>
|
||||
<a href="allocation_edit/0" class="btn btn-success" role="button">
|
||||
<span class="glyphicon glyphicon-plus"></span> Nouvelle classe</a>
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table id="categories_list" class="table table-condensed table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Classe</th>
|
||||
<th class="text-right">% cible</th>
|
||||
<th class="text-right">% actuel</th>
|
||||
<th class="text-right">Ecart</th>
|
||||
<th class="text-right">Valeur</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr tal:repeat="item items">
|
||||
<td class="${item.bg_color}">${item.classe}</td>
|
||||
<td class="text-right"><a href="allocation_edit/${item.no_cat}">${item.pc_cible} %</a></td>
|
||||
<td class="text-right">${layout.to_percent(item.pc_atteint,1)}</td>
|
||||
<td tal:condition="(item.pc_atteint - item.pc_cible)>=0" class="text-right" style="color: green;">${layout.to_percent(item.pc_atteint - item.pc_cible,1)}</td>
|
||||
<td tal:condition="(item.pc_atteint - item.pc_cible) <0" class="text-right" style="color: red;">${layout.to_percent(item.pc_atteint - item.pc_cible,1)}</td>
|
||||
<td class="text-right">${layout.to_euro(item.valeur)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<table id="portfolio" class="table table-condensed table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Portefeuille</th>
|
||||
<th class="text-right">Montant</th>
|
||||
<th class="text-right">%</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Valorisation</td>
|
||||
<td class="text-right">${layout.to_euro(member.pf_valeur)}</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Plus value</td>
|
||||
<td class="text-right">${layout.to_euro(member.pf_plusvalue)}</td>
|
||||
<td class="text-right">${layout.to_percent(member.pf_plusvalue_pc, 1)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rendemant brut</td>
|
||||
<td class="text-right">${layout.to_euro(member.pf_rendement)}</td>
|
||||
<td class="text-right">${layout.to_percent(member.pf_rdt_pc, 1)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
<b>Allocation globale</b> : 60% actions + 5% REITS + 35% obligations<br />
|
||||
<b>Allocation actions D</b> (1/2) : 60% US (18%) + 30% Europe (12%)<br />
|
||||
<b>Allocation actions C</b> (1/2) : 100% World (30%) <br />
|
||||
[Cette allocation est inspirée de celle du <a href="https://www.nbim.no/en/the-fund/how-we-invest/benchmark-index/">Fond souverain Norvégien</a>]
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<!-- graphique donut cible -->
|
||||
<div id="donutchart_cible" style="width: 100%; height: 500px;"></div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<!-- graphique donut actuel -->
|
||||
<div id="donutchart_actuel" style="width: 100%; height: 500px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h1>Blog</h1>
|
||||
<p tal:condition="not layout.isAnonymous()">
|
||||
<a href="doc_edit/0">Créer un nouveau post</a>
|
||||
</p>
|
||||
|
||||
<div class="row">
|
||||
<h3>Mes actifs</h3>
|
||||
<p>"<i>Diversification is not determined by the number of securities held.</i>"
|
||||
<a href="http://www.etf.com/sections/index-investor-corner" target="_blank">Larry Swedroe</a></p>
|
||||
|
||||
<form id="actif_list-form" action="${url}" method="post">
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
<button id="updateButton" class="btn btn-primary" type="submit" name="form.submitted">
|
||||
<i class="glyphicon glyphicon-refresh"></i> MAJ du portefeuille</button>
|
||||
<a href="#" class="btn btn-success" role="button"
|
||||
data-toggle="modal" data-target="#choixTypeActif"><span class="glyphicon glyphicon-plus"></span> Nouvel actif</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table id="actifs_list" class="table table-condensed table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Classe</th>
|
||||
<th>Libellé</th>
|
||||
<th class="text-right">Cours</th>
|
||||
<th class="text-right">Nb</th>
|
||||
<th class="text-right">Valeur</th>
|
||||
<th class="text-right">+/- Valeur</th>
|
||||
<th class="text-right">% de +/-</th>
|
||||
<th class="text-right">Rdt brut</th>
|
||||
<th class="text-right">% Rdt</th>
|
||||
<th class="text-right">% PF</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr tal:repeat="ligne actifs">
|
||||
<td class="${ligne.bg_color}">${ligne.classe}</td>
|
||||
<td tal:condition="ligne.type=='ACTION'"><a href="actif_edit/${ligne.no_id}">${ligne.libelle}</a></td>
|
||||
<td tal:condition="ligne.type!='ACTION'"><a href="actif2_edit/${ligne.no_id}">${ligne.libelle}</a></td>
|
||||
<td tal:condition="ligne.devise=='EUR'" class="text-right">${layout.to_euro(ligne.cours)}</td>
|
||||
<td tal:condition="ligne.devise=='USD'" class="text-right">${layout.to_usd(ligne.cours)}</td>
|
||||
<td class="text-right">${ligne.nombre}</td>
|
||||
<td class="text-right">${layout.to_euro(ligne.valeur)}</td>
|
||||
<td tal:condition="ligne.plus_value>=0" class="text-right" style="color: green;">${layout.to_euro(ligne.plus_value)}</td>
|
||||
<td tal:condition="ligne.plus_value <0" class="text-right" style="color: red;">${layout.to_euro(ligne.plus_value)}</td>
|
||||
<td tal:condition="ligne.pc_plusvalue>=0" class="text-right" style="color: green;">${layout.to_percent(ligne.pc_plusvalue,1)}</td>
|
||||
<td tal:condition="ligne.pc_plusvalue <0" class="text-right" style="color: red;">${layout.to_percent(ligne.pc_plusvalue,1)}</td>
|
||||
<td class="text-right">${u'%.0f €' % (ligne.rendement)}</td>
|
||||
<td class="text-right">${layout.to_percent(ligne.pc_rdt,1)}</td>
|
||||
<td class="text-right">${ligne.pc_allocation} %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-right" colspan="4"><b>Total</b></td>
|
||||
<td tal:condition="total_valeur>=0" class="text-right" style="color: green;"><b>${layout.to_euro(total_valeur)}</b></td>
|
||||
<td tal:condition="total_valeur <0" class="text-right" style="color: red;"><b>${layout.to_euro(total_valeur)}</b></td>
|
||||
<td tal:condition="total_pv>=0" class="text-right" style="color: green;"><b>${layout.to_euro(total_pv)}</b></td>
|
||||
<td tal:condition="total_pv <0" class="text-right" style="color: red;"><b>${layout.to_euro(total_pv)}</b></td>
|
||||
<td class="text-right"><b>${layout.to_percent(total_pc_value, 1)}</b></td>
|
||||
<td class="text-right"><b>${total_rdt} €</b></td>
|
||||
<td></td>
|
||||
<td class="text-right"><b>100.0 %</b></td>
|
||||
<table class="table">
|
||||
<tr tal:repeat="ligne items">
|
||||
<td>${ligne.cree_le.strftime("%Y")}</td>
|
||||
<td>${ligne.cree_le.strftime("%d %b")}</td>
|
||||
<td><a href="doc_view/${ligne.doc_id}"><b>${ligne.intitule}</b></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<!-- graphique evolution -->
|
||||
<div id="curve_chart" style="width: 200%; height: 500px;"></div>
|
||||
<div class="row well text-center" tal:condition="not layout.isAnonymous()">
|
||||
<div class="col-sm-3">
|
||||
<a href="${request.application_url}/portfolio"><span class="glyphicon glyphicon-piggy-bank logo-primary"></span></a>
|
||||
<h4>EPARGNE</h4>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="col-sm-3">
|
||||
<a href="${request.application_url}/doc_list"><span class="glyphicon glyphicon-list-alt logo-primary"></span></a>
|
||||
<h4>MEMOS</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODAL POPUP : Affichage de la FAQ -->
|
||||
<div class="modal fade" id="choixTypeActif" tabindex="-1" role="dialog" aria-labelledby="choixTypeActif" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span class="glyphicon glyphicon-remove"></span></button>
|
||||
<h4 class="modal-title" id="choixTypeActif">Choix du type d'actif à créer</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
Voulez-vous créer un actif de type <br />
|
||||
<br />
|
||||
<a href="${request.application_url}/actif_edit/0" class="btn btn-primary" role="button">
|
||||
ACTION</a> ou
|
||||
<a href="${request.application_url}/actif2_edit/0" class="btn btn-warning" role="button">
|
||||
AUTRE</a>
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('#updateButton').on('click', function(){
|
||||
$('i.gly-spin').removeClass('gly-spin');
|
||||
$('i').addClass('gly-spin');
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
|
||||
<script type="text/javascript">
|
||||
google.charts.load("current", {packages:["corechart"]});
|
||||
google.charts.setOnLoadCallback(drawChart);
|
||||
var dataSet_cible = ${donut_cible};
|
||||
var dataSet_actuel = ${donut_actuel};
|
||||
var dataSet_evoln = ${courbe_evoln};
|
||||
|
||||
function drawChart() {
|
||||
var data_cible = google.visualization.arrayToDataTable(dataSet_cible);
|
||||
var data_actuel = google.visualization.arrayToDataTable(dataSet_actuel);
|
||||
var data_evoln = google.visualization.arrayToDataTable(dataSet_evoln);
|
||||
|
||||
var options_cible = {
|
||||
title: 'Allocation cible',
|
||||
pieHole: 0.4,
|
||||
slices: {
|
||||
0: {color: 'SteelBlue'}, 1: {color: 'LightSteelBlue'},
|
||||
2: {color: 'Maroon'}, 3: {color: 'Brown'},
|
||||
5: {offset: 0.2, color: 'DarkGreen'}, 6: {offset: 0.3, color: 'Green'},
|
||||
},
|
||||
};
|
||||
var options_actuel = {
|
||||
title: 'Allocation actuelle',
|
||||
pieHole: 0.4,
|
||||
slices: {
|
||||
0: {color: 'SteelBlue'}, 1: {color: 'LightSteelBlue'},
|
||||
2: {color: 'Maroon'}, 3: {color: 'Brown'},
|
||||
5: {offset: 0.2, color: 'DarkGreen'}, 6: {offset: 0.3, color: 'Green'},
|
||||
},
|
||||
};
|
||||
var options_evoln = {
|
||||
title: 'Evolution du portefeuille VS fond Carmignac Investissement',
|
||||
curveType: 'function',
|
||||
legend: { position: 'top' }
|
||||
};
|
||||
|
||||
var chart_cible = new google.visualization.PieChart(document.getElementById('donutchart_cible'));
|
||||
chart_cible.draw(data_cible, options_cible);
|
||||
var chart_actuel = new google.visualization.PieChart(document.getElementById('donutchart_actuel'));
|
||||
chart_actuel.draw(data_actuel, options_actuel);
|
||||
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
|
||||
chart.draw(data_evoln, options_evoln);
|
||||
}
|
||||
</script>
|
||||
|
||||
</div><!-- content -->
|
||||
</metal:block>
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<title>${page_title}</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" />
|
||||
<link rel="shortcut icon" href="${request.static_url('caotek_mesavoirs:static/img/favicon.ico')}">
|
||||
|
||||
<!-- Bootstrap core + Plug-ins CSS -->
|
||||
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
|
||||
@@ -48,26 +49,24 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a href="${request.application_url}" alt="Accueil">
|
||||
<img src="${request.static_url('caotek_mesavoirs:static/img/logo.png')}" class="logo" /></a>
|
||||
MON PORTEFEUILLE
|
||||
<a class="navbar-brand" class="text-center" href="${request.application_url}" alt="Accueil">
|
||||
<img src="${request.static_url('caotek_mesavoirs:static/img/logo-caotek.png')}" class="logo" /></a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="myNavbar" tal:condition="not layout.isAnonymous()">
|
||||
<div class="collapse navbar-collapse" id="myNavbar">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="${request.application_url}/histo_list">HISTORIQUE</a></li>
|
||||
<li><a href="${request.application_url}/doc_list">DOCS</a></li>
|
||||
<!-- <li><a href="${request.application_url}/histo_list">HISTORIQUE</a></li> -->
|
||||
<li tal:condition="layout.isAnonymous()"><a href="${request.application_url}/login">se connecter</a></li>
|
||||
${panel('dropdown_menu_panel')}
|
||||
</ul>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<hr>
|
||||
<div class="container">
|
||||
<h1>${page_title}</h1>
|
||||
<br />
|
||||
<h1 tal:condition="request.path != '/'">${page_title}</h1>
|
||||
<div id="messages" tal:attributes="class request.is_xhr and 'ajax-replace' or None">
|
||||
<div tal:repeat="queue ('', 'info', 'success', 'warning', 'danger')"
|
||||
tal:omit-tag="">
|
||||
@@ -86,8 +85,24 @@
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<footer class="container-fluid bg-footer text-center">
|
||||
<p>© 2017 - www.caotek.fr - Powered by <a href="https://trypyramid.com/">Pyramid</a></p>
|
||||
<footer class="container-fluid bg-footer">
|
||||
<div class="row">
|
||||
<div class="col-xs-offset-2 col-xs-4">
|
||||
<p>L'argent que l'on possède est l'instrument de la liberté; celui que l'on pourchasse est celui de la servitude - <b>Rousseau</b></p>
|
||||
<p>L'intelligence ce n'est pas ce que l'on sait mais ce que l'on fait quand on ne sait pas - <b>Jean Piaget</b></p>
|
||||
</div>
|
||||
<div class="col-xs-offset-2 col-xs-4">
|
||||
<p>
|
||||
Apprendre Restructured Text <a href="https://github.com/ralsina/rst-cheatsheet/blob/master/rst-cheatsheet.rst">(reST)</a><br />
|
||||
Apprendre Markdown <a href="https://www.markdownguide.org/basic-syntax/">(md)</a><br />
|
||||
<a href="http://www.marinestylefitness.com/">Marine Style Fitness </a><br />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<p class="text-center">© 2017 - www.caotek.fr - Powered by <a href="https://trypyramid.com/">Pyramid</a></p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<div metal:define-slot="additional_scripts" />
|
||||
|
||||
@@ -34,6 +34,97 @@ import time
|
||||
import yfinance as yf
|
||||
import html
|
||||
|
||||
@view_config(route_name='portfolio', renderer='../templates/actifs/portfolio.pt', permission='view')
|
||||
def portfolio(request):
|
||||
logged_in = request.authenticated_userid
|
||||
member = get_member_by_email(request, logged_in)
|
||||
url = request.route_url('portfolio')
|
||||
|
||||
message = ''
|
||||
|
||||
# lire les categories
|
||||
items = get_allocation(request, '0')
|
||||
# construire la liste pour donut
|
||||
donut_cible=[]
|
||||
donut_cible.append(('Allocation cible', 'Pourcent'))
|
||||
donut_actuel=[]
|
||||
donut_actuel.append(('Allocation actuelle', 'Pourcent'))
|
||||
|
||||
# calculer % total
|
||||
total = 0
|
||||
for item in items:
|
||||
# construire la liste pour donut cible
|
||||
d = (item.classe, item.pc_cible)
|
||||
donut_cible.append(d)
|
||||
# construire la liste pour donut actuel
|
||||
d = (item.classe, int(item.pc_atteint * 10))
|
||||
donut_actuel.append(d)
|
||||
# totaliser les pourcentages
|
||||
total += item.pc_cible
|
||||
|
||||
if total != 100:
|
||||
message = 'Attention, le total de votre répartition cible est incorrect : %s.' % total
|
||||
|
||||
# lire les actifs
|
||||
actifs = get_actifs(request, '0')
|
||||
|
||||
# MAJ du prtefeuille
|
||||
if 'form.submitted' in request.params:
|
||||
# lire le cours de EURUSD
|
||||
ticker = yf.Ticker('EUR=X')
|
||||
# maj des parités des devises
|
||||
update_actif_devise(request, 'USD', ticker.info.get('regularMarketPrice'))
|
||||
|
||||
for item in actifs:
|
||||
if item.type == 'ACTION':
|
||||
# lire le cours de l'action
|
||||
ticker = yf.Ticker(item.symbole)
|
||||
# caluler son rendement
|
||||
dividends = get_dividends(ticker)
|
||||
update_actif_valeur(request, item.symbole, ticker.info.get('regularMarketPrice'), dividends)
|
||||
time.sleep(1) # attendre 2 secondes
|
||||
|
||||
# update du portefeuille
|
||||
update_portefeuille(request, logged_in)
|
||||
# relire les actifs
|
||||
actifs = get_actifs(request, '0')
|
||||
message = 'Le portefeuille est mis à jour avec succès.'
|
||||
|
||||
total_valeur = 0
|
||||
total_pv = 0
|
||||
total_rdt = 0
|
||||
for item in actifs:
|
||||
total_valeur += item.valeur
|
||||
total_pv += item.plus_value
|
||||
total_pc_value = total_pv / total_valeur * 100
|
||||
total_rdt += item.rendement
|
||||
|
||||
# lire l'historique
|
||||
histos = get_histo(request,'0')
|
||||
courbe_evoln=[]
|
||||
courbe_evoln.append(('Date', 'Valeur part PF', 'Valeur part CARINVT:FP'))
|
||||
|
||||
for item in histos:
|
||||
# construire la liste pour donut cible
|
||||
d = (item.date.strftime('%d/%m/%Y'), int(item.val_part * 1000), int(item.val_part_ref * 1000))
|
||||
courbe_evoln.append(d)
|
||||
|
||||
return {
|
||||
'page_title': "Portefeuille",
|
||||
'message': message,
|
||||
'url': url,
|
||||
'items': items,
|
||||
'member': member,
|
||||
'donut_cible': json.dumps(donut_cible),
|
||||
'donut_actuel': json.dumps(donut_actuel),
|
||||
'courbe_evoln': json.dumps(courbe_evoln),
|
||||
'actifs': actifs,
|
||||
'total_valeur': total_valeur,
|
||||
'total_pv': total_pv,
|
||||
'total_pc_value': total_pc_value,
|
||||
'total_rdt': total_rdt
|
||||
}
|
||||
|
||||
@view_config(route_name='actif_edit', renderer='../templates/actifs/actif_edit.pt', permission='view')
|
||||
def actif_edit(request):
|
||||
no_id = request.matchdict['no_id']
|
||||
@@ -61,7 +152,7 @@ def actif_edit(request):
|
||||
actif = get_actifs(request, no_id)
|
||||
if not actif:
|
||||
request.session.flash(u"Actif non trouvé : %s" % no_id, 'warning')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
page_title= "Actif ACTION : %s" % (actif.libelle)
|
||||
|
||||
if 'form.submitted' in request.params:
|
||||
@@ -80,16 +171,15 @@ def actif_edit(request):
|
||||
ticker = yf.Ticker(symbole)
|
||||
new_values['cours'] = ticker.info.get('regularMarketPrice')
|
||||
new_values['devise'] = ticker.info.get('currency')
|
||||
longName = html.unescape(ticker.info.get('longName'))
|
||||
new_values['libelle'] = longName.replace('Vanguard Funds Public Limited Company - ','').replace('Amundi Index Solutions - ','').replace('Distributing','')
|
||||
new_values['libelle'] = html.unescape(ticker.info.get('shortName'))
|
||||
update_actif(request, no_id, new_values)
|
||||
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
|
||||
if 'form.deleted' in request.params:
|
||||
delete_actif(request, no_id)
|
||||
request.session.flash(u"La fiche a été supprimée avec succès.", 'success')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
|
||||
return {
|
||||
'page_title': page_title,
|
||||
@@ -124,7 +214,7 @@ def actif2_edit(request):
|
||||
actif = get_actifs(request, no_id)
|
||||
if not actif:
|
||||
request.session.flash(u"Actif non trouvé : %s" % no_id, 'warning')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
page_title= "Actif : %s" % (actif.symbole)
|
||||
|
||||
if 'form.submitted' in request.params:
|
||||
@@ -137,12 +227,12 @@ def actif2_edit(request):
|
||||
new_values['devise'] = 'EUR'
|
||||
update_actif(request, no_id, new_values)
|
||||
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
|
||||
if 'form.deleted' in request.params:
|
||||
delete_actif(request, no_id)
|
||||
request.session.flash(u"La fiche a été supprimée avec succès.", 'success')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
|
||||
return {
|
||||
'page_title': page_title,
|
||||
@@ -174,7 +264,7 @@ def allocation_edit(request):
|
||||
allocation = get_allocation(request, no_cat)
|
||||
if not allocation:
|
||||
request.session.flash(u"Classe non trouvé : %s" % no_cat, 'warning')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
page_title= "Classe : %s" % (allocation.classe)
|
||||
|
||||
if 'form.submitted' in request.params:
|
||||
@@ -186,12 +276,12 @@ def allocation_edit(request):
|
||||
if new_values:
|
||||
update_allocation(request, no_cat, new_values)
|
||||
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
|
||||
if 'form.deleted' in request.params:
|
||||
delete_allocation(request, no_cat)
|
||||
request.session.flash(u"La fiche a été supprimée avec succès.", 'success')
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
return HTTPFound(location=request.route_url('portfolio'))
|
||||
|
||||
return {
|
||||
'page_title': page_title,
|
||||
|
||||
@@ -18,10 +18,6 @@ from sqlalchemy.exc import DBAPIError
|
||||
from ..security import groupfinder
|
||||
|
||||
from ..models.default import *
|
||||
from ..models.actifs import *
|
||||
from ..models.members import (
|
||||
get_member_by_email,
|
||||
)
|
||||
|
||||
# import datetime
|
||||
import time
|
||||
@@ -70,110 +66,28 @@ def to_percent(x, d):
|
||||
return pc.replace('.', ',')
|
||||
|
||||
|
||||
@view_config(route_name='home', renderer='../templates/home.pt', permission='view')
|
||||
@view_config(route_name='home', renderer='../templates/home.pt')
|
||||
def home(request):
|
||||
logged_in = request.authenticated_userid
|
||||
member = get_member_by_email(request, logged_in)
|
||||
url = request.route_url('home')
|
||||
|
||||
message = ''
|
||||
|
||||
# lire les categories
|
||||
items = get_allocation(request, '0')
|
||||
# construire la liste pour donut
|
||||
donut_cible=[]
|
||||
donut_cible.append(('Allocation cible', 'Pourcent'))
|
||||
donut_actuel=[]
|
||||
donut_actuel.append(('Allocation actuelle', 'Pourcent'))
|
||||
|
||||
# calculer % total
|
||||
total = 0
|
||||
for item in items:
|
||||
# construire la liste pour donut cible
|
||||
d = (item.classe, item.pc_cible)
|
||||
donut_cible.append(d)
|
||||
# construire la liste pour donut actuel
|
||||
d = (item.classe, int(item.pc_atteint * 10))
|
||||
donut_actuel.append(d)
|
||||
# totaliser les pourcentages
|
||||
total += item.pc_cible
|
||||
|
||||
if total != 100:
|
||||
message = 'Attention, le total de votre répartition cible est incorrect : %s.' % total
|
||||
|
||||
# lire les actifs
|
||||
actifs = get_actifs(request, '0')
|
||||
|
||||
# MAJ du prtefeuille
|
||||
if 'form.submitted' in request.params:
|
||||
# lire le cours de EURUSD
|
||||
ticker = yf.Ticker('EUR=X')
|
||||
# maj des parités des devises
|
||||
update_actif_devise(request, 'USD', ticker.info.get('regularMarketPrice'))
|
||||
|
||||
for item in actifs:
|
||||
if item.type == 'ACTION':
|
||||
# lire le cours de l'action
|
||||
ticker = yf.Ticker(item.symbole)
|
||||
# caluler son rendement
|
||||
dividends = get_dividends(ticker)
|
||||
update_actif_valeur(request, item.symbole, ticker.info.get('regularMarketPrice'), dividends)
|
||||
time.sleep(1) # attendre 2 secondes
|
||||
|
||||
# update du portefeuille
|
||||
update_portefeuille(request, logged_in)
|
||||
# relire les actifs
|
||||
actifs = get_actifs(request, '0')
|
||||
message = 'Le portefeuille est mis à jour avec succès.'
|
||||
|
||||
total_valeur = 0
|
||||
total_pv = 0
|
||||
total_rdt = 0
|
||||
for item in actifs:
|
||||
total_valeur += item.valeur
|
||||
total_pv += item.plus_value
|
||||
total_pc_value = total_pv / total_valeur * 100
|
||||
total_rdt += item.rendement
|
||||
|
||||
# lire l'historique
|
||||
histos = get_histo(request,'0')
|
||||
courbe_evoln=[]
|
||||
courbe_evoln.append(('Date', 'Valeur part PF', 'Valeur part CARINVT:FP'))
|
||||
|
||||
for item in histos:
|
||||
# construire la liste pour donut cible
|
||||
d = (item.date.strftime('%d/%m/%Y'), int(item.val_part * 1000), int(item.val_part_ref * 1000))
|
||||
courbe_evoln.append(d)
|
||||
# lire toutes les docs
|
||||
items = get_docs_bytheme(request, 'BLOG')
|
||||
|
||||
return {
|
||||
'page_title': "Allocation d'actifs",
|
||||
'message': message,
|
||||
'url': url,
|
||||
'page_title': "Home",
|
||||
'items': items,
|
||||
'member': member,
|
||||
'donut_cible': json.dumps(donut_cible),
|
||||
'donut_actuel': json.dumps(donut_actuel),
|
||||
'courbe_evoln': json.dumps(courbe_evoln),
|
||||
'actifs': actifs,
|
||||
'total_valeur': total_valeur,
|
||||
'total_pv': total_pv,
|
||||
'total_pc_value': total_pc_value,
|
||||
'total_rdt': total_rdt
|
||||
}
|
||||
|
||||
@view_config(route_name='doc_list', renderer='../templates/doc_list.pt', permission='view')
|
||||
def doc_list(request):
|
||||
|
||||
# lire toutes les docs
|
||||
docs_finance = get_docs_bytheme(request, 'FINANCE')
|
||||
docs_maison = get_docs_bytheme(request, 'MAISON')
|
||||
docs_voiture = get_docs_bytheme(request, 'VOITURE')
|
||||
memos = get_docs_bytheme(request, 'memo')
|
||||
docs = get_docs_bytheme(request, 'doc')
|
||||
|
||||
return {
|
||||
'page_title': "Documents",
|
||||
'docs_finance': docs_finance,
|
||||
'docs_maison': docs_maison,
|
||||
'docs_voiture': docs_voiture,
|
||||
'memos': memos,
|
||||
'docs': docs,
|
||||
}
|
||||
|
||||
@view_config(route_name='doc_edit', renderer='../templates/doc_edit.pt', permission='view')
|
||||
@@ -182,6 +96,8 @@ def doc_edit(request):
|
||||
url = request.route_url('doc_edit',doc_id=doc_id)
|
||||
|
||||
message = ""
|
||||
themes = get_blog_themes(request)
|
||||
|
||||
if doc_id == '0':
|
||||
titre = "Nouveau doc"
|
||||
intitule = ""
|
||||
@@ -222,7 +138,7 @@ def doc_edit(request):
|
||||
'intitule': intitule,
|
||||
'texte': texte,
|
||||
'theme': theme,
|
||||
'themes': ["MAISON","FINANCE","VOITURE"],
|
||||
'themes': themes,
|
||||
}
|
||||
|
||||
@view_config(route_name='doc_view', renderer='../templates/doc_view.pt', permission='view')
|
||||
|
||||
@@ -190,10 +190,7 @@ def logout(request):
|
||||
request.session.invalidate()
|
||||
headers = forget(request)
|
||||
request.session.flash(u"Vous avez bien été déconnecté.")
|
||||
return HTTPFound(location=request.route_url('login', login=''),
|
||||
headers=headers)
|
||||
|
||||
|
||||
return HTTPFound(location=request.route_url('home'), headers=headers)
|
||||
|
||||
|
||||
@view_config(route_name='user_edit', renderer='../templates/members/user_edit.pt', permission='manage')
|
||||
|
||||