remplacer devis-en-attente par derniers-suivis

This commit is contained in:
2021-08-18 11:17:40 +02:00
parent 8efd6589bc
commit 52b30b5660
13 changed files with 218 additions and 189 deletions

View File

@@ -130,26 +130,25 @@ def get_codespostaux(request, codep):
return results
def get_dd_restant(request):
query = """SELECT SUM(IF(societe='PE',1,0)) AS nb_PE,
SUM(IF(societe='ME',1,0)) AS nb_ME,
SUM(IF(societe='PL',1,0)) AS nb_PL
FROM dem_devis WHERE STATUS=0;"""
query = """SELECT (SELECT count(*) FROM dem_devis WHERE societe='PE' AND STATUS=0) AS nb_PE,
(SELECT count(*) FROM dem_devis WHERE societe='ME' AND STATUS=0) AS nb_ME,
(SELECT count(*) FROM dem_devis WHERE societe='PL' AND STATUS=0) AS nb_PL;"""
results = request.dbsession.execute(query).first()
return results
def get_de_restant(request):
query = """SELECT SUM(IF(societe='PE',1,0)) AS nb_PE,
SUM(IF(societe='ME',1,0)) AS nb_ME,
SUM(IF(societe='PL',1,0)) AS nb_PL
FROM devis WHERE STATUS<4;"""
# les suivis des attachés commerciaux dnas les 4 derniers jours
query = """SELECT
(SELECT count(*) FROM dem_lig WHERE societe='PE' AND DATEDIFF(CURDATE(), date) <= 7 AND usermaj in ('CG','MP','RV','VD')) AS nb_PE,
(SELECT count(*) FROM dem_lig WHERE societe='ME' AND DATEDIFF(CURDATE(), date) <= 7 AND usermaj in ('CG','MP','RV','VD')) AS nb_ME,
(SELECT count(*) FROM dem_lig WHERE societe='PL' AND DATEDIFF(CURDATE(), date) <= 7 AND usermaj in ('CG','MP','RV','VD')) AS nb_PL;"""
results = request.dbsession.execute(query).first()
return results
def get_fa_restant(request):
query = """SELECT SUM(IF(societe='PE',1,0)) AS nb_PE,
SUM(IF(societe='ME',1,0)) AS nb_ME,
SUM(IF(societe='PL',1,0)) AS nb_PL
FROM facture WHERE STATUS<8;"""
query = """SELECT (SELECT count(*) FROM facture WHERE societe='PE' AND STATUS < 8) AS nb_PE,
(SELECT count(*) FROM facture WHERE societe='ME' AND STATUS < 8) AS nb_ME,
(SELECT count(*) FROM facture WHERE societe='PL' AND STATUS < 8) AS nb_PL;"""
results = request.dbsession.execute(query).first()
return results

View File

@@ -235,8 +235,3 @@ def update_devis_cloture(request, nodevis, status, logged_in):
query = "UPDATE devis SET STATUS = :status, USERMAJ = :logged_in WHERE societe=:societe AND no_id=:nochantier;"
execute_query(request, query, {'societe': societe, 'nochantier': nochantier, 'status': status, 'logged_in': logged_in})
def get_devis_en_att(request, societe):
query = """SELECT d.date, LPAD(d.no_id,6,'0') AS numero, d.nomcli, CONCAT(d.c_nom,'; ',d.c_adr,'; ',d.c_ville) AS chantier, d.totalht AS montant, d.status, s.libelle, d.nosin, d.nopol, d.usermaj
FROM devis d JOIN p_statuts s ON d.STATUS = s.CODE WHERE d.societe=:societe AND d.STATUS < 4 ORDER BY d.societe, d.STATUS, d.nomcli;"""
results = request.dbsession.execute(query, {'societe': societe}).fetchall()
return results

View File

@@ -58,6 +58,12 @@ def get_clients_byName(request, societe, nom):
results = request.dbsession.execute(query).fetchall()
return results
def get_derniers_suivis(request):
query = """SELECT l.*, CONCAT(l.societe,'-',l.no_id) AS nodossier, d.C_NOM FROM dem_lig l
INNER JOIN dem_devis d ON l.societe=d.societe AND l.no_id=d.no_id
WHERE DATEDIFF(CURDATE(), l.date) <= 7 AND l.usermaj in ('CG','MP','RV','VD') ORDER BY l.date, l.societe DESC;"""
results = request.dbsession.execute(query, ).fetchall()
return results
def get_dossier_rdv_by_no(request,nodossier, nolig):
@@ -287,6 +293,16 @@ def update_rapport_client(request, norapport, nomClient, codeClient):
query = "UPDATE dem_rdf SET CD_CLI = :cd_cli, NOMCLI = :nomClient WHERE no_id = :norapport"
execute_query(request, query, {'norapport': norapport, 'cd_cli': cd_cli, 'nomClient': nomClient})
def update_rapport_nochantier(request, norapport, new_nochantier):
# controler que le no du nouveau dossier existe
dossier = get_dossier_by_no(request,'PL-' + new_nochantier)
if dossier:
query = "UPDATE dem_rdf SET nochantier = :new_nochantier WHERE no_id = :norapport"
execute_query(request, query, {'norapport': norapport, 'new_nochantier': new_nochantier})
return "OK"
else:
return "NOK"
def insert_facture_rdf(request, societe, nochantier, cd_cli, nomcli, user, ref, date_rapport):
# créer une facture vierge à partir du dossier
query = "CALL spINS_FACTURE_RDF(:societe, :nochantier, :cd_cli, :nomcli, :user, :ref, :date_rapport)"

View File

@@ -27,7 +27,6 @@ def includeme(config):
config.add_route('devis_web', '/devis_web/{nodevis}')
config.add_route('devis_view', '/devis_view/{nodevis}')
config.add_route('devis_preview', '/devis_preview/{nodevis}')
config.add_route('devis_en_att','/devis_en_att')
config.add_route('devis_select', '/devis_select/{date}')
config.add_route('devis_selected', '/devis_selected/{goto}/{date}/{nodevis}')
config.add_route('factures_en_att','/factures_en_att')
@@ -39,6 +38,7 @@ def includeme(config):
config.add_route('demandes_dl','/demandes_dl/{societe}/{email_from}/{email_uid}')
config.add_route('dem_devis','/dem_devis')
config.add_route('delete_img','/delete_img/{nodossier}/{norapport}/{origine}/{nomfic}')
config.add_route('dern_suivis','/dern_suivis')
config.add_route('dossier_edit', '/dossier_edit/{nodossier}')
config.add_route('dossier_lookup', '/dossier_lookup')
config.add_route('dossier_select', '/dossier_select/{date}')
@@ -50,6 +50,7 @@ def includeme(config):
config.add_route('rdf_client','/rdf_client/{no_id}')
config.add_route('rdf_edit','/rdf_edit/{nodossier}/{date_inter}')
config.add_route('rdf_list','/rdf_list')
config.add_route('rdf_nochantier','/rdf_nodossier/{no_id}')
config.add_route('rdf_rapport','/rdf_rapport/{no_id}')
config.add_route('rdf_view','/rdf_view/{no_id}')
config.add_route('rotate_img','/rotate_img/{nodossier}/{norapport}/{origine}/{nomfic}/{angle}')

View File

@@ -104,12 +104,12 @@
</a>
</div>
<div class="col-sm-3">
<a href="${request.application_url}/devis_en_att" tal:condition="access > 0">
<a href="${request.application_url}/dern_suivis" tal:condition="access > 0">
<div class="info-box bg-gest">
<span class="info-box-icon"><i class="glyphicon glyphicon-file"></i></span>
<div class="info-box-content">
<span class="info-box-number">DEVIS</span>
<span class="info-box-text">EN COURS </span>
<span class="info-box-number">CHANTIERS</span>
<span class="info-box-text">DERNIERS SUIVIS</span>
<span class="info-box-number"><span class="badge bg-PE">${nb_de_restants.nb_PE}</span>
<span class="badge bg-ME">${nb_de_restants.nb_ME}</span>
<span class="badge bg-PL">${nb_de_restants.nb_PL}</span></span>

View File

@@ -1,108 +0,0 @@
<metal:block use-macro="main_template">
<div metal:fill-slot="content">
<div class="row">
<form id="site-search-form" class="form-horizontal" role="form" action="${url}" method="post"
data-fv-framework="bootstrap"
data-fv-icon-valid="glyphicon glyphicon-ok"
data-fv-icon-invalid="glyphicon glyphicon-remove"
data-fv-icon-validating="glyphicon glyphicon-refresh">
<div class="form-group">
<label class="col-sm-4 control-label">Société</label>
<div class="col-xs-8">
<label class="radio-inline"><input type="radio" name="societe" value="PE"
tal:attributes="checked societe=='PE'">PE</label>
<label class="radio-inline"><input type="radio" name="societe" value="ME"
tal:attributes="checked societe=='ME'">ME</label>
<label class="radio-inline"><input type="radio" name="societe" value="PL"
tal:attributes="checked societe=='PL'">PL</label>
<label class="radio-inline"><input type="radio" name="societe" value="PO"
tal:attributes="checked societe=='PO'">PO</label>
<label class="radio-inline"><input type="radio" name="societe" value="CD"
tal:attributes="checked societe=='CD'">CD</label>
<button id="submitButton" class="btn btn-primary" type="submit" name="form.submitted">
<i class="glyphicon glyphicon-search"></i>&nbsp;Rechercher</button>
</div>
</div>
</form>
</div><!-- row -->
<br />
<div class="row">
<table id="dossiers_list" class="table table-bordered">
<thead>
<tr>
<th>Numéro</th>
<th>Date</th>
<th>Client</th>
<th>Chantier</th>
<th class="text-right">Montant</th>
<th>Sinistre</th>
<th class="text-center">Statut</th>
<th>Uti.</th>
</tr>
</thead>
</table>
</div>
<br />
<br />
<script type="text/javascript">
var dataSet = ${dt_data};
var goto_url = '${goto_url}';
var order_option = '${order_option}'
$(document).ready(function() {
$.fn.dataTable.moment('DD-MM-YYYY');
$('#dossiers_list').DataTable({
data: dataSet,
pageLength: 100,
bLengthChange: false,
language: {
url: 'https://cdn.datatables.net/plug-ins/1.10.16/i18n/French.json'
},
order: [[0, order_option]],
columnDefs: [
{ className: "text-right", "targets": [4] },
{ "targets": 0,
"render": function (data, type, full, meta) {
// ajouter un link vers le formulaire
return '<a href="' + goto_url + data + '">' + data + '</a>';
},
},
],
createdRow: function( row, data, dataIndex ){
if ( data[6] == "Humidité" ) {
$('td', row).eq(6).css('background-color', 'Crimson').css('color', 'white');
}
if ( data[6] == "Devis" || data[6] == "Commandé") {
$('td', row).eq(6).css('background-color', 'Orange');
}
if ( data[6] == "Facturé") {
$('td', row).eq(6).css('background-color', 'LightBlue');
}
if ( data[6] == "Réglée" || data[6] == "Régl part.") {
$('td', row).eq(6).css('background-color', 'LightGreen');
}
},
});
});
$('form input').on('keypress', function(e) {
var code = e.keyCode || e.which;
if (code === 13) {
e.preventDefault();
// simuler clic bouton submit
document.getElementById("submitButton").click();
}
});
</script>
</div><!-- content -->
</metal:block>

View File

@@ -0,0 +1,31 @@
<metal:block use-macro="main_template">
<div metal:fill-slot="content">
<br />
<div class="row">
<table class="table table-bordered table-condensed">
<tr>
<th>Date</th>
<th>Dossier</th>
<th>Action - commentaire</th>
<th class="text-center">Par</th>
</tr>
<tr tal:repeat="item items">
<td>${item.DATE.strftime('%d-%m-%Y')}</td>
<td>
<a href="${request.route_url('dossier_view', nodossier=item.nodossier)}">
${item.nodossier} - ${item.C_NOM}</a>
</td>
<td>${item.COMMENT}</td>
<td class="text-center">${item.USERMAJ}</td>
</tr>
</table>
</div>
<br />
<br />
</div><!-- content -->
</metal:block>

View File

@@ -65,6 +65,16 @@
data-fv-stringlength-message="20 caractères maximum" />
</div>
</div>
<div class="form-group">
<label class="col-xs-3 control-label">Observation</label>
<div class="col-xs-5">
<input class="form-control" type="text" name="C_OBS"
value="${dossier.C_OBS}" placeholder="40 caractères maximum"
data-fv-stringlength="true"
data-fv-stringlength-max="40"
data-fv-stringlength-message="40 caractères maximum" />
</div>
</div>
<h3 class="text-primary">EMAIL et TELEPHONES</h3>
<div class="form-group">

View File

@@ -26,15 +26,17 @@
<td>
Etage - Code<br />
Ascenseur<br />
Observation<br />
Téléphone 1 et 2<br />
Portable 1 et 2
Portable 1 et 2<br />
</td>
<td>
${dossier.C_ETAGE} - ${dossier.C_CODE}<br />
<span tal:condition="dossier.c_ascenseur==0">NON<br /></span>
<span tal:condition="dossier.c_ascenseur!=0">OUI<br /></span>
${dossier.C_OBS}<br />
${dossier.C_TEL1} - ${dossier.C_TEL2}<br />
${dossier.C_TELP} - ${dossier.C_FAX}
${dossier.C_TELP} - ${dossier.C_FAX} <br />
</td>
</tr>
<tr>
@@ -54,14 +56,12 @@
Police<br />
Sinistre<br />
Votre référence<br />
Observation<br />
Travaux<br />
</td>
<td>
${dossier.NOPOL}<br />
${dossier.NOSIN}<br />
${dossier.VREF}<br />
${dossier.C_OBS}<br />
${dossier.TX_TRAV}<br />
</td>
</tr>
@@ -97,12 +97,12 @@
</table>
</div>
<div class="col-md-6">
<h4>Statut : ${dossier.libelle}</h4>
<br />
<h4>
Statut : <span class="label label-warning">${dossier.libelle}</span>&nbsp;&nbsp;&nbsp;
[ <a href="#" data-toggle="modal" data-target="#confirmCloture">Modifier le statut</a> ]
</h4>
<p>Dernière modif. le <b>${dossier.DATEMAJ.strftime('%d/%m/%Y à %H:%M')}</b> par <b>${dossier.USERMAJ}</b></p>
<p>
<a class="btn btn-warning" role="button" href="#"
data-toggle="modal" data-target="#confirmCloture"><span class="glyphicon glyphicon-check"></span> Modif. statut dossier</a>
</p>
</div>
</div> <!-- row -->

View File

@@ -0,0 +1,79 @@
<metal:block use-macro="main_template">
<div metal:fill-slot="content">
<div tal:condition="message" tal:content="message" class="alert alert-danger" />
<br />
<div class="row">
<form id="rdf_nochantier-form" class="form-horizontal" action="${url}" method="post"
data-fv-framework="bootstrap"
data-fv-icon-valid="glyphicon glyphicon-ok"
data-fv-icon-invalid="glyphicon glyphicon-remove"
data-fv-icon-validating="glyphicon glyphicon-refresh">
<div class="form-group">
<label class="control-label col-sm-3">N° rapport</label>
<div class="col-sm-9">
<p class="form-control-static">${rapport.no_id}</p>
</div>
<label class="control-label col-sm-3">Date d'intervention</label>
<div class="col-sm-9">
<p class="form-control-static">${rapport.date_inter.strftime('%d-%m-%Y')}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">Nom du chantier actuel</label>
<div class="col-sm-9">
<p class="form-control-static text-danger">${rapport.C_QUALITE} ${rapport.C_NOM}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">No du chantier actuel</label>
<div class="col-sm-9">
<p class="form-control-static">${rapport.nochantier}</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Nouveau no de chantier</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="new_nochantier" name="new_nochantier"
placeholder="6 chiffres"
data-fv-numeric="true"
data-fv-numeric-message="Le numero de dossier est incorrect" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<a class="btn btn-default" href="${request.route_url('rdf_view', no_id=norapport)}">
<span class="glyphicon glyphicon-arrow-left"></span> Annuler</a>
<button class="btn btn-primary" type="submit" name="form.submitted">
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
</div>
</div>
</form>
</div> <!-- row -->
<br />
<br />
<br />
</div>
<div metal:fill-slot="additional_scripts">
<!-- autocomplete plugin -->
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(document).ready(function() {
$('#rdf_nochantier-form').formValidation({
framework: 'bootstrap',
excluded: ':disabled',
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
});
});
</script>
</div>
</metal:block>

View File

@@ -15,9 +15,13 @@
</div>
<div class="form-group">
<label class="control-label">N° dossier</label> : ${nodossier}<br />
<label class="control-label">N° rapport</label> : ${norapport}<br />
<label class="control-label">Date d'intervention</label> : ${rapport.date_inter.strftime('%d-%m-%Y')}<br />
<label class="control-label">N° dossier</label> : ${nodossier}<br />
<p tal:condition="pt_name != 'rdf_rapport'">
<a href="${request.route_url('rdf_nochantier', no_id=norapport)}"
tal:condition="access > 0">[ Changer le No dossier ]</a>
</p>
</div>
<h4 class="text-center text-primary">ADRESSE d'INTERVENTION</h4>

View File

@@ -401,49 +401,6 @@ def devis_lig_mv(request):
request.session.flash(u"La ligne de devis a été déplacée avec succès.", 'success')
return HTTPFound(location=request.route_url("devis_web", nodevis=nodevis))
@view_config(route_name='devis_en_att', renderer='../templates/devis/devis_en_att.pt', permission='view')
@view_config(route_name='devis_select', renderer='../templates/devis/devis_en_att.pt', permission='view')
def devis_en_att(request):
if 'devis_select' in request.current_route_path() :
# récupérer les paramètres de l'appel de la view
datePlan = request.matchdict['date']
# sélectionner devis -> goto planning
goto_url = '/devis_selected/agenda/%s/' % datePlan
url = request.route_url('devis_selected', date=datePlan)
else:
# recherche devis en att -> goto fiche devis
goto_url = '/devis_selected/devis_view/%s/' % date.today().strftime('%Y-%m-%d')
url = request.route_url('devis_en_att')
logged_in = request.authenticated_userid.upper()
url = request.route_url('devis_en_att')
member = get_member_by_id(request, logged_in)
societe_defaut = member.societe
societe = societe_defaut
access_defaut = member.access
liste=[]
if 'form.submitted' in request.params:
societe = request.params['societe']
list_devis_en_att = get_devis_en_att(request, societe)
for item in list_devis_en_att:
d = ('%s-DE%s' % (societe, item.numero),item.date.strftime('%d-%m-%Y'), item.nomcli, item.chantier, to_euro(item.montant),
item.nosin, item.libelle, item.usermaj)
liste.append(d)
order_option = 'desc'
return {
'page_title': "Devis en attente d'acceptation",
'url': url,
'goto_url': goto_url,
'dt_data': json.dumps(liste),
'societe': societe,
'order_option': order_option,
}
@view_config(route_name='devis_selected', permission='view')
def devis_selected(request):

View File

@@ -607,6 +607,45 @@ def rdf_client(request):
'rapport': rapport,
}
@view_config(route_name='rdf_nochantier', renderer='../templates/dossier/rdf_nochantier.pt', permission='view')
def rdf_nochantier(request):
logged_in = request.authenticated_userid.upper()
norapport = request.matchdict['no_id']
message = ''
# lire code accès du user
access = get_userAccess(request, logged_in)
if access == 0:
request.session.flash("Vous n'avez pas les droits nécessaires pour changer de client.", 'danger')
return HTTPFound(location=request.route_url('rdf_view', no_id=norapport))
url = request.route_url('rdf_nochantier', no_id=norapport)
# lire le rapport
rapport = get_rapport_by_no_id(request, norapport)
nodossier = 'PL-' + str(rapport.nochantier)
if 'form.submitted' in request.params:
new_nochantier = request.params['new_nochantier']
if len(new_nochantier) == 6:
retour = update_rapport_nochantier(request, norapport, new_nochantier)
if retour == "OK":
request.session.flash("Le numéro du dossier été modifié avec succès.", 'success')
return HTTPFound(location=request.route_url('rdf_view', no_id=norapport))
else:
message = "Le numéro du dossier n'existe pas : %s" % new_nochantier
else:
message = "Un numero de dossier doit avoir 6 chiffres"
return {
'page_title': "Changer le no du dossier du rapport n° %s" % norapport,
'url': url,
'message': message,
'access': access,
'norapport': norapport,
'rapport': rapport,
}
@view_config(route_name='rdf_view', renderer='../templates/dossier/rdf_view.pt', permission='view')
def rdf_view(request):
logged_in = request.authenticated_userid.upper()
@@ -1448,12 +1487,9 @@ def resize_photos(image_file):
img_org = Image.open(image_file)
# get the size of the original image
width_org, height_org = img_org.size
# set the resizing factor so the aspect ratio can be retained
# factor > 1.0 increases size
# factor < 1.0 decreases size
# set the max width
width = 1366
factor = (width/float(width_org))
height = int(height_org * factor)
height = int(height_org / width_org * width)
# best down-sizing filter
img_anti = img_org.resize((width, height), Image.ANTIALIAS)
# split image filename into name and extension
@@ -1602,7 +1638,7 @@ def note_edit(request):
url = request.route_url('note_edit', nodossier=nodossier, noligne=noligne)
message = ""
note = get_dem_notes(request, nodossier, noligne)
note = get_dem_notes(request, nodossier, noligne, 'NOTE')
if 'form.submitted' in request.params:
notes = request.params["notes"]
@@ -1631,3 +1667,12 @@ def croquis_edit(request):
'page_title': 'NOUVEAU CROQUIS',
}
@view_config(route_name='dern_suivis', renderer='../templates/dossier/dern_suivis.pt', permission='view')
def dern_suivis(request):
# lire les derniers suivis créés par les attachés de clientèle
items = get_derniers_suivis(request)
return {
'page_title': 'Derniers suivis créés',
'items': items,
}