déplacer les templates actif dans un module à part

This commit is contained in:
2017-07-24 09:53:05 +02:00
parent 988bb87263
commit a2c5ac2cfe
11 changed files with 303 additions and 152 deletions

View File

@@ -0,0 +1,57 @@
# -*- coding: utf8 -*-
from sqlalchemy import text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (
scoped_session,
sessionmaker,
)
from zope.sqlalchemy import ZopeTransactionExtension, mark_changed
from datetime import *
import transaction
from .default import (
execute_query,
)
def get_actifs(request, no_id):
if no_id == '0':
query = "SELECT * FROM actifs ORDER BY symbole"
results = request.dbsession.execute(query).fetchall()
else:
# lire le actif par son identifiant
query = """SELECT * FROM actifs WHERE no_id=:no_id;"""
results = request.dbsession.execute(query, {'no_id': no_id}).first()
return results
def update_actif(request, no_id, new_values):
# formater les champs
s = ''
for param in new_values.keys():
if param == 'symbole':
new_values['symbole'] = new_values['symbole'].upper()
if s:
s += ",%s=:%s" % (param, param)
else:
s = "%s=:%s" % (param, param)
if no_id == '0':
query = "INSERT INTO actifs SET %s" % s
else:
new_values['no_id'] = no_id
query = "UPDATE actifs SET %s WHERE no_id = :no_id;" % s
execute_query(request, query, new_values)
def update_actif_devise(request, devise, taux):
query = "UPDATE actifs SET parite = :taux WHERE devise = :devise;"
execute_query(request, query, {'taux': taux, 'devise': devise})
def update_actif_valeur(request, symbole, cours):
query = "UPDATE actifs SET cours = :cours WHERE symbole = :symbole;"
execute_query(request, query, {'symbole': symbole, 'cours': cours})
def delete_actif(request, no_id):
query = "DELETE FROM actifs WHERE no_id = :no_id ;"
execute_query(request, query, {'no_id': no_id})

View File

@@ -44,16 +44,6 @@ def delete_doc(request, doc_id):
query = "delete from docs where doc_id = :doc_id;" query = "delete from docs where doc_id = :doc_id;"
results = request.dbsession.execute(query, {'doc_id': doc_id}) results = request.dbsession.execute(query, {'doc_id': doc_id})
def get_actifs(request, no_id):
if no_id == '0':
query = "SELECT * FROM actifs ORDER BY symbole"
results = request.dbsession.execute(query).fetchall()
else:
# lire le actif par son identifiant
query = """SELECT * FROM actifs WHERE no_id=:no_id;"""
results = request.dbsession.execute(query, {'no_id': no_id}).first()
return results
def get_categories(request, cat_id): def get_categories(request, cat_id):
if cat_id == '0': if cat_id == '0':
query = "SELECT * FROM categories ORDER BY categorie" query = "SELECT * FROM categories ORDER BY categorie"
@@ -64,25 +54,3 @@ def get_categories(request, cat_id):
results = request.dbsession.execute(query, {'cat_id': cat_id}).first() results = request.dbsession.execute(query, {'cat_id': cat_id}).first()
return results return results
def update_actif(request, no_id, new_values):
# formater les champs
s = ''
for param in new_values.keys():
if param == 'symbole':
new_values['symbole'] = new_values['symbole'].upper()
if s:
s += ",%s=:%s" % (param, param)
else:
s = "%s=:%s" % (param, param)
if no_id == '0':
query = "INSERT INTO actifs SET %s" % s
else:
new_values['no_id'] = no_id
query = "UPDATE actifs SET %s WHERE no_id = :no_id;" % s
execute_query(request, query, new_values)
def delete_actif(request, no_id):
query = "DELETE FROM actifs WHERE no_id = :no_id ;"
execute_query(request, query, {'no_id': no_id})

View File

@@ -4,6 +4,8 @@ def includeme(config):
config.add_route('doc_edit', '/doc_edit/{doc_id}') config.add_route('doc_edit', '/doc_edit/{doc_id}')
config.add_route('doc_list', '/doc_list') config.add_route('doc_list', '/doc_list')
config.add_route('doc_view', '/doc_view/{doc_id}') config.add_route('doc_view', '/doc_view/{doc_id}')
# actifs
config.add_route('actifs_list', '/actifs_list')
config.add_route('actif_edit', '/actif_edit/{no_id}') config.add_route('actif_edit', '/actif_edit/{no_id}')
# members # members
config.add_route('changer_mdp', '/changer_mdp') config.add_route('changer_mdp', '/changer_mdp')

View File

@@ -54,6 +54,10 @@
} }
} }
#doc-text {
font-family: Monaco, "Courier New", Courier, monospace;
}
#bg { #bg {
position: fixed; position: fixed;
top: 0; top: 0;

View File

@@ -55,7 +55,8 @@
<div class="form-group"> <div class="form-group">
<div class="col-xs-offset-2 col-xs-10"> <div class="col-xs-offset-2 col-xs-10">
<div class="form-group"> <div class="form-group">
<a class="btn btn-default" href="${request.application_url}/home"><span class="glyphicon glyphicon-chevron-left"></span> Retour</a> <a class="btn btn-default" href="${request.application_url}/actifs_list">
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
<button class="btn btn-primary" type="submit" name="form.submitted"> <button class="btn btn-primary" type="submit" name="form.submitted">
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button> <span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
<button class="btn btn-warning" type="submit" name="form.deleted" <button class="btn btn-warning" type="submit" name="form.deleted"

View File

@@ -0,0 +1,84 @@
<metal:block use-macro="main_template">
<div metal:fill-slot="content">
<div tal:condition="message" tal:content="message" class="alert alert-danger" />
<form id="actif_list-form" action="${request.application_url}" method="post">
<div class="form-group">
<div class="form-group">
<button class="btn btn-primary" type="submit" name="form.submitted">
<span class="glyphicon glyphicon-refresh"></span> MAJ du portefueille</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-striped table-bordered">
<thead>
<tr>
<th>Catégorie</th>
<th>Symbole</th>
<th>Libellé</th>
<th>Nombre</th>
<th>Cours</th>
<th>PRU</th>
<th>Valeur</th>
<th>Plus-Value</th>
<th>No</th>
</tr>
</thead>
</table>
<br />
<br />
<!-- 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">
var dataSet = ${dt_data};
$(document).ready(function() {
$.fn.dataTable.moment('DD/MM/YYYY - HH:mm');
$('#actifs_list').DataTable({
data: dataSet,
pageLength: 50,
bLengthChange: false,
columnDefs: [
{ className: "text-right", "targets": [3,4,5,6,7] },
{ "targets": 8,
"render": function (data, type, full, meta) {
// ajouter un link vers le formulaire
return '<a class="btn btn-primary btn-sm" role="button" href="/actif_edit/' + data +
'"><span class="glyphicon glyphicon-pencil"></span> </a>';
},
},
]
});
});
</script>
</div><!-- content -->
</metal:block>

View File

@@ -1,52 +1,7 @@
<metal:block use-macro="main_template"> <metal:block use-macro="main_template">
<div metal:fill-slot="content"> <div metal:fill-slot="content">
<p> <div tal:condition="message" tal:content="message" class="alert alert-danger" />
<a href="${request.application_url}/actif_edit/0" class="btn btn-success" role="button">
<span class="glyphicon glyphicon-plus"></span> Nouvel actif</a>
</p>
<table id="actifs_list" class="table table-striped table-bordered">
<thead>
<tr>
<th>No</th>
<th>Symbole</th>
<th>Libellé</th>
<th>Catégorie</th>
<th>Nombre</th>
<th>Cours</th>
<th>PRU</th>
<th>Valeur</th>
<th>Plus-Value</th>
</tr>
</thead>
</table>
<br />
<br />
<script type="text/javascript">
var dataSet = ${dt_data};
$(document).ready(function() {
$.fn.dataTable.moment('DD/MM/YYYY - HH:mm');
$('#actifs_list').DataTable({
data: dataSet,
pageLength: 50,
bLengthChange: false,
columnDefs: [
{ className: "text-right", "targets": [4,5,6,7,8] },
{ "targets": 0,
"render": function (data, type, full, meta) {
// ajouter un link vers le formulaire
return '<a href="/actif_edit/' + data + '">' + data + '</a>';
},
},
]
});
});
</script>
</div><!-- content --> </div><!-- content -->
</metal:block> </metal:block>

View File

@@ -50,12 +50,12 @@
</button> </button>
<a href="${request.application_url}" alt="Accueil"> <a href="${request.application_url}" alt="Accueil">
<img src="${request.static_url('caotek_mesavoirs:static/img/logo.png')}" class="logo" /></a> <img src="${request.static_url('caotek_mesavoirs:static/img/logo.png')}" class="logo" /></a>
&nbsp;MES AVOIRS &nbsp;MON PORTEFEUILLE
</div> </div>
<div class="collapse navbar-collapse" id="myNavbar" tal:condition="not layout.isAnonymous()"> <div class="collapse navbar-collapse" id="myNavbar" tal:condition="not layout.isAnonymous()">
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="${request.application_url}">ACTIFS</a></li> <li><a href="${request.application_url}/actifs_list">ACTIFS</a></li>
<li><a href="${request.application_url}/allocation">ALLOCATION</a></li> <li><a href="${request.application_url}/allocations">ALLOCATION</a></li>
<li><a href="${request.application_url}/doc_list">DOCS</a></li> <li><a href="${request.application_url}/doc_list">DOCS</a></li>
${panel('dropdown_menu_panel')} ${panel('dropdown_menu_panel')}
</ul> </ul>

View File

@@ -0,0 +1,137 @@
# -*- coding: utf8 -*-
from pyramid.response import Response
from pyramid.renderers import render, get_renderer
from pyramid.view import (
view_config,
forbidden_view_config,
)
from pyramid.security import (
authenticated_userid,
remember,
forget,
)
from pyramid.httpexceptions import (
HTTPFound,
HTTPNotFound,
HTTPForbidden,
)
from pyramid_mailer import get_mailer
from pyramid_mailer.message import Message, Attachment
from datetime import *
import hashlib
from yahoo_finance import Share, Currency
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,
)
from ..views.default import (
to_euro,
to_usd,
)
import json
@view_config(route_name='actifs_list', renderer='../templates/actifs/actifs_list.pt', permission='view')
def actifs_list(request):
message = ''
# lire les actifs
items = get_actifs(request, '0')
# MAJ du prtefeuille
if 'form.submitted' in request.params:
# maj des parités des devises d'après Yahoo finance
usdeur = Currency('USDEUR')
update_actif_devise(request, 'USD', usdeur.get_rate())
for item in items:
sym = Share(item.symbole)
update_actif_valeur(request, item.symbole, sym.get_price())
# relire les actifs
items = get_actifs(request, '0')
message = u'Le portefeuille est mis à jour avec succès.'
# construire la liste
liste=[]
for item in items:
if item.devise == 'EUR':
cours = to_euro(item.cours)
else:
cours = to_usd(item.cours)
d = (item.categorie, item.symbole, item.libelle, str(item.nombre), cours, to_euro(item.pru), to_euro(item.valeur), to_euro(item.plus_value),str(item.no_id))
liste.append(d)
return {
'page_title': u"Mes actifs",
'dt_data': json.dumps(liste),
'message': message,
}
@view_config(route_name='actif_edit', renderer='../templates/actifs/actif_edit.pt', permission='view')
def actif_edit(request):
no_id = request.matchdict['no_id']
url = request.route_url('actif_edit', no_id=no_id)
message = ''
categories_list = get_categories(request,'0')
if no_id == '0':
# nouveau
actif = {}
actif['no_id'] = '0'
actif['symbole'] = ''
actif['categorie'] = 'Actions Europe'
actif['nombre'] = '0'
actif['pru'] = '0'
page_title= 'Nouvel actif'
else:
# lire la fiche du actif
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'))
page_title= u"Actif : %s" % (actif.symbole)
if 'form.submitted' in request.params:
new_values = {}
for param, db_value in actif.items():
if param in request.params and request.params[param] != db_value:
new_values[param] = request.params[param]
if new_values:
# récupérer les infos du symbole de Yahoo finance
if 'symbole' in request.params:
symbole = request.params['symbole']
else:
symbole = actif.symbole
sym = Share(symbole)
if sym.get_name() <> None:
# import pdb;pdb.set_trace()
new_values['libelle'] = sym.get_name()
new_values['cours'] = sym.get_price()
new_values['devise'] = sym.get_currency()
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'))
else:
message = 'Symbole inconnu. Veuillez ressaisir.'
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 {
'page_title': page_title,
'url': url,
'actif': actif,
'categories_list': categories_list,
'message': message,
}

View File

@@ -20,7 +20,7 @@ from pyramid_mailer.message import Message, Attachment
from datetime import * from datetime import *
import hashlib import hashlib
from docutils.core import publish_parts from docutils.core import publish_parts
from yahoo_finance import Share from yahoo_finance import Share, Currency
from sqlalchemy.exc import DBAPIError from sqlalchemy.exc import DBAPIError
from ..security import groupfinder from ..security import groupfinder
@@ -43,6 +43,14 @@ def to_euro(x):
#else: #else:
return (u"%.2f" % x).replace('.', ',') return (u"%.2f" % x).replace('.', ',')
def to_usd(x):
"""Takes a float and returns a string"""
#if x == 0:
# return ""
#else:
return (u"%.2f $" % x).replace('.', ',')
def to_int(x): def to_int(x):
try: try:
number = int(x.replace(',', '.')) number = int(x.replace(',', '.'))
@@ -57,25 +65,17 @@ def to_percent(x):
@view_config(route_name='home', renderer='../templates/home.pt', permission='view') @view_config(route_name='home', renderer='../templates/home.pt', permission='view')
def home(request): def home(request):
message = ''
logged_in = authenticated_userid(request) logged_in = authenticated_userid(request)
# lire la fiche du membre # lire la fiche du membre
membre = get_member_by_email(request, logged_in) membre = get_member_by_email(request, logged_in)
if not membre: if not membre:
request.session.flash(u"Utilisateur non trouvé : %s" % logged_in, 'warning') request.session.flash(u"Utilisateur non trouvé : %s" % logged_in, 'warning')
return HTTPFound(location=request.route_url('/home')) return HTTPFound(location=request.route_url('/'))
# lire les actifs
items = get_actifs(request, '0')
# construire la liste
liste=[]
for item in items:
d = (str(item.no_id), item.symbole, item.libelle, item.categorie, str(item.nombre), to_euro(item.cours), to_euro(item.pru), to_euro(item.valeur), to_euro(item.plus_value))
liste.append(d)
return { return {
'page_title': u"%s %s" % (membre.prenom, membre.nom), 'page_title': u"%s %s" % (membre.prenom, membre.nom),
'dt_data': json.dumps(liste), 'message': message,
} }
@view_config(route_name='doc_list', renderer='../templates/doc_list.pt', permission='view') @view_config(route_name='doc_list', renderer='../templates/doc_list.pt', permission='view')
@@ -171,60 +171,3 @@ gestion.entreprise-dumas.com
mailer = get_mailer(request) mailer = get_mailer(request)
mailer.send_immediately(message) mailer.send_immediately(message)
@view_config(route_name='actif_edit', renderer='../templates/actif_edit.pt', permission='view')
def actif_edit(request):
no_id = request.matchdict['no_id']
url = request.route_url('actif_edit', no_id=no_id)
message = ''
categories_list = get_categories(request,'0')
if no_id == '0':
# nouveau
actif = {}
actif['no_id'] = '0'
actif['symbole'] = ''
actif['categorie'] = 'Actions Europe'
actif['nombre'] = '0'
actif['pru'] = '0'
page_title= 'Nouvel actif'
else:
# lire la fiche du actif
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'))
page_title= u"Fiche de %s" % (actif.symbole)
if 'form.submitted' in request.params:
new_values = {}
for param, db_value in actif.items():
if param in request.params and request.params[param] != db_value:
new_values[param] = request.params[param]
if new_values:
# récupérer les infos du symbole de Yahoo finance
if 'symbole' in request.params:
symbole = request.params['symbole']
else:
symbole = actif.symbole
sym = Share(symbole)
new_values['libelle'] = sym.get_name()
new_values['cours'] = sym.get_price()
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'))
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 {
'page_title': page_title,
'url': url,
'actif': actif,
'categories_list': categories_list,
'message': message,
}

View File

@@ -213,7 +213,7 @@ def user_edit(request):
if not membre: if not membre:
request.session.flash(u"Utilisateur non trouvé : %s" % email, 'warning') request.session.flash(u"Utilisateur non trouvé : %s" % email, 'warning')
return HTTPFound(location=request.route_url('users_list')) return HTTPFound(location=request.route_url('users_list'))
page_title= u"Fiche de %s" %(membre.nom) page_title= u"Membre : %s" %(membre.nom)
if 'form.submitted' in request.params: if 'form.submitted' in request.params:
new_values = {} new_values = {}