| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- from django.shortcuts import render
- from django.http import HttpResponse,HttpResponseRedirect,FileResponse
- from django.urls import reverse
- from django.db import IntegrityError
- from .models import *
- from config.views import *
- from att.views import *
- from django.conf import settings
- from django.conf.urls.static import static
- from django.contrib.auth import authenticate
- import mimetypes
- from random import randint
- import csv
- import time
- import datetime
- import zipfile
- import re
- #pip install python-codicefiscale
- from codicefiscale import codicefiscale
- import os
- # come sono gestiti i file nella configurazione:
- # MEDIA_ROOT=os.path.join(settings.BASE_DIR,'static/upload')
- # che diventa = os.path.join(settings.BASE_DIR,getConfig('DocPath'))
- # inoltre devo aver fatto qualche casino oggi 9.8.24 con i copia e incolla. ho dovuto rivedere tutto il file
- # il terrore si impossessa di me. sta storia del cvs non e' esattamente chiara
- # questo blocco rimuove fisicamente il file prima della sua rimozione logica nel db
- def delete_file(documento):
- file_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'),documento.utente.azienda.partitaiva,documento.utente.codicefiscale,documento.storage)
- print('Path completa:',file_path)
- if os.path.isfile(file_path):
- print('rimozione fisica file:',file_path)
- try:
- os.remove(file_path)
- except OSError as ose:
- print('errore nella rimozione del file:',ose)
- # impacchetta il file e procede a fornire il file via web
- def download_file(request,uid):
- utente = Utenti.objects.get(pk=uid)
- file_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'),documento.utente.azienda.partitaiva,documento.utente.codicefiscale,utente.storage)
- print('Path completa da Basedir:',file_path)
- if utente.storage and os.path.isfile(file_path):
- try:
- fl = open(file_path, 'rb')
- except Exception as er:
- print('errore',er)
- data=dict()
- data['errore']="File non esistente o non ancora disponibile"
- data['utente'] = utente
- return render(request,'documento.error.html',data)
- else:
- print('il file non esiste',file_path)
- data=dict()
- data['errore']='File non esistente o non ancora disponibile'
- data['utente'] = utente
- return render(request,'documento.error.html',data)
- mime_type, _ = mimetypes.guess_type(file_path)
- print('file',file_path,mime_type)
- response = FileResponse(open(file_path,'rb'),content_type='application/pdf',as_attachment=False)
- #response['Content-Disposition'] = "attachment; filename=%s" % u.documento
- return response
- # upload file
- # procedura singolo file per singolo utente
- def upload_file(uploaded_file,utente,originale=False):
- stored_file = ''.join((str(time.time()),'.saved'))
- fl_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'))
- print('nome file',uploaded_file.name,stored_file)
- #modifico il file per dire alla funzione superiore se il file e' stato caricato o meno
- nomefile=None
- if originale:
- nomefile = uploaded_file.name
- else:
- nomefile = stored_file
- # vediamo se caricare o meno.
- # in questo caso, se il documento esiste gia', non lo carica.
- # come facciamo a stabilire se il documento esiste gia'?
- # fl_path = corrisponde a media.ROOT (che mi domando se non e' il caso di spostarlo nella configurazione)
- # azienda.partitaiva
- # utente.codicefiscale (prima era "record" e mi sono deciso a cambiarlo)
- try:
- print('posizione partitaiva',os.path.join(fl_path,utente.azienda.partitaiva))
- os.mkdir(os.path.join(fl_path,utente.azienda.partitaiva))
- except FileExistsError as fee:
- print('posizione partitaiva',os.path.join(fl_path,utente.azienda.partitaiva),"esistente")
- try:
- print("posizione partitaiva codicefiscale",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale))
- os.mkdir(os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale))
- except FileExistsError as fee:
- print("posizione partitaiva codicefiscale",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale),"esistente")
- with open(os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile),'wb+') as d:
- for chunk in uploaded_file.chunks():
- d.write(chunk)
- if originale:
- # viene richiesto il file originale piuttosto cheil file codificato con il timing
- print("viene restituito il file originale",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile))
- return os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile)
- print("viene restituito il file rinominato",os.path.join(fl_path,utente.azienda.partitaiva,utente.codicefiscale,nomefile))
- return stored_file
- # caricamento file indice (gestito in modo diverso)
- def upload_file_indice(uploaded_file):
-
- stored_file = ''.join((str(time.time()),'.saved'))
- fl_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'),getConfig('DocPathIndex'))
- print('nome file',uploaded_file.name,stored_file)
- # verifica l'esistenza della directory
- try:
- os.mkdir(fl_path)
- except FileExistsError as fee:
- print(fl_path,"esistente")
- print('file_memorizzato',os.path.join(fl_path,stored_file))
- with open(os.path.join(fl_path,stored_file),'wb+') as d:
- for chunk in uploaded_file.chunks():
- d.write(chunk)
- return stored_file
- # sposta directory sulla base del codicefiscale aggiornato
- def rename_dir(utente,old,new):
- fl_path = os.path.join(settings.BASE_DIR,getConfig('DocPath'))
- try:
- print("posizione partitaiva codicefiscale",os.path.join(fl_path,utente.azienda.partitaiva,old))
- os.rename(os.path.join(fl_path,utente.azienda.partitaiva,old),os.path.join(fl_path,utente.azienda.partitaiva,new))
- except FileExistsError as fee:
- print("posizione partitaiva codicefiscale old",os.path.join(fl_path,utente.azienda.partitaiva,old))
- print("posizione partitaiva codicefiscale new",os.path.join(fl_path,utente.azienda.partitaiva,new),"esistente")
- return False
- except FileNotFoundError as fnfe:
- print('non trovo la directory da rinominare')
- return False
- except OSError as ose:
- print('errore generico')
- print(ose)
- return False
- return True
- # il file caricato viene associato a un utente specifico
- def associafile_a_utente(singolodocumento,request,utente,azienda=None,sede=None,descrizione=None,amministratore=None,pertutti=False):
- risultato = upload_file(singolodocumento,utente)
- documento = Documento()
- documento.dataupload = datetime.datetime.now()
- documento.utente = utente
- listaok = None
- listanotok = None
- if pertutti:
- documento.documento = "".join((utente.codicefiscale.strip(),"_",singolodocumento.name))
- else:
- documento.documento = singolodocumento.name
- print('documento.documento',documento.documento)
- documento.storage = risultato
- documento.descrizione = descrizione
- # verifica se il file è da considerarsi privato
- # 21.11.25: anziche' cercare la parola nella stringa, ho usato le regex... che mi sembrano decisamente meglio
- r = re.compile(r"^emo(_|-)",re.I)
- if r.match(documento.documento.lower()):
- print("Individuato elemento emo_ in:", documento.documento)
- documento.privato = True
- try:
- documento.save()
- setLog(8,azienda=azienda,sede=sede,utente=utente,documento=documento,amministratore=amministratore)
- listaok = {'n':documento.documento,'c':'documento assegnato regolarmente'}
- except IntegrityError as ie:
- print("problema di integrita', il file esiste",ie)
- listanotok = {'n':documento.documento,'c':'documento esistente'}
- return(listaok,listanotok)
- ##################################################################################
- # carica file multipli. Utilizzato prevalentemente dalla gestione documenti.
- def save_and_load_file_multiple(listadocumenti,request,utente,azienda=None,sede=None,descrizione=None,amministratore=None,pertutti=False,ignoraAzienda=False,ignoraSede=False,_privato=False):
- listaok = list()
- listanotok = list()
- listanotass = list()
- if azienda: print('Caricamento Multiplo,azienda',azienda.nome)
- if sede: print('Caricamento Multiplo,sede',sede.nome)
- print("Ignora le aziende",ignoraAzienda)
- print("Ignora le sedi",ignoraSede)
- print("Per tutti",pertutti)
- print("Privato",_privato)
- for singolodocumento in listadocumenti:
- print('singolodocumento:',singolodocumento)
- statusAss = False
- for ut in utente:
- print('utente:',ut.nome)
- lok = None
- nok = None
- # si deve individuare il codice fiscale dell'utente
- if not pertutti:
- if ut.codicefiscale.strip() in singolodocumento.name:
- statusAss = True
- print('associa documento CON riferimento a codice fiscale')
- if ignoraAzienda:
- print("Effettua ricerca in tutte le aziende")
- lok,nok = associafile_a_utente(singolodocumento,request,ut,ut.azienda,sede,descrizione,amministratore)
- elif ignoraSede:
- print("Effettua ricerca in tutte le Sedi dell'azienda")
- lok,nok = associafile_a_utente(singolodocumento,request,ut,ut.azienda,sede,descrizione,amministratore)
- else:
- print("Caricamento solo per l'azienda corrente")
- lok,nok = associafile_a_utente(singolodocumento,request,ut,azienda,sede,descrizione,amministratore)
- #else:
- # print('il codice fiscale',ut.codicefiscale.strip()," non si trova in ",singolodocumento.name)
- # statusAss = False
- else:
- print('associo documento SENZA riferimento a codice fiscale')
- lok,nok = associafile_a_utente(singolodocumento,request,ut,azienda,sede,descrizione,amministratore,pertutti)
- #lok: file associato in quanto nuovo
- #nok: file non associato perche' gia esistente
- if lok:
- listaok.append(lok)
- if nok:
- listanotok.append(nok)
- # se statusAss passa a False, significa che il codice fiscale non si trova.
- # pertanto lo inserisco tra quelli non associabili.
- if not statusAss:
- listanotass.append({'n':singolodocumento.name,'c':'non associabile - il codice fiscale non corrisponde'})
- print('lista',listaok,listanotok,listanotass)
- return (listaok,listanotok,listanotass)
- #carica un singolofile - utilizzato prevalentemente nella pagina utente
- def save_and_load_file_single(listadocumenti,request,utente,azienda=None,sede=None,descrizione=None,amministratore=None,_privato=False):
- """
- listadocumenti da caricare
- request: i documenti vengono caricati via web
- utente: utente a cui associare il documento
- azienda: (perche? se l'utente deve essere gia' associato a un'azienda?)
- sede: (lo stesso, perche' passare la sede, se l'utente stesso dovrebbe avere gia' l'indicazione della sede)
- e comunque questi parametri servono solo per i log, che insomma, posso aggirarli con semplicita'
- descrizione: descrizione assegnata al documento
- amministratore: caricamente a mezzo di un amministratore
- """
- listaok = list()
- listanotok = list()
- listanotass = list()
- associato=False
- for singolodocumento in listadocumenti:
- print('singolodocumento',singolodocumento,descrizione)
- #risultato = upload_file(singolodocumento,utente)
- documento = Documento()
- documento.dataupload = datetime.datetime.now()
- documento.utente = utente
- documento.documento = singolodocumento.name
- #documento.storage = risultato
- documento.descrizione = descrizione
- documento.privato = _privato
- # verifica se il documento debba essere inserito come privato o meno
- r = re.compile(r"^emo(_|-)",re.I)
- if r.match(documento.documento):
- print("Individuato elemento emo_ in:", documento.documento)
- documento.privato = True
- try:
- documento.save()
- setLog(8,azienda=azienda,sede=sede,utente=utente,documento=documento,amministratore=amministratore)
- #listaok.append(documento)
- print('record generato:',documento.id)
- associato=True
- except IntegrityError as ie:
- print("problema di integrita', il file esiste",ie)
- listanotok.append(documento)
- if associato:
- print("Il documento è correttamente associato",documento.documento,documento.utente.nome)
- # se il record e' stato correttamente salvato, procede al caricamento del file.
- risultato=upload_file(singolodocumento,utente)
- documento.storage = risultato
- documento.save()
- listaok.append(documento)
- else:
- listanotass.append(documento)
- return (listaok,listanotok,listanotass)
- #file_indice: contiene l'elenco dei nominativi da gestire.
- def save_and_load_file_indice(request,fileindice,azienda=None,sede=None):
- """
- qui, oltre alla request, viene chiesto il nome del file indice
- il nome dell'azienda a cui si fa riferimento e la sua sede
- """
- print('nome indice caricato',fileindice.name)
- if azienda: print('azienda',azienda.nome)
- if sede: print('sede',sede.nome)
- file_memorizzato = upload_file_indice(request.FILES['indice'])
- fl_path = os.path.join(getConfig('DocPath'),getConfig('DocPathIndex'))
- risultato = None
- listaOk=list()
- listaNotOk=list()
- listaNotAss=list()
- with open(os.path.join(fl_path,file_memorizzato),'rb') as ind:
- risultato = ind.read()
- risultato = risultato.decode('utf-8',errors='replace')
- if isinstance(risultato,str):
- risultato = risultato.encode('utf8')
- with open(os.path.join(fl_path,''.join((file_memorizzato,'.cvtd'))),'wb') as ind:
- ind.write(risultato)
- print('una volta convertito, passiamo oltre')
-
- with open(os.path.join(fl_path,''.join((file_memorizzato,'.cvtd'))),'rt') as ind:
- spamreader = csv.reader(ind,delimiter=';')
- next(spamreader,None) #salta l'intestazione
- count = 0
- for sr in spamreader:
- salvare = False
- count +=1 #il recordo parte gia' dalla riga 1
- # 30.10.25: Vale ha segnalato che il caricamente parte sempre dalla seconda riga utile.
- # if count==1: continue
- print(count,'sr',sr,len(sr))
- if len(sr) >= 1 and len("".join(sr)) > 0: # la lunghezza del record segnala qualcosa
- print('record sr',sr)
- utente = None
- codicefiscale = sr[1].strip()
- print('codice fiscale',sr[1].strip().upper())
- try:
- utente = Utente.objects.get(codicefiscale=sr[1].strip().upper())
- listaNotAss.append({"nome":utente.nome,"codicefiscale":utente.codicefiscale,"errore":"già presente"})
- print('Utente Trovato')
- except Utente.DoesNotExist as dne:
- print('Utente non trovato,lo aggiungo')
- utente = Utente()
- if azienda:
- utente.azienda = azienda
- print('Associata Azienda')
- if sede:
- utente.sede = sede
- print('Associata Sede')
- utente.nome = sr[0].strip().title()
- print("Utente:",utente.nome)
- utente.codicefiscale=sr[1].strip().upper()
- print("Codice Fiscale",utente.codicefiscale,len(utente.codicefiscale))
- for fmt in ('%d/%m/%y','%d/%m/%Y','%d-%m-%y','%d-%m-%Y'):
- try:
- data_convertita = datetime.datetime.strptime(sr[2],fmt)
- print('data convertita',data_convertita)
- utente.datanascita = data_convertita
- except ValueError as ve:
- print('errore con la data di nascita',ve)
- utente.luogonascita = sr[3].title()
- print("Luogo di nascita",utente.luogonascita)
- utente.mail = sr[4].strip().lower()
- print("Mail",utente.mail)
- # ricerca sede: se il codice estratto nella colonna corrisponde...
- tmp_sede = sr[5]
- lista_sede = azienda.sede_set.all()
- for ls in lista_sede:
- if tmp_sede == ls.identificativo:
- utente.sede = ls
- utente.cabiopassword = ls.cambiopassword
- utente.forzanuovapassword = ls.forzanuovapassword
- utente.otppassword = ls.otppassword
- else:
- utente.cabiopassword = azienda.cambiopassword
- utente.forzanuovapassword = azienda.forzanuovapassword
- utente.otppassword = azienda.otppassword
-
- utente.inserimento = datetime.datetime.today().strftime("%Y-%m-%d")
- utente.pin = str(randint(100000,999999))
- if len(utente.codicefiscale) == 16:
- utente.save()
- listaOk.append({"nome":utente.nome,"codicefiscale":utente.codicefiscale})
- else:
- print("Codice Fiscale NON valido o mancante")
- listaNotOk.append({"nome":utente.nome,"codicefiscale":utente.codicefiscale,"errore":"Codice Fiscale"})
- return (listaOk,listaNotOk,listaNotAss,count)
- def PrepareZipFile(listafile=[]):
- zip_path = os.path.join(settings.BASE_DIR,getConfig('DocZipFile'))
- print("zip_path:",zip_path)
- # verifica l'esistenza della directory
- try:
- os.mkdir(zip_path)
- except FileExistsError as fee:
- print(zip_path,"esistente")
- filename = ''.join((str(time.time()),'.zip'))
- with zipfile.ZipFile(os.path.join(zip_path,filename),'w') as zip:
- for lf in listafile:
- d = Documento.objects.get(pk=lf)
- file2zip = os.path.join(settings.BASE_DIR,getConfig('DocPath'),d.utente.azienda.partitaiva,d.utente.codicefiscale,d.storage)
- print('path completa',file2zip)
- print('file completo',os.path.join(zip_path,filename))
- if os.path.exists(file2zip):
- zip.write(file2zip,arcname=d.documento)
- else:
- print('il file non esiste:',file2zip)
- return (zip_path,filename)
|