fusion devis et facture dans un chantier

This commit is contained in:
2024-03-25 10:57:22 +01:00
parent 58371d3b84
commit 86889f33ce
9 changed files with 179 additions and 115 deletions

View File

@@ -2,11 +2,17 @@ Metadata-Version: 2.1
Name: mondumas Name: mondumas
Version: 1.0 Version: 1.0
Summary: mondumas Summary: mondumas
Home-page: UNKNOWN Home-page:
Author: Author:
Author-email: Author-email:
License: UNKNOWN Keywords: web wsgi bfg pylons pyramid
Description: # README # Classifier: Programming Language :: Python
Classifier: Framework :: Pyramid
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Provides-Extra: testing
# README #
Cette application web permet aux collaborateurs de l'entreprise Dumas : Cette application web permet aux collaborateurs de l'entreprise Dumas :
@@ -48,11 +54,3 @@ Description: # README #
--- ---
- Initial version - Initial version
Keywords: web wsgi bfg pylons pyramid
Platform: UNKNOWN
Classifier: Programming Language :: Python
Classifier: Framework :: Pyramid
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Provides-Extra: testing

View File

@@ -1,4 +1,2 @@
[paste.app_factory] [paste.app_factory]
main = mondumas:main main = mondumas:main
[console_scripts]

View File

@@ -8,7 +8,7 @@ SQLAlchemy==1.2.19
transaction transaction
zope.sqlalchemy==1.1 zope.sqlalchemy==1.1
waitress waitress
mysqlclient==2.1 mysqlclient==1.4
docutils docutils
pdfkit pdfkit
python-dateutil python-dateutil

View File

@@ -25,19 +25,23 @@ def execute_query(request, query, params):
mark_changed(request.dbsession) mark_changed(request.dbsession)
transaction.commit() transaction.commit()
def get_devis_byName(request, societe, name):
numero = to_int(name)
if numero > 0: def get_dossiers_byName(request, societe, name):
query = """SELECT date,'DE' AS TYPE, LPAD(no_id,6,'0') AS numero, nomcli, CONCAT(c_nom,'; ',c_adr,'; ',c_ville) AS chantier, COALESCE(totalht,0) AS montant, status, nosin, nopol, nochantier, web # lires tous les dossiers d'un chantier
FROM devis WHERE societe=:societe AND no_id >=:name AND web = 'W' LIMIT 300;;""" % (societe, name)
elif len(name) == 0: query = """select * from (
query = """SELECT date,'DE' AS TYPE, LPAD(no_id,6,'0') AS numero, nomcli, CONCAT(c_nom,'; ',c_adr,'; ',c_ville) AS chantier, COALESCE(totalht,0) AS montant, status, nosin, nopol, nochantier, web SELECT date,'DD' AS TYPE, LPAD(no_id,6,'0') AS numero, nomcli, CONCAT(c_nom,'; ',c_adr,'; ',c_ville) AS chantier, 0 AS montant, status, nosin, societe , no_id as nochantier
FROM devis WHERE societe=:societe AND web = 'W' ORDER BY no_id DESC LIMIT 300;""" FROM dem_devis WHERE societe=:societe AND c_nom LIKE :name
else: UNION
query = """(SELECT date,'DE' AS TYPE, LPAD(no_id,6,'0') AS numero, nomcli, CONCAT(c_nom,'; ',c_adr,'; ',c_ville) AS chantier, COALESCE(totalht,0) AS montant, status, nosin, nopol , nochantier, web SELECT date,'DE' AS TYPE, LPAD(no_id,6,'0') AS numero, nomcli, CONCAT(c_nom,'; ',c_adr,'; ',c_ville) AS chantier, COALESCE(totalht,0) AS montant, status, nosin, societe , nochantier
FROM devis WHERE societe=:societe AND c_nom LIKE ':name%' AND web = 'W' LIMIT 500)""" FROM devis WHERE societe=:societe AND c_nom LIKE :name
results = request.dbsession.execute(query, {'societe': societe, 'name': name}).fetchall() UNION
SELECT date,'FA' AS TYPE, LPAD(no_id,6,'0') AS numero, nomcli, CONCAT(c_nom,'; ',c_adr,'; ',c_ville) AS chantier, COALESCE(totalht,0) AS montant, status, nosin, societe , nochantier
FROM facture WHERE societe=:societe AND c_nom LIKE :name
) a
order by date, TYPE
"""
results = request.dbsession.execute(query, {'societe': societe, 'name': name+'%'}).fetchall()
return results return results
def get_devfac_by_no(request,nodossier): def get_devfac_by_no(request,nodossier):
@@ -235,3 +239,14 @@ 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;" 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}) execute_query(request, query, {'societe': societe, 'nochantier': nochantier, 'status': status, 'logged_in': logged_in})
def update_devis_nochantier(request, societe, no_devis, nochantier):
# extraire type de doc et no de doc à mettre à jour
type = no_devis[0:2]
no_id = no_devis[3:]
if type == 'DE':
# maj le numero du dossier du devis
query = "UPDATE devis SET nochantier = :nochantier WHERE societe=:societe AND no_id=:no_id;"
else:
# maj le numero du dossier de la facture
query = "UPDATE facture SET nochantier = :nochantier WHERE societe=:societe AND no_id=:no_id;"
execute_query(request, query, {'societe': societe, 'nochantier': nochantier, 'no_id': no_id})

View File

@@ -22,8 +22,9 @@ def includeme(config):
# devis # devis
config.add_route('devis_ligne', '/devis_ligne/{type_ligne}/{nodevis}/{nolig}') config.add_route('devis_ligne', '/devis_ligne/{type_ligne}/{nodevis}/{nolig}')
config.add_route('devis_lig_mv', '/devis_lig_mv/{move}/{nodevis}/{nolig}') config.add_route('devis_lig_mv', '/devis_lig_mv/{move}/{nodevis}/{nolig}')
config.add_route('devis_list', '/devis_list') config.add_route('devis_list', '/devis_list/{societe}/{nodevis}')
config.add_route('devis_create', '/devis_create/{nodossier}') config.add_route('devis_create', '/devis_create/{nodossier}')
config.add_route('devis_nochantier', '/devis_nochantier/{societe}/{nodevis}/{nochantier}')
config.add_route('devis_web', '/devis_web/{nodevis}') config.add_route('devis_web', '/devis_web/{nodevis}')
config.add_route('devis_view', '/devis_view/{nodevis}') config.add_route('devis_view', '/devis_view/{nodevis}')
config.add_route('devis_preview', '/devis_preview/{nodevis}') config.add_route('devis_preview', '/devis_preview/{nodevis}')

View File

@@ -133,11 +133,11 @@
</a> </a>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-4">
<a href="${request.application_url}/devis_list" tal:condition="logged_in == 'CAO'"> <a href="${request.application_url}/devis_list/PE/0" tal:condition="logged_in == 'CAO'">
<div class="info-box bg-prod"> <div class="info-box bg-prod">
<span class="info-box-icon"><i class="glyphicon glyphicon-text-height"></i></span> <span class="info-box-icon"><i class="glyphicon glyphicon-search"></i></span>
<div class="info-box-content"> <div class="info-box-content">
<span class="info-box-number">E-DEVIS</span> <span class="info-box-number">RECHERCHE DEVIS</span>
</div> </div>
</div> </div>
</a> </a>

View File

@@ -27,10 +27,9 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">Nom ou numéro du chantier</label> <label class="col-sm-4 control-label">Numéro du devis</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input type="text" class="form-control" name="name" value="${name}" <input type="text" class="form-control" name="nodevis" value="${nodevis}" >
placeholder="Le nom ou le numéro doit avoir de 2 à 30 caractères de long" >
</div> </div>
</div> </div>
@@ -53,19 +52,20 @@
<th>Client</th> <th>Client</th>
<th>Chantier</th> <th>Chantier</th>
<th class="text-right">Montant</th> <th class="text-right">Montant</th>
<th>Sinistre</th> <th>No chantier</th>
<th class="text-center">Statut</th> <th class="text-center">Action</th>
</tr> </tr>
<tr tal:repeat="detail devis"> <tr tal:repeat="detail dossiers">
<td> <td>${detail.TYPE}-${detail.numero}</td>
<a href="/devis_web/${societe}-DE${detail.numero}">${societe}-${detail.numero}-W</a>
</td>
<td>${detail.date.strftime('%d-%m-%Y')}</td> <td>${detail.date.strftime('%d-%m-%Y')}</td>
<td>${detail.nomcli}</td> <td>${detail.nomcli}</td>
<td>${detail.chantier}</td> <td>${detail.chantier}</td>
<td class="text-right">${layout.to_euro(detail.montant)}</td> <td class="text-right">${layout.to_euro(detail.montant)}</td>
<td>${detail.nosin}</td> <td>${detail.nochantier}</td>
<td class="text-center">${detail.status}</td> <td class="text-center">
<a tal:condition="detail.nochantier == 0" id="modalButton" href="#confirmCreate"
data-toggle="modal" data-societe="${detail.societe}" data-nodevis="${detail.TYPE}-${detail.numero}">Joindre</a>
</td>
</tr> </tr>
</thead> </thead>
@@ -74,26 +74,53 @@
<br /> <br />
</div> </div>
<script type="text/javascript"> <!-- Modal : Confirmation CREATION -->
$(document).ready(function() { <div class="modal fade" id="confirmCreate" role="dialog" aria-labelledby="confirmCreateLabel" aria-hidden="true">
$('#devis-search-form').formValidation({ <div class="modal-dialog">
framework: 'bootstrap', <div class="modal-content">
message: 'This value is not valid', <div class="modal-header">
icon: { <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
valid: 'glyphicon glyphicon-ok', <h4 class="modal-title">Ajouter le nochantier dans le </h4>
invalid: 'glyphicon glyphicon-remove', </div>
validating: 'glyphicon glyphicon-refresh' <div class="modal-body">
}, <!-- The form is placed inside the body of modal -->
}); <form id="add_justif-form" class="form-horizontal" action="${url}" method="post">
$('form input').on('keypress', function(e) { <div class="form-group">
var code = e.keyCode || e.which; <label class="control-label col-xs-4">Document No:</label>
if (code === 13) { <div class="col-xs-8">
e.preventDefault(); <input type="text" name="md_nodevis" id="md_nodevis" value="" readonly/>
// simuler clic bouton submit </div>
document.getElementById("submitButton").click(); </div>
} <div class="form-group">
}); <label class="control-label col-xs-4">Chantier No :</label>
<div class="col-xs-8">
<input type="text" name="md_nochantier" id="md_nochantier" value=""/>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-4">Société:</label>
<div class="col-xs-8">
<input type="text" name="md_societe" id="md_societe" value="" readonly/>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
<button type="submit" class="btn btn-success" name="form.joined">Ajouter</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$('#confirmCreate').on('show.bs.modal', function(e) {
var societe = $(e.relatedTarget).data('societe');
var nodevis = $(e.relatedTarget).data('nodevis');
$(e.currentTarget).find('input[name="md_societe"]').val(societe);
$(e.currentTarget).find('input[name="md_nodevis"]').val(nodevis);
});
</script> </script>
</div> </div>

View File

@@ -21,35 +21,49 @@ from ..models.devis import *
@view_config(route_name='devis_list', renderer='../templates/devis/devis_list.pt', permission='view') @view_config(route_name='devis_list', renderer='../templates/devis/devis_list.pt', permission='view')
def devis_list(request): def devis_list(request):
societe = request.matchdict['societe']
nodevis = request.matchdict['nodevis']
try:
int(nodevis)
except:
message = "Numero de Devis incorrect : %s" % societe + '-' + nodevis
url = request.route_url('devis_list')
logged_in = request.authenticated_userid.upper()
message = '' message = ''
member = get_member_by_id(request, logged_in) dossiers=None
societe_defaut = member.societe
societe = societe_defaut
access_defaut = member.access
liste=[]
name = ''
cb_tous = "non"
if 'form.submitted' in request.params: if 'form.submitted' in request.params:
name = request.params['name']
societe = request.params['societe'] societe = request.params['societe']
nodevis = request.params['nodevis']
if 'form.joined' in request.params:
md_nochantier = request.params['md_nochantier']
md_nodevis = request.params['md_nodevis']
md_societe = request.params['md_societe']
# modifier un devis à partir d'un dossier
update_devis_nochantier(request, md_societe, md_nodevis, md_nochantier)
message = "Le devis %s a été modifié avec succès : " % md_nodevis
url = request.route_url('devis_list', societe=societe, nodevis=nodevis)
if nodevis != '0':
# lire le devis
devis = get_devis_by_no(request, societe + '-DE' + nodevis)
if devis == None:
message = "Devis non trouvé : %s" % societe + '-' + nodevis
else:
# lire tous les dossiers du chantiers
dossiers = get_dossiers_byName(request, societe, devis.C_NOM)
# lire les devis
devis = get_devis_byName(request, societe, name)
if len(devis) == 0:
message = "Devis non trouvé : %s" % name
return { return {
'page_title': "Rechercher un devis", 'page_title': "Rechercher un devis",
'url': url, 'url': url,
'message': message, 'message': message,
'devis': devis, 'dossiers': dossiers,
'societe': societe, 'societe': societe,
'name': name, 'nodevis': nodevis,
} }
@view_config(route_name='devis_create', permission='view') @view_config(route_name='devis_create', permission='view')
@@ -64,6 +78,17 @@ def devis_create(request):
request.session.flash(u"Le devis %s a été créé avec succès" % no_devis.last_insert_id, 'success') request.session.flash(u"Le devis %s a été créé avec succès" % no_devis.last_insert_id, 'success')
return HTTPFound(location=request.route_url("dossier_view", nodossier=nodossier) + '#tab_documents') return HTTPFound(location=request.route_url("dossier_view", nodossier=nodossier) + '#tab_documents')
@view_config(route_name='devis_nochantier', permission='view')
def devis_nochantier(request):
societe = request.matchdict['societe']
nodevis = request.matchdict['nodevis']
nochantier = request.matchdict['nochantier']
# modifier un devis à partir d'un dossier
update_devis_nochantier(request, societe, nodevis, nochantier)
request.session.flash(u"Le devis %s a été modifié avec succès : " + nodevis, 'success')
return HTTPFound(location=request.route_url("devis_list", societe=societe, nodevis=nodevis))
@view_config(route_name='devis_view', renderer='../templates/devis/devis_view.pt', permission='view') @view_config(route_name='devis_view', renderer='../templates/devis/devis_view.pt', permission='view')

View File

@@ -19,7 +19,7 @@ requires = [
'transaction', 'transaction',
'zope.sqlalchemy == 1.1', 'zope.sqlalchemy == 1.1',
'waitress', 'waitress',
'mysqlclient == 2.1', 'mysqlclient == 1.4',
'docutils', 'docutils',
'pdfkit', 'pdfkit',
'python-dateutil', 'python-dateutil',