Hai ragione… per oggetti intendevo in maniera grossolana un campo data con possibilità di apertura calendario….
Giro i due codici così da rendere tutto più chiaro…
File APP.PY
from flask import Flask, render_template, request
import pyodbc, calendar, datetime, locale
from datetime import date, datetime, timedelta
from gevent.pywsgi import WSGIServer
app = Flask(__name__,template_folder='c:\\sito\\templates' )
f = open("AHR.TXT", "r")#leggo parametri da file
IP_APP=f.readline()[:-1]
@app.route('/',methods=['GET', 'POST'])
def index(result=None):
Variabile_DA= request.args.get('DA',None)
Variabile_A= request.args.get('A',None)
#calcola GIORNO, MESE ED ANNO CORRENTE
MESENOW=(datetime.now()- timedelta(days=60)).strftime('%m')
ANNONOW=(datetime.now()- timedelta(days=60)).strftime('%Y')
GIORNONOW=(datetime.now()-timedelta(days=60)).strftime('%d')
if not Variabile_DA:
Variabile_DA="{d '"+ANNONOW +"-" + MESENOW+ "-01'}"
Variabile_A="{d '"+ANNONOW +"-" + MESENOW+ "-" + GIORNONOW +"'}"
else:
Variabile_DA="{d '" + Variabile_DA + "'}"
Variabile_A="{d '" + Variabile_A + "'}"
f = open("AHR.TXT", "r")#leggo parametri da file
IP_APP=f.readline()[:-1]
SERVERSQL=f.readline()[:-1]
DATABASESQL=f.readline()[:-1]
USER=f.readline()[:-1]
PASSWORD=f.readline()[:-1]
AZIENDA=f.readline()#su ultima riga non cancello carattere di ritorno a capo
f.close()
connection_string = "DRIVER={ODBC Driver 17 for SQL Server};SERVER="+ SERVERSQL+";DATABASE="+DATABASESQL+";UID="+USER+";PWD="+PASSWORD
cnn = pyodbc.connect(connection_string)
query=f"select CERE2KVC.RSDATREG,CERE2KVC.RSPUNVEN,PUN_VEND.PVDESCRI,CERE2KVC.RPTOTCON-CERE1KVC.RPRESTO as RPTOTCON,CERE2KVC.RPVALASS,CERE2KVC.RPVALCCR,CERE2KVC.RPVALBUP,CERE2KVC.RPVALBUO,CERE2KVC.RPVALCRE,CERE2KVC.RPVALALT,CERE2KVC.RSINCASS-CERE1KVC.RPRESTO as RSINCASS from (((select MSC_MAST.RSDATREG,MSC_MAST.RSPUNVEN,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='01' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPTOTCON,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='02' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPVALASS,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='03' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPVALCCR,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='04' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPVALBUP,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='05' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPVALBUO,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='06' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPVALCRE,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND MSC_DETT.RSCODICE='99' THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RPVALALT,SUM(CASE WHEN MSC_DETT.RSTIPREC='P' AND(MSC_DETT.RSCODICE='01' OR MSC_DETT.RSCODICE='02' OR MSC_DETT.RSCODICE='03' OR MSC_DETT.RSCODICE='04' OR MSC_DETT.RSCODICE='05' OR MSC_DETT.RSCODICE='06' OR MSC_DETT.RSCODICE='99') THEN MSC_DETT.RSIMPRIG ELSE 0 END) as RSINCASS from ({AZIENDA}MSC_MAST MSC_MAST Left outer Join {AZIENDA}MSC_DETT MSC_DETT on MSC_MAST.RSSERIAL=MSC_DETT.RSSERIAL) where (MSC_MAST.RSDATREG >={Variabile_DA} AND MSC_MAST.RSDATREG <={Variabile_A} AND MSC_MAST.RSTIPTRA = 'V' AND MSC_DETT.RSTIPREC = 'P') group by MSC_MAST.RSDATREG,MSC_MAST.RSPUNVEN) CERE2KVC Left outer Join (select MSC_MAST.RSDATREG,MSC_MAST.RSPUNVEN,SUM(CASE WHEN MSC_MAST.RSTIPTRA='V' THEN MSC_MAST.RS_RESTO ELSE 0 END) as RPRESTO from {AZIENDA}MSC_MAST MSC_MAST where (MSC_MAST.RSDATREG >={Variabile_DA} AND MSC_MAST.RSDATREG <={Variabile_A} ) group by MSC_MAST.RSDATREG,MSC_MAST.RSPUNVEN) CERE1KVC on CERE2KVC.RSPUNVEN=CERE1KVC.RSPUNVEN and CERE2KVC.RSDATREG=CERE1KVC.RSDATREG) Left outer Join {AZIENDA}PUN_VEND PUN_VEND on CERE2KVC.RSPUNVEN=PUN_VEND.PVCODICE)order by 2, 1 desc"
DATANOW=datetime.now()- timedelta(days=60) #150
DATANOW= (DATANOW.strftime('%Y-%m-%d'))
locale.setlocale(locale.LC_ALL, 'it_IT') # assegno nazione e lingua locale per le formattazioni degli importi in euro
NPV=0
nrighe=0
vettore =[]
vettore2=[]
cursor = cnn.cursor()
cursor.execute(query)
PVCORRENTE=0
for row in cursor.fetchall():
nrighe=nrighe+1
if PVCORRENTE!=row[1]: # PER LA PRIMA RIGA INSERISCO DATI PER INTESTAZIONE
vettore.append({"DATA": "DATA","PVCODICE": row[1],"PVDESCRI": "P. VENDITA", "CREDITI": "CREDITI", "ASSEGNI": "ASSEGNI", "ALTREFORME": "ALTRE FORME", "BUONISCONTO": "B. SCONTO", "BUONIPASTO": "B. PASTO", "CONTANTI": "CONTANTI", "POS": "POS", "INCASSI": "INCASSI"})
PVCORRENTE=row[1]
NPV=NPV+1 # CONTEGGIO TOTALE PUNTI VENDITA
vettore2.append({"DATA": f"{row[0]:%d/%m/%Y}" , "PVCODICE": row[1], "PVDESCRI": row[2], "CREDITI":"€. "+locale.format_string('%.2f', row[8], True), "ASSEGNI":"€. "+locale.format_string('%.2f', row[4], True), "ALTREFORME":"€. "+locale.format_string('%.2f', row[9], True), "BUONISCONTO":"€. "+locale.format_string('%.2f', row[7], True), "BUONIPASTO":"€. "+locale.format_string('%.2f', row[6], True), "CONTANTI":"€. "+locale.format_string('%.2f', row[3], True), "POS":"€. "+locale.format_string('%.2f', row[5], True), "INCASSI":"€. "+locale.format_string('%.2f', row[10], True) })
vettore.append({"DATA": f"{row[0]:%d/%m/%Y}" , "PVCODICE": row[1], "PVDESCRI": row[2], "CREDITI":"€. "+locale.format_string('%.2f', row[8], True), "ASSEGNI":"€. "+locale.format_string('%.2f', row[4], True), "ALTREFORME":"€. "+locale.format_string('%.2f', row[9], True), "BUONISCONTO":"€. "+locale.format_string('%.2f', row[7], True), "BUONIPASTO":"€. "+locale.format_string('%.2f', row[6], True), "CONTANTI":"€. "+locale.format_string('%.2f', row[3], True), "POS":"€. "+locale.format_string('%.2f', row[5], True), "INCASSI":"€. "+ locale.format_string('%.2f', row[10], True) })
cursor.close()
cnn.commit()
cnn.close()
return render_template('index.html', valori=vettore,valori2=vettore2, NPV=NPV )
http_server = WSGIServer((IP_APP, 12345), app)
http_server.serve_forever()
File Index.HTML
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap....." rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<title>NOMETABXX</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="https://www.indirizzo.logo" alt="" class="d-inline-block align-text-top">
</a>
</div>
</nav>
<form action="/elaborazione" method="post" class=m-4>
Seleziona Periodo: <br>
<div class="row">
<div class="col"> <input class="form-control" style="max-width:300px;" type="date" id="Da" name="DA" placeholder="Da.." value="" </input> </div>
<div class="col"> <input class="form-control" style="max-width:300px;" type="date" id="A" name="A" placeholder="A..." value="" </input> </div>
<div class="col-auto"> <button class="btn btn-primary" type="submit">Cerca</button> </div>
</div>
</form>
<div class="accordion m-2" id="accordionExample">
Totale Punti Vendita: {{NPV}}
{% for Npuntovendita in valori2 %}
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-<{{Npuntovendita.PVCODICE}}>" aria-expanded="false" aria-controls="#collapse-<{{Npuntovendita.PVCODICE}}>">
<div class="col"> <b> Punto Vendita: <br> {{Npuntovendita.PVCODICE}} {{Npuntovendita.PVDESCRI}} </b></div>
<div class="col"> <b> Ultimo Incasso aggiornato al: {{Npuntovendita.DATA}} </b> </div>
<div class="col"> <b> {{Npuntovendita.INCASSI}} </b> </div>
</button>
</h2>
{% for riga in valori %}
{% if riga.PVCODICE == Npuntovendita.PVCODICE %}
<div class="accordion-header">
<div id="collapse-<{{Npuntovendita.PVCODICE}}>" class="accordion-collapse collapse" data-bs-parent="#accordion-header" >
<div class="row g-0 text-end">
<style>
@media screen and (min-width: 801px) { div.row { font-size: 16px; padding:1px; margin-top:2px }}
@media screen and (max-width: 800px) { div.row { font-size: 9px; padding:1px; margin-top:1px; margin-left:0; margin-right:0; border:0}}
@media screen and (max-width: 700px) { div.row { font-size: 5px; padding:1px; margin-top:2px; margin-left:0; margin-right:0; border:0}}
</style>
<div class="col text-center"> {{riga.DATA}} </div>
<div class="col-2 col-lg-2 text-center"> {{riga.PVDESCRI}} </div>
<div class="col"> {{riga.CREDITI}} </div>
<div class="col"> {{riga.ASSEGNI}} </div>
<div class="col"> {{riga.ALTREFORME}} </div>
<div class="col"> {{riga.BUONISCONTO}} </div>
<div class="col"> {{riga.BUONIPASTO}} </div>
<div class="col"> {{riga.CONTANTI}} </div>
<div class="col text-end"> {{riga.POS}} </div>
<div class="col"> <b> {{riga.INCASSI}}   </b> </div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap...t/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>
</html>
Tutto funziona correttamente in base alle mie necessità…. L'unica cosa che volevo aggiungere è un “loader”, o meglio una barra di progressione, che durante l'esecuzione della query, dia un messaggio di attesa…visto che a volte ci vogliono anche una ventina di secondi…