def logout(request): logged = request.user.is_authenticated() and request.user response = django_logout(request, login_url="/") if not request.user.is_authenticated() and logged: # just logged out logger.debug("Logout user %s" % logged) logAction('O', description='Disconnesso', user=logged) return response
def doBackup(user): backupInfo = getBackupInfo(doCleanup=True) logAction('B', description='Backup richiesto', user=user) username = user.username dbType = settings.DATABASES['default']['ENGINE'] n = tamdates.ita_now() newBackupFilename = "%s - tam - %s" % (n.strftime('%Y-%m-%d %H%M'), username) backupPath = os.path.join(backupInfo["backupdir"], newBackupFilename) logging.debug("%s ===> %s" % (backupInfo["dbname"], backupPath)) if dbType == 'django.db.backends.sqlite3': doBackupSqlite(targetFile=backupPath + ".db3.gz", sourceFile=backupInfo["dbname"]) elif dbType == 'django.db.backends.postgresql_psycopg2': doBackupPostgre( targetFile=backupPath + ".pgdump", dbName=settings.DATABASES['default']['NAME'], host=settings.DATABASES['default']['HOST'], port=settings.DATABASES['default']['PORT'], username=settings.DATABASES['default']['USER'], password=settings.DATABASES['default']['PASSWORD'], ) else: raise Exception("Impossibile fare backup di %s" % dbType) return backupPath
def getbackup(request, backupdate): if not request.user.has_perm('tam.get_backup'): messages.error(request, "Non hai accesso al download dei backup.") return HttpResponseRedirect(reverse("tamBackup")) t = time.strptime(backupdate, '%d-%m-%Y-%H%M') dataScelta = datetime.datetime(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min) backupInfo = getBackupInfo(doCleanup=True) for backup in backupInfo["backups"]: if backup["date"].timetuple()[:5] == dataScelta.timetuple()[:5]: logAction('G', description='Backup del %s scaricato' % backupdate, user=request.user) backup_filename = backup["filename"] backupPath = os.path.join(backupInfo["backupdir"], backup_filename) responseFile = open(backupPath, 'rb') response = HttpResponse( responseFile.read(), content_type='application/octet-stream') # 'application/gzip' response[ 'Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename( backup_filename) return response else: messages.error(request, "Backup del %s non trovato." % dataScelta) return HttpResponseRedirect(reverse("tamBackup"))
def login(request): if getattr(request, 'limited', False): messages = ["Too many requests on {path}. Page forbidden.".format(path=request.path), "From IP: %s" % get_client_ip(request)] if request.method == "POST" and request.POST.get('username'): messages.append("Last try with username: %s" % request.POST.get('username')) logger.error("\n".join(messages)) return render_to_response("429-limited.html", status=429) logged = request.user.is_authenticated() and request.user.username response = django_login(request, template_name="login.html", extra_context={'logo_consorzio': settings.TRANSPARENT_LOGO, 'nome_consorzio': settings.LICENSE_OWNER }, authentication_form=AuthenticationFormWrapped, ) if request.user.is_authenticated() and request.user.username != logged: # just logged in request.session["userAgent"] = request.META.get('HTTP_USER_AGENT') logger.debug("Login for %s" % request.user) logAction('L', description='Accesso effettuato', user=request.user) else: if request.method == "POST": logger.debug("Login attempt failed") if request.is_ajax(): return HttpResponseServerError("Please login") return response
def nuova_fattura(request, fatturazione): tipo = fatturazione.codice if fatturazione.ask_progressivo: anno = datetime.date.today().year ultimo = ultimoProgressivoFattura(anno, tipo=tipo) progressivo = ultimo + 1 else: anno = None progressivo = None # if tipo == '3': # # le ricevute hanno sempre come data l'ultimo fine mese precedente # data_fattura = datetime.date.today().replace(day=1) - datetime.timedelta(days=1) # else: data_fattura = datetime.date.today() fattura = Fattura(anno=anno, tipo=tipo, progressivo=progressivo, data=data_fattura) if fatturazione.mittente == "consorzio": fattura.emessa_da = settings.DATI_CONSORZIO elif fatturazione.destinatario == "consorzio": fattura.emessa_a = settings.DATI_CONSORZIO fattura.save() message = "Creata la %s %s." % (fattura.nome_fattura(), fattura.descrittore()) messages.success(request, message) logAction('C', instance=fattura, description=message, user=request.user) return HttpResponseRedirect(fattura.url())
def clean(self): cleaned_data = super(AuthenticationFormWrapped, self).clean() username = self.cleaned_data.get('username') request = self.request user = self.user_cache if settings.FORCE_SINGLE_DEVICE_SESSION and user: if hasattr(user, "prenotazioni"): utentePrenotazioni = user.prenotazioni else: utentePrenotazioni = None if not user.has_perm( 'tam.reset_sessions') and not utentePrenotazioni: concurrent_sessions = get_concurrent_sessions(request, user) if concurrent_sessions: logger.warning( "We have concurrent sessions: login forbidden") logAction('L', description='Accesso proibito - multisessione', user=user) raise forms.ValidationError( self.error_messages['multisession_forbidden'], code='multisession_forbidden', params={'username': username}, ) return cleaned_data
def login(request): if getattr(request, 'limited', False): messages = [ "Too many requests on {path}. Page forbidden.".format( path=request.path), "From IP: %s" % get_client_ip(request) ] if request.method == "POST" and request.POST.get('username'): messages.append("Last try with username: %s" % request.POST.get('username')) logger.error("\n".join(messages)) return render_to_response("429-limited.html", status=429) logged = request.user.is_authenticated() and request.user.username response = django_login( request, template_name="login.html", extra_context={ 'logo_consorzio': settings.TRANSPARENT_LOGO, 'nome_consorzio': settings.LICENSE_OWNER }, authentication_form=AuthenticationFormWrapped, ) if request.user.is_authenticated( ) and request.user.username != logged: # just logged in request.session["userAgent"] = request.META.get('HTTP_USER_AGENT') logger.debug("Login for %s" % request.user) logAction('L', description='Accesso effettuato', user=request.user) else: if request.method == "POST": logger.debug("Login attempt failed") if request.is_ajax(): return HttpResponseServerError("Please login") return response
def logAndCleanExpiredSessions(): """ Clear all the expired sessions and log the disconnection of the users """ for s in Session.objects.filter(expire_date__lt=timezone.now()): data = s.get_decoded() try: if '_auth_user_id' in data: user = User.objects.get(id=data['_auth_user_id']) logAction('O', user=user, description='Sessione scaduta', log_date=s.expire_date) except: pass s.delete()
def flat(request, template_name="archive/flat.html"): """ Livella le classifiche, in modo che gli ultimi abbiano zero """ if not request.user.has_perm('tamArchive.flat'): messages.error(request, "Devi avere accesso all'appianamento.") return HttpResponseRedirect(reverse("tamArchiveUtil")) classifiche = get_classifiche() def trovaMinimi(c1, c2): """ Date due classifiche (2 conducenti) ritorna il minimo """ keys = ("puntiDiurni", "puntiNotturni", "prezzoDoppioPadova", "prezzoVenezia", "prezzoPadova") results = OrderedDict() for key in keys: v1, v2 = c1[key], c2[key] if type(v1) is float: v1 = Decimal("%.2f" % v1) # converto i float in Decimal if type(v2) is float: v2 = Decimal("%.2f" % v2) results[key] = min(v1, v2) return results minimi = reduce(trovaMinimi, classifiche) # controllo che ci sia qualche minimo da togliere flat_needed = (max(minimi.values()) > 0) if "flat" in request.POST and flat_needed: logAction("F", instance=request.user, description="Appianamento delle classifiche", user=request.user) logging.debug("FLAT delle classifiche") stopLog(Conducente) with transaction.atomic(): for conducente in Conducente.objects.all(): conducente.classifica_iniziale_diurni -= minimi["puntiDiurni"] conducente.classifica_iniziale_notturni -= minimi[ "puntiNotturni"] conducente.classifica_iniziale_doppiPadova -= minimi[ 'prezzoDoppioPadova'] conducente.classifica_iniziale_long -= minimi['prezzoVenezia'] conducente.classifica_iniziale_medium -= minimi['prezzoPadova'] conducente.save() startLog(Conducente) messages.success(request, "Appianamento effettuato.") return HttpResponseRedirect(reverse("tamArchiveUtil")) return render(request, template_name, { "minimi": minimi, 'flat_needed': flat_needed })
def flat(request, template_name="archive/flat.html"): """ Livella le classifiche, in modo che gli ultimi abbiano zero """ if not request.user.has_perm('tamArchive.flat'): messages.error(request, "Devi avere accesso all'appianamento.") return HttpResponseRedirect(reverse("tamArchiveUtil")) classifiche = get_classifiche() def trovaMinimi(c1, c2): """ Date due classifiche (2 conducenti) ritorna il minimo """ keys = ("puntiDiurni", "puntiNotturni", "prezzoDoppioPadova", "prezzoVenezia", "prezzoPadova") results = OrderedDict() for key in keys: v1, v2 = c1[key], c2[key] if type(v1) is float: v1 = Decimal("%.2f" % v1) # converto i float in Decimal if type(v2) is float: v2 = Decimal("%.2f" % v2) results[key] = min(v1, v2) return results minimi = reduce(trovaMinimi, classifiche) # controllo che ci sia qualche minimo da togliere flat_needed = (max(minimi.values()) > 0) if "flat" in request.POST and flat_needed: logAction("F", instance=request.user, description="Appianamento delle classifiche", user=request.user) logging.debug("FLAT delle classifiche") stopLog(Conducente) with transaction.atomic(): for conducente in Conducente.objects.all(): conducente.classifica_iniziale_diurni -= minimi["puntiDiurni"] conducente.classifica_iniziale_notturni -= minimi[ "puntiNotturni"] conducente.classifica_iniziale_doppiPadova -= minimi[ 'prezzoDoppioPadova'] conducente.classifica_iniziale_long -= minimi['prezzoVenezia'] conducente.classifica_iniziale_medium -= minimi['prezzoPadova'] conducente.save() startLog(Conducente) messages.success(request, "Appianamento effettuato.") return HttpResponseRedirect(reverse("tamArchiveUtil")) return render(request, template_name, {"minimi": minimi, 'flat_needed': flat_needed})
def xlsResponse(request, querySet): doc = xlwt.Workbook() numViaggi = querySet.count() logging.debug("Export to EXCEL %d viaggi." % numViaggi) if numViaggi > settings.MAX_XLS_ROWS: messages.error(request, "Non puoi esportare in Excel più di %d viaggi contemporaneamente." % settings.MAX_XLS_ROWS) return HttpResponseRedirect("/") # back home # from guppy import hpy # h = hpy() # h.setref() querySet = querySet.select_related("da", "a", "cliente", "conducente", "passeggero") generatore = xlsUtil.Sql2xls(doc, manager=querySet) tamEnumerateTables = lambda x: djangoManagerToTable(x, fields=corseField) generatore.enumerateTables = tamEnumerateTables generatore.run() if generatore.sheetCount: output = BytesIO() doc.save(output) # save the excel output.seek(0) response = HttpResponse(output.getvalue(), content_type='application/excel') response['Content-Disposition'] = \ 'attachment; filename="%s"' % 'tamExport.xls' logAction(action='X', description="Export in Excel di %d corse." % numViaggi, user=request.user, log_date=None) # print h.heap() return response else: messages.error(request, "Non ho alcun viaggio da mettere in Excel," + " cambia i filtri per selezionarne qualcuno.") del generatore return HttpResponseRedirect("/") # back home
def clean(self): cleaned_data = super(AuthenticationFormWrapped, self).clean() username = self.cleaned_data.get('username') request = self.request user = self.user_cache if settings.FORCE_SINGLE_DEVICE_SESSION and user: if hasattr(user, "prenotazioni"): utentePrenotazioni = user.prenotazioni else: utentePrenotazioni = None if not user.has_perm('tam.reset_sessions') and not utentePrenotazioni: concurrent_sessions = get_concurrent_sessions(request, user) if concurrent_sessions: logger.warning("We have concurrent sessions: login forbidden") logAction('L', description='Accesso proibito - multisessione', user=user) raise forms.ValidationError( self.error_messages['multisession_forbidden'], code='multisession_forbidden', params={'username': username}, ) return cleaned_data
def post(self, request, *args, **kwargs): context = self.get_context_data() form = context['form'] action = request.POST.get('action') if not context['can_edit']: return self.render_to_response( dict(message=u"Non hai permessi per modificare le presenze.", status=401, redirect_url='calendariopresenze-manage')) if action == 'new': if not request.user.has_perm('calendariopresenze.add_calendar'): return self.render_to_response( dict( message=u"Non hai permessi per modificare le presenze.", status=401, redirect_url='calendariopresenze-manage')) cal_fixed_start = None cal_fixed_end = None subname = None caldesc = None if 'type' in request.POST: try: caldesc = settings.CALENDAR_DESC[int(request.POST['type'])] if "subname" in request.POST: subname = request.POST['subname'] for subcal in caldesc['display_as']: if subcal['name'] == subname: cal_fixed_start = subcal['date_start'] cal_fixed_end = subcal['date_end'] break except ValueError: pass day = context['day'] conducente_id = int(request.POST['conducente']) conducente = Conducente.objects.get(id=conducente_id) calendar_type = int(request.POST['type']) if 'time_from' in request.POST: string_from = request.POST['time_from'] try: date_start = appendTimeToDate(day, string_from) except ValueError: return self.render_to_response( dict(message=u"Ora iniziale non valida.", status=400, redirect_url='calendariopresenze-manage')) else: assert cal_fixed_start date_start = appendTimeFromRegex(day, cal_fixed_start) if 'time_to' in request.POST: string_to = request.POST['time_to'] try: date_end = appendTimeToDate(day, string_to) except ValueError: return self.render_to_response( dict(message=u"Ora finale non valida.", status=400, redirect_url='calendariopresenze-manage')) else: assert cal_fixed_end date_end = appendTimeFromRegex(day, cal_fixed_end) calendar = Calendar( conducente=conducente, type=calendar_type, date_start=date_start, date_end=date_end, ) calendar.save() logAction( 'P', instance=calendar, description=u"Presenze: aggiunto {name} {calendar}".format( name=subname or caldesc['name'], calendar=calendar)) if request.is_ajax(): row_template = get_template('calendar/cal_row.html') # I use the context view, adding the things to render the row context.update( dict( element=calendar, calDesc=settings.CALENDAR_DESC[calendar.type], )) return HttpResponse(row_template.render(context, request), status=201) else: return HttpResponseRedirect( reverse('calendariopresenze-manage') + '?day=' + context['selected_day']) elif action == 'delete': if not request.user.has_perm('calendariopresenze.delete_calendar'): return self.render_to_response( dict( message=u"Non hai permessi per cancellare le presenze.", status=401, redirect_url='calendariopresenze-manage')) try: calendar = Calendar.objects.get(id=request.POST['calendar_id']) except Calendar.DoesNotExist: return self.render_to_response( dict(message=u"Il calendario indicato non esiste più.", status=400, redirect_url='calendariopresenze-manage')) caldesc = settings.CALENDAR_DESC[calendar.type] logAction( 'P', instance=calendar, description=u"Presenze: cancellato {name} {calendar}".format( name=caldesc['name'], calendar=calendar)) calendar.delete() return HttpResponse("ok", status=200) elif action == 'toggle': if not request.user.has_perm( 'calendariopresenze.toggle_calendarvalue'): return self.render_to_response( dict( message= u"Non hai permessi per modificare il valore dei calendari.", status=401, redirect_url='calendariopresenze-manage')) try: calendar = Calendar.objects.get(id=request.POST['calendar_id']) except Calendar.DoesNotExist: return self.render_to_response( dict(message=u"Il calendario indicato non esiste più.", status=400, redirect_url='calendariopresenze-manage')) caldesc = settings.CALENDAR_DESC[calendar.type] if 'toggle' not in caldesc: return self.render_to_response( dict(message=u"Valore del calendario non modificabile.", status=400, redirect_url='calendariopresenze-manage')) old_value = calendar.value caldesc['toggle'](calendar) new_value = calendar.value logAction( 'P', instance=calendar, description= u"Presenze: variato {name} {calendar} da {old} a {new}".format( name=caldesc['name'], calendar=calendar, old=old_value, new=new_value, )) if request.is_ajax(): row_template = get_template('calendar/cal_row.html') # I use the context view, adding the things to rendere the row context.update( dict(element=calendar, calDesc=settings.CALENDAR_DESC[calendar.type])) return HttpResponse(row_template.render(context, request), status=201) else: return HttpResponseRedirect( reverse('calendariopresenze-manage') + '?day=' + context['selected_day']) else: return self.render_to_response( dict(message=u"Azione sconosciuta.", status=400, redirect_url='calendariopresenze-manage'))
def fattura(request, id_fattura=None, anno=None, progressivo=None, tipo=None, template_name="6.fattura.html"): """ Vedo la fattura ed (eventualmente) ne consento la modifica """ try: if id_fattura: fattura = Fattura.objects.get(id=id_fattura) else: fattura = Fattura.objects.get(tipo=tipo, anno=anno, progressivo=progressivo) except Fattura.DoesNotExist: if request.is_ajax(): return HttpResponse('Questa fattura non esiste più.', status=400) else: messages.error(request, "Fattura non trovata.") return HttpResponseRedirect(reverse('tamVisualizzazioneFatture')) bigEdit = request.user.has_perm('fatturazione.generate') # gli utenti con smalledit possono cambiare le fatture conducenti, per alcuni campi smallEdit = request.user.has_perm('fatturazione.smalledit') \ and fattura.tipo in ( '2', '5') # le fatture conducente IVATE e NON consentono gli smalledit editable = bigEdit or smallEdit readonly = not editable if request.is_ajax(): action = request.POST.get('action') if action == 'delete-fat': if not bigEdit: return HttpResponse( 'Non hai permessi per cancellare le fatture.', status=400) # cancello l'intera fattura. # se ho successo, restituisco l'url a cui andare message = "%s eliminata." % fattura.nome_fattura() try: logAction('C', instance=fattura, description=message, user=request.user) fattura.delete() except: return HttpResponse( 'Non sono riuscito a cancellare la fattura.', status=400) messages.success(request, message) return HttpResponse(reverse('tamVisualizzazioneFatture'), status=200) if action == 'delete-row': if not bigEdit: return HttpResponse( 'Non hai permessi per cancellare le righe delle fatture.', status=400) try: rowid = int(request.POST.get('row')) # if rowid in fattura.righe.values_list('id', flat=True): riga = fattura.righe.get(id=rowid) logAction('C', instance=fattura, description="Riga eliminata.", user=request.user) riga.delete() return HttpResponse('Riga eliminata.', status=200) except Exception as e: return HttpResponse('Impossibile trovare la riga.\n%s' % e, status=500) if action == 'append-row': if not bigEdit: return HttpResponse( 'Non hai permessi sufficienti per aggiungere righe.', status=400) ultimaRiga = fattura.righe.aggregate(Max('riga'))['riga__max'] or 0 riga = RigaFattura( descrizione="riga inserita manualmente", qta=1, prezzo=0, iva=10 if fattura.tipo not in ('3', '4', '5') else 0, # tipi esenti IVA riga=ultimaRiga + 10) riga.fattura = fattura riga.save() logAction('C', instance=fattura, description="Riga inserita manualmente.", user=request.user) return render( request, '6.fattura-riga.inc.html', { "riga": riga, 'readonly': readonly, 'bigEdit': bigEdit, 'smallEdit': smallEdit, }, ) if action == 'set': object_id = request.POST.get('id') smallcampi_modificabili = ('fat_anno', 'fat_progressivo', 'fat_note') # modificabili in testata if smallEdit and (object_id in smallcampi_modificabili or object_id.startswith('riga-desc-')): # posso modificare il campo in quanto è una modifica consentita pass else: if not bigEdit: return HttpResponse( 'Non hai permessi sufficienti per modificare le fatture.', status=400) object_value = request.POST.get('value') header_ids = { 'fat_mittente': 'emessa_da', 'fat_note': 'note', 'fat_destinatario': 'emessa_a', 'fat_anno': 'anno', 'fat_progressivo': 'progressivo', 'fat_data': 'data', } header_numerici = ['fat_anno', 'fat_progressivo'] logAction('C', instance=fattura, description=u"%s modificato in %s." % (object_id, object_value), user=request.user) if object_id in header_ids: # print("cambio il valore di testata da %s a %s" % # ( getattr(fattura, header_ids[object_id]), # object_value) # ) if object_id in header_numerici: if object_value.strip( ) == '': # converto nei valori numerici, # le stringhe vuote in None object_value = None else: try: object_value = int(object_value.replace( ',', '.')) # altrimenti richiedo un numerico except Exception: return HttpResponse( 'Ho bisogno di un valore numerico.', status=500) if object_id == "fat_progressivo" and fattura.tipo == "1": esistenti = Fattura.objects.filter( anno=fattura.anno, progressivo=int(object_value), tipo=fattura.tipo) if esistenti.count() > 0: return HttpResponse( "Esiste già una fattura con questo progressivo.", status=500) if object_id == "fat_data": parsed_date = parse_datestring(object_value) if parsed_date: object_value = parsed_date else: return HttpResponse( "Non sono riuscito a interpretare la data.", status=400) # print header_ids[object_id], "=", object_value setattr(fattura, header_ids[object_id], object_value) fattura.save() return HttpResponse('Header changed.', status=200) else: row_ids = { 'riga-desc-': 'descrizione', 'riga-qta-': 'qta', 'riga-prezzo-': 'prezzo', 'riga-iva-': 'iva' } row_numerici = ['riga-qta-', 'riga-prezzo-', 'riga-iva-'] for prefix in row_ids.keys(): if object_id.startswith(prefix): try: riga_id = int(object_id[len(prefix):]) riga = fattura.righe.get(id=riga_id) except: return HttpResponse( 'Non ho trovato la riga corrispondente a %s.' % object_id, status=500) if prefix in row_numerici: # print "Converto il valore in un numerico" # tolgo i punti delle migliaia e metto il punto come separatore decimali object_value = object_value.replace(".", "").replace( ",", ".") if object_value == '': object_value = 0 else: try: object_value = object_value.replace( ',', '.') if object_id.startswith('riga-prezzo-'): # print "Converto in Decimal:", object_value object_value = Decimal(object_value) else: # converto in int # print "Converto in int:", object_value object_value = int(object_value) except Exception as e: # print e return HttpResponse( 'Ho bisogno di un valore numerico.', status=500) # print "cambio la riga %d" % riga_id # print "imposto il valore %s" % object_value setattr(riga, row_ids[prefix], object_value) riga.save() return HttpResponse('OK.', status=200) return HttpResponse('Non conosco il campo %s.' % object_id, status=500) return HttpResponse('Azione sconosciuta.', status=500) # print "generate: ", request.user.has_perm('fatturazione.generate') # print "smalledit: ", request.user.has_perm('fatturazione.smalledit') # print "tipo: ", fattura.tipo # print "readonly: ", readonly return render( request, template_name, { "fattura": fattura, 'readonly': readonly, 'bigEdit': bigEdit, 'smallEdit': smallEdit, 'logo_url': settings.OWNER_LOGO, }, )
def coda(request, template_name='codapresenze/coda.html'): if not request.user.has_perm('codapresenze.view'): messages.error(request, 'Non hai accesso alla coda presenze.') return HttpResponseRedirect(reverse('tamCorse')) if request.method == 'POST': actinguser = request.user if request.user.has_perm( 'codapresenze.editall') and 'user' in request.POST: try: username = request.POST.get('user').strip() # print 'Changing user to %s' % username actinguser = User.objects.get(username=username) except: raise Exception("Error changing user") posizioneCorrente = CodaPresenze.objects.filter(utente=actinguser) messageParts = [] if 'dequeue' in request.POST or 'place' in request.POST: # mi disaccodo if posizioneCorrente: posizioneCorrente = posizioneCorrente[0] messageParts.append("Si disaccoda da %s." % posizioneCorrente.luogo) posizioneCorrente.delete() if 'place' in request.POST: # mi riaccodo nuovaPosizione = CodaPresenze( utente=actinguser, luogo=request.POST.get('place'), ) messageParts.append("Si accoda a %s." % nuovaPosizione.luogo) nuovaPosizione.save() if messageParts: if actinguser != request.user: messageParts.append('Effettuato da %s' % request.user) logAction('Q', description=" ".join(messageParts), user=actinguser) coda = CodaPresenze.objects.all().values('id', 'utente__username', 'luogo', 'data_accodamento') dthandler = lambda obj: obj.astimezone(tz_italy).isoformat() if isinstance( obj, datetime.datetime) else None coda = [{ "luogo": u["luogo"], "utente": u["utente__username"], "data": u['data_accodamento'], "id": u['id'] } for u in coda] codajson = json.dumps(coda, default=dthandler) if request.is_ajax(): return HttpResponse(codajson, content_type="application/json") piazze = getattr(settings, "CODA_PIAZZE", ['Abano', 'Montegrotto']) utenti = User.objects.filter(prenotazioni__isnull=True, is_active=True) if not request.user.is_superuser: utenti = utenti.filter( is_superuser=False) # solo i superuser vedono i superuser utenti = sorted(utenti, key=get_userkeys) return render( request, template_name, { 'codajson': codajson, "piazze": piazze, 'utenti': utenti, }, )
def genera_fatture(request, fatturazione): tipo = fatturazione.codice template_name = fatturazione.template_generazione manager = fatturazione.origine.objects order_by = fatturazione.order_by filtro = fatturazione.filtro keys = fatturazione.keys ids = request.POST.getlist("id") plurale = nomi_plurale[tipo] conducenti_ricevute = None anno = 0 # usato solo con le fatture consorzio if not ids: messages.error(request, "Devi selezionare qualche corsa da fatturare.") return HttpResponseRedirect(reverse("tamGenerazioneFatture")) data_generazione = parse_datestring(request.POST['data_generazione']) if fatturazione.ask_progressivo: # la generazione fatture consorzio richiede anno e progressivo - li controllo try: anno = int(request.POST.get("anno")) except: messages.error(request, "Seleziona un anno numerico.") return HttpResponseRedirect(reverse("tamGenerazioneFatture")) try: progressivo = int(request.POST.get("progressivo", 1)) except: messages.error(request, "Ho bisogno di un progressivo iniziale numerico.") return HttpResponseRedirect(reverse("tamGenerazioneFatture")) ultimo_progressivo = ultimoProgressivoFattura(anno, tipo) if ultimo_progressivo >= progressivo: messages.error(request, "Il progressivo è troppo piccolo, ho già la %s %s/%s." % ( nomi_fatture[tipo], anno, ultimo_progressivo)) return HttpResponseRedirect(reverse("tamGenerazioneFatture")) else: progressivo = 0 # nelle ricevute lo uso per ciclare progressivo_iniziale = progressivo lista = manager.filter(id__in=ids) lista = lista.filter(filtro) if manager.model == Viaggio: lista = lista.select_related("da", "a", "cliente", "conducente", "passeggero", "padre") elif manager.model == RigaFattura: lista = lista.select_related("viaggio__da", "viaggio__a", "viaggio__cliente", "viaggio__conducente", "viaggio__passeggero", 'fattura', 'conducente') if order_by is None: order_by = keys + ["data"] # ordino per chiave - quindi per data lista = lista.order_by(*order_by).all() if not lista: messages.error(request, "Tutte le %s selezionate sono già state fatturate." % plurale) return HttpResponseRedirect(reverse("tamGenerazioneFatture")) fatture = 0 lastKey = None for elemento in lista: key = [getattr(elemento, keyName) for keyName in keys] if lastKey != key: if lastKey != None: progressivo += 1 lastKey = key fatture += 1 elemento.key = key if fatturazione.ask_progressivo: elemento.codice_fattura = fatturazione.codice_fattura elemento.progressivo_fattura = progressivo elemento.anno_fattura = anno if request.method == "POST": if "generate" in request.POST: lastKey = None fattura = None fatture_generate = 0 for elemento in lista: if manager.model == RigaFattura: viaggio = elemento.viaggio else: viaggio = elemento if elemento.key != lastKey: if fattura: on_fattura_end(fattura, esente_iva) # TESTATA fattura = Fattura(tipo=tipo) data_fattura = data_generazione fattura.data = data_fattura if fatturazione.ask_progressivo: fattura.anno = anno fattura.progressivo = viaggio.progressivo_fattura if fatturazione.destinatario == "cliente": # popolo il destinatario della fattura if viaggio.cliente: fattura.cliente = viaggio.cliente fattura.emessa_a = viaggio.cliente.dati or viaggio.cliente.nome elif viaggio.passeggero: fattura.passeggero = viaggio.passeggero fattura.emessa_a = viaggio.passeggero.dati or viaggio.passeggero.nome elif fatturazione.destinatario == "consorzio": fattura.emessa_a = settings.DATI_CONSORZIO else: raise Exception( "%s non è un valido destinatario." % fatturazione.destinatario) if getattr(fatturazione, 'note', ""): fattura.note = fatturazione.note if fatturazione.mittente == "consorzio": fattura.emessa_da = settings.DATI_CONSORZIO elif fatturazione.mittente == "conducente": fattura.emessa_da = viaggio.conducente.dati or viaggio.conducente.nome else: raise Exception( "%s non è un valido mittente." % fatturazione.mittente) fattura.save() fatture_generate += 1 riga = 10 if callable(fatturazione.esente_iva): esente_iva = fatturazione.esente_iva(elemento) else: esente_iva = fatturazione.esente_iva lastKey = elemento.key # RIGHE dettaglio riga_fattura = RigaFattura() riga_fattura.riga = riga # progressivo riga riga_fattura.conducente = elemento.conducente if manager.model == RigaFattura: # fattura da altra fattura campi_da_riportare = "descrizione", "qta" for campo in campi_da_riportare: setattr(riga_fattura, campo, getattr(elemento, campo)) if not esente_iva and hasattr(fatturazione, 'iva_forzata'): # le fatture senza IVA per i conducenti che non le emettono, hanno IVA comunque riga_fattura.iva = fatturazione.iva_forzata else: # altrimenti riporto l'iva dalla fattura di origine riga_fattura.iva = elemento.iva if viaggio: # us price of the run if we have it riga_fattura.prezzo = viaggio.prezzo_netto( riga_fattura.iva) if viaggio.prezzo_sosta > 0: # se ho una sosta, aggiungo il prezzo della sosta in fattura riga_fattura.prezzo += viaggio.prezzo_sosta if viaggio.cliente: riga_fattura.note = viaggio.cliente.nome elif viaggio.passeggero: riga_fattura.note = viaggio.passeggero.nome else: riga_fattura.prezzo = elemento.prezzo # ... if or price of the item riga_fattura.riga_fattura_consorzio = elemento else: # fattura da un viaggio riga_fattura.descrizione = "%s-%s %s %dpax %s" % \ (viaggio.da, viaggio.a, viaggio.data.astimezone( tamdates.tz_italy).strftime( "%d/%m/%Y"), viaggio.numero_passeggeri, "taxi" if viaggio.esclusivo else "collettivo") riga_fattura.qta = 1 riga_fattura.iva = 0 if fatturazione.esente_iva else 10 riga_fattura.prezzo = viaggio.prezzo_netto( riga_fattura.iva) if viaggio.prezzo_sosta > 0: # se ho una sosta, aggiungo il prezzo della sosta in fattura riga_fattura.prezzo += viaggio.prezzo_sosta riga_fattura.descrizione += " + sosta" riga_fattura.viaggio = viaggio riga_fattura.fattura = fattura riga_fattura.save() riga += 10 if fattura: on_fattura_end(fattura, esente_iva) message = "Generate %d %s." % (fatture_generate, plurale) messages.success(request, message) logAction('C', description=message, user=request.user) return HttpResponseRedirect(reverse("tamGenerazioneFatture")) return render(request, template_name, { # riporto i valori che mi arrivano dalla selezione "anno": anno, "progressivo_iniziale": progressivo_iniziale, "lista": lista, "mediabundleJS": ('tamUI',), "mediabundleCSS": ('tamUI',), "singolare": nomi_fatture[tipo], "fatture": fatture, "plurale": plurale, # "error_message":error_message, 'conducenti_ricevute': conducenti_ricevute, 'data_generazione': data_generazione, 'fatturazione': fatturazione, 'PREZZO_VIAGGIO_NETTO': PREZZO_VIAGGIO_NETTO, }, )
def do_archiviazione(user, end_date): # if settings.DEBUG: # raise Exception("Per archiviare devi uscire dal DEBUG mode.") filtroViaggi = Q(data__lt=end_date, padre__isnull=True) to_archive = Viaggio.objects.select_related("da", "a", "cliente", "conducente", "passeggero").filter(filtroViaggi) # Optimizations: mi faccio dare solo i modelli che mi interessano # Rimovo l'ordinamento di default logAction("K", instance=user, description="Archiviazione fino al %s" % end_date, user=user) logger.debug("Archiviazione fino al %s cominciata" % end_date) # disabilita il log delle operazioni: cancello viaggi e cambio conducenti stopLog(Viaggio) stopLog(Conducente) ricordi = {} # ricordi[conducente_id] = {chiaveClassifica=valore} archiviati = 0 chunkSize = 500 total = to_archive.count() logger.debug(u"Archivio %d viaggi padre." % total) while to_archive: # split viaggi padre in chucks viaggi_chunk, to_archive = to_archive[:chunkSize], to_archive[chunkSize:] with transaction.atomic(): with transaction.atomic(using='archive'): for viaggiopadre in viaggi_chunk: archivio_viaggiopadre = archiveFromViaggio(viaggiopadre) daRicordareDelViaggio(ricordi, viaggiopadre) archivio_viaggiopadre.save() archiviati += 1 for figlio in viaggiopadre.viaggio_set.select_related("da", "a", "cliente", "conducente", "passeggero").order_by().all(): archivio_viaggiofiglio = archiveFromViaggio(figlio) archivio_viaggiofiglio.padre = archivio_viaggiopadre daRicordareDelViaggio(ricordi, figlio) archivio_viaggiofiglio.save() # archiviati += 1 viaggiopadre.delete() logger.debug("Modifico le classifiche e commit %d/%d" % (archiviati, total)) applyRicordi(ricordi) logger.debug("fine archiviazione") if archiviati: vacuum_db() logDaEliminare = ActionLog.objects.filter(data__lt=end_date) contaLog = logDaEliminare.count() if contaLog: logger.debug("Ora cancello tutti i vecchi LOG.") logDaEliminare.delete() vacuum_db(using='modellog') # riabilita il log delle operazioni startLog(Conducente) startLog(Viaggio) logger.debug("Archiviazione fino al %s completata." % end_date.strftime("%d/%m/%Y"))
def moveLogs(name='movelogs.job'): from django.contrib.contenttypes.models import ContentType from django.db import connections from modellog.actions import logAction print("Cominciamo a spostare") con = connections['default'] cursor = con.cursor() try: cursor.execute( "SELECT count(*) FROM tam_actionlog WHERE data>='2012-01-01'") # sposto solo dal 2012 except: print "no table actionlog" con.set_clean() return totalcount = cursor.fetchone()[0] print("Total logs:", totalcount) count = 0 chunksize = 500 oldPercent = None usersByID = {} ctypeByID = {} while True: cursor.execute( "SELECT * from tam_actionlog where data>='2012-01-01' order by data desc limit %d" % chunksize) con.set_clean() oldLogsChunk = cursor.fetchall() logs_to_delete = [] # lista degli ID da cancellare if not oldLogsChunk: break for oldlog in oldLogsChunk: user_id, content_type_id, object_id, action_type, data, pk, description = oldlog # @UnusedVariable if user_id in usersByID: user = usersByID[user_id] else: user = User.objects.get(pk=user_id) usersByID[user_id] = user if not content_type_id in ctypeByID: ct = ContentType.objects.get(id=content_type_id) ctypeByID[content_type_id] = ct else: ct = ctypeByID[content_type_id] ct_class = ct.model_class() try: instance = ct_class.objects.get(id=object_id) except ct_class.DoesNotExist: instance = None logAction(action=action_type, instance=instance, description=description, user=user, log_date=data) logs_to_delete.append(str(pk)) count += 1 percent = count * 100 / totalcount if logs_to_delete: delete_query = "delete from tam_actionlog where id in (%s)" % ",".join(logs_to_delete) # print delete_query cursor.execute(delete_query) con.commit() # transaction.commit(using="modellog") if oldPercent is None or percent >= oldPercent + 5: print("%s%%" % percent, end=' ') oldPercent = percent # break # fine del chunk print() print("Delete table") cursor.execute("DROP TABLE tam_actionlog") from tamArchive.tasks import vacuum_db vacuum_db() con.commit() print("Fine")
def do_archiviazione(user, end_date): # if settings.DEBUG: # raise Exception("Per archiviare devi uscire dal DEBUG mode.") filtroViaggi = Q(data__lt=end_date, padre__isnull=True) to_archive = Viaggio.objects.select_related( "da", "a", "cliente", "conducente", "passeggero").filter(filtroViaggi) # Optimizations: mi faccio dare solo i modelli che mi interessano # Rimovo l'ordinamento di default logAction("K", instance=user, description="Archiviazione fino al %s" % end_date, user=user) logger.debug("Archiviazione fino al %s cominciata" % end_date) # disabilita il log delle operazioni: cancello viaggi e cambio conducenti stopLog(Viaggio) stopLog(Conducente) ricordi = {} # ricordi[conducente_id] = {chiaveClassifica=valore} archiviati = 0 chunkSize = 500 total = to_archive.count() logger.debug(u"Archivio %d viaggi padre." % total) # to_archive = to_archive[:1] # TODO: temp debug 1 viaggio while to_archive: # split viaggi padre in chucks viaggi_chunk, to_archive = to_archive[:chunkSize], to_archive[ chunkSize:] with transaction.atomic(): with transaction.atomic(using='archive'): for viaggiopadre in viaggi_chunk: archivio_viaggiopadre = archiveFromViaggio(viaggiopadre) daRicordareDelViaggio(ricordi, viaggiopadre) archivio_viaggiopadre.save() archiviati += 1 for figlio in viaggiopadre.viaggio_set.select_related( "da", "a", "cliente", "conducente", "passeggero").order_by().all(): archivio_viaggiofiglio = archiveFromViaggio(figlio) archivio_viaggiofiglio.padre = archivio_viaggiopadre daRicordareDelViaggio(ricordi, figlio) archivio_viaggiofiglio.save() # archiviati += 1 viaggiopadre.delete() logger.debug("Modifico le classifiche e commit %d/%d" % (archiviati, total)) applyRicordi(ricordi) logger.debug("fine archiviazione") if archiviati: vacuum_db() logDaEliminare = ActionLog.objects.filter(data__lt=end_date) contaLog = logDaEliminare.count() if contaLog: logger.debug("Ora cancello tutti i vecchi LOG.") logDaEliminare.delete() vacuum_db(using='modellog') # riabilita il log delle operazioni startLog(Conducente) startLog(Viaggio) logger.debug("Archiviazione fino al %s completata." % end_date.strftime("%d/%m/%Y"))
def post(self, request, *args, **kwargs): context = self.get_context_data() form = context['form'] action = request.POST.get('action') if not context['can_edit']: return self.render_to_response( dict(message=u"Non hai permessi per modificare le presenze.", status=401, redirect_url='calendariopresenze-manage') ) if action == 'new': if not request.user.has_perm('calendariopresenze.add_calendar'): return self.render_to_response( dict(message=u"Non hai permessi per modificare le presenze.", status=401, redirect_url='calendariopresenze-manage') ) cal_fixed_start = None cal_fixed_end = None subname = None caldesc = None if 'type' in request.POST: try: caldesc = settings.CALENDAR_DESC[int(request.POST['type'])] if "subname" in request.POST: subname = request.POST['subname'] for subcal in caldesc['display_as']: if subcal['name'] == subname: cal_fixed_start = subcal['date_start'] cal_fixed_end = subcal['date_end'] break except ValueError: pass day = context['day'] conducente_id = int(request.POST['conducente']) conducente = Conducente.objects.get(id=conducente_id) calendar_type = int(request.POST['type']) if 'time_from' in request.POST: string_from = request.POST['time_from'] try: date_start = appendTimeToDate(day, string_from) except ValueError: return self.render_to_response( dict(message=u"Ora iniziale non valida.", status=400, redirect_url='calendariopresenze-manage') ) else: assert cal_fixed_start date_start = appendTimeFromRegex(day, cal_fixed_start) if 'time_to' in request.POST: string_to = request.POST['time_to'] try: date_end = appendTimeToDate(day, string_to) except ValueError: return self.render_to_response( dict(message=u"Ora finale non valida.", status=400, redirect_url='calendariopresenze-manage') ) else: assert cal_fixed_end date_end = appendTimeFromRegex(day, cal_fixed_end) calendar = Calendar( conducente=conducente, type=calendar_type, date_start=date_start, date_end=date_end, ) calendar.save() logAction('P', instance=calendar, description=u"Presenze: aggiunto {name} {calendar}".format( name=subname or caldesc['name'], calendar=calendar ) ) if request.is_ajax(): row_template = get_template('calendar/cal_row.html') # I use the context view, adding the things to render the row context.update(dict(element=calendar, calDesc=settings.CALENDAR_DESC[calendar.type], )) return HttpResponse(row_template.render(context, request), status=201) else: return HttpResponseRedirect( reverse('calendariopresenze-manage') + '?day=' + context['selected_day'] ) elif action == 'delete': if not request.user.has_perm('calendariopresenze.delete_calendar'): return self.render_to_response( dict(message=u"Non hai permessi per cancellare le presenze.", status=401, redirect_url='calendariopresenze-manage') ) try: calendar = Calendar.objects.get(id=request.POST['calendar_id']) except Calendar.DoesNotExist: return self.render_to_response( dict(message=u"Il calendario indicato non esiste più.", status=400, redirect_url='calendariopresenze-manage') ) caldesc = settings.CALENDAR_DESC[calendar.type] logAction('P', instance=calendar, description=u"Presenze: cancellato {name} {calendar}".format( name=caldesc['name'], calendar=calendar ) ) calendar.delete() return HttpResponse("ok", status=200) elif action == 'toggle': if not request.user.has_perm('calendariopresenze.toggle_calendarvalue'): return self.render_to_response( dict(message=u"Non hai permessi per modificare il valore dei calendari.", status=401, redirect_url='calendariopresenze-manage') ) try: calendar = Calendar.objects.get(id=request.POST['calendar_id']) except Calendar.DoesNotExist: return self.render_to_response( dict(message=u"Il calendario indicato non esiste più.", status=400, redirect_url='calendariopresenze-manage') ) caldesc = settings.CALENDAR_DESC[calendar.type] if 'toggle' not in caldesc: return self.render_to_response( dict(message=u"Valore del calendario non modificabile.", status=400, redirect_url='calendariopresenze-manage') ) old_value = calendar.value caldesc['toggle'](calendar) new_value = calendar.value logAction('P', instance=calendar, description=u"Presenze: variato {name} {calendar} da {old} a {new}".format( name=caldesc['name'], calendar=calendar, old=old_value, new=new_value, ) ) if request.is_ajax(): row_template = get_template('calendar/cal_row.html') # I use the context view, adding the things to rendere the row context.update(dict( element=calendar, calDesc=settings.CALENDAR_DESC[calendar.type] )) return HttpResponse(row_template.render(context, request), status=201) else: return HttpResponseRedirect( reverse('calendariopresenze-manage') + '?day=' + context['selected_day'] ) else: return self.render_to_response( dict(message=u"Azione sconosciuta.", status=400, redirect_url='calendariopresenze-manage') )
def coda(request, template_name='codapresenze/coda.html'): if not request.user.has_perm('codapresenze.view'): messages.error(request, 'Non hai accesso alla coda presenze.') return HttpResponseRedirect(reverse('tamCorse')) if request.method == 'POST': actinguser = request.user if request.user.has_perm('codapresenze.editall') and 'user' in request.POST: try: username = request.POST.get('user').strip() # print 'Changing user to %s' % username actinguser = User.objects.get(username=username) except: raise Exception("Error changing user") posizioneCorrente = CodaPresenze.objects.filter(utente=actinguser) messageParts = [] if 'dequeue' in request.POST or 'place' in request.POST: # mi disaccodo if posizioneCorrente: posizioneCorrente = posizioneCorrente[0] messageParts.append("Si disaccoda da %s." % posizioneCorrente.luogo) posizioneCorrente.delete() if 'place' in request.POST: # mi riaccodo nuovaPosizione = CodaPresenze( utente=actinguser, luogo=request.POST.get('place'), ) messageParts.append("Si accoda a %s." % nuovaPosizione.luogo) nuovaPosizione.save() if messageParts: if actinguser != request.user: messageParts.append('Effettuato da %s' % request.user) logAction('Q', description=" ".join(messageParts), user=actinguser) coda = CodaPresenze.objects.all().values('id', 'utente__username', 'luogo', 'data_accodamento') dthandler = lambda obj: obj.astimezone(tz_italy).isoformat() if isinstance(obj, datetime.datetime) else None coda = [{"luogo": u["luogo"], "utente": u["utente__username"], "data": u['data_accodamento'], "id": u['id'] } for u in coda] codajson = json.dumps(coda, default=dthandler) if request.is_ajax(): return HttpResponse(codajson, content_type="application/json") piazze = getattr(settings, "CODA_PIAZZE", ['Abano', 'Montegrotto']) utenti = User.objects.filter(prenotazioni__isnull=True, is_active=True) if not request.user.is_superuser: utenti = utenti.filter(is_superuser=False) # solo i superuser vedono i superuser utenti = sorted(utenti, key=get_userkeys) return render( request, template_name, { 'codajson': codajson, "piazze": piazze, 'utenti': utenti, }, )
def genera_fatture(request, fatturazione): tipo = fatturazione.codice template_name = fatturazione.template_generazione manager = fatturazione.origine.objects order_by = fatturazione.order_by filtro = fatturazione.filtro keys = fatturazione.keys ids = request.POST.getlist("id") plurale = nomi_plurale[tipo] conducenti_ricevute = None anno = 0 # usato solo con le fatture consorzio if not ids: messages.error(request, "Devi selezionare qualche corsa da fatturare.") return HttpResponseRedirect(reverse("tamGenerazioneFatture")) data_generazione = parse_datestring(request.POST['data_generazione']) if fatturazione.ask_progressivo: # la generazione fatture consorzio richiede anno e progressivo - li controllo try: anno = int(request.POST.get("anno")) except: messages.error(request, "Seleziona un anno numerico.") return HttpResponseRedirect(reverse("tamGenerazioneFatture")) try: progressivo = int(request.POST.get("progressivo", 1)) except: messages.error(request, "Ho bisogno di un progressivo iniziale numerico.") return HttpResponseRedirect(reverse("tamGenerazioneFatture")) ultimo_progressivo = ultimoProgressivoFattura(anno, tipo) if ultimo_progressivo >= progressivo: messages.error( request, "Il progressivo è troppo piccolo, ho già la %s %s/%s." % (nomi_fatture[tipo], anno, ultimo_progressivo)) return HttpResponseRedirect(reverse("tamGenerazioneFatture")) else: progressivo = 0 # nelle ricevute lo uso per ciclare progressivo_iniziale = progressivo lista = manager.filter(id__in=ids) lista = lista.filter(filtro) if manager.model == Viaggio: lista = lista.select_related("da", "a", "cliente", "conducente", "passeggero", "padre") elif manager.model == RigaFattura: lista = lista.select_related("viaggio__da", "viaggio__a", "viaggio__cliente", "viaggio__conducente", "viaggio__passeggero", 'fattura', 'conducente') if order_by is None: order_by = keys + ["data"] # ordino per chiave - quindi per data lista = lista.order_by(*order_by).all() if not lista: messages.error( request, "Tutte le %s selezionate sono già state fatturate." % plurale) return HttpResponseRedirect(reverse("tamGenerazioneFatture")) fatture = 0 lastKey = None for elemento in lista: key = [getattr(elemento, keyName) for keyName in keys] if lastKey != key: if lastKey != None: progressivo += 1 lastKey = key fatture += 1 elemento.key = key if fatturazione.ask_progressivo: elemento.codice_fattura = fatturazione.codice_fattura elemento.progressivo_fattura = progressivo elemento.anno_fattura = anno if request.method == "POST": if "generate" in request.POST: lastKey = None fattura = None fatture_generate = 0 for elemento in lista: if manager.model == RigaFattura: viaggio = elemento.viaggio else: viaggio = elemento if elemento.key != lastKey: if fattura: on_fattura_end(fattura, esente_iva) # TESTATA fattura = Fattura(tipo=tipo) data_fattura = data_generazione fattura.data = data_fattura if fatturazione.ask_progressivo: fattura.anno = anno fattura.progressivo = viaggio.progressivo_fattura if fatturazione.destinatario == "cliente": # popolo il destinatario della fattura if viaggio.cliente: fattura.cliente = viaggio.cliente fattura.emessa_a = viaggio.cliente.dati or viaggio.cliente.nome elif viaggio.passeggero: fattura.passeggero = viaggio.passeggero fattura.emessa_a = viaggio.passeggero.dati or viaggio.passeggero.nome elif fatturazione.destinatario == "consorzio": fattura.emessa_a = settings.DATI_CONSORZIO else: raise Exception("%s non è un valido destinatario." % fatturazione.destinatario) if getattr(fatturazione, 'note', ""): fattura.note = fatturazione.note if fatturazione.mittente == "consorzio": fattura.emessa_da = settings.DATI_CONSORZIO elif fatturazione.mittente == "conducente": fattura.emessa_da = viaggio.conducente.dati or viaggio.conducente.nome else: raise Exception("%s non è un valido mittente." % fatturazione.mittente) fattura.save() fatture_generate += 1 riga = 10 if callable(fatturazione.esente_iva): esente_iva = fatturazione.esente_iva(elemento) else: esente_iva = fatturazione.esente_iva lastKey = elemento.key # RIGHE dettaglio riga_fattura = RigaFattura() riga_fattura.riga = riga # progressivo riga riga_fattura.conducente = elemento.conducente if manager.model == RigaFattura: # fattura da altra fattura campi_da_riportare = "descrizione", "qta" for campo in campi_da_riportare: setattr(riga_fattura, campo, getattr(elemento, campo)) if not esente_iva and hasattr(fatturazione, 'iva_forzata'): # le fatture senza IVA per i conducenti che non le emettono, hanno IVA comunque riga_fattura.iva = fatturazione.iva_forzata else: # altrimenti riporto l'iva dalla fattura di origine riga_fattura.iva = elemento.iva if viaggio: # us price of the run if we have it riga_fattura.prezzo = viaggio.prezzo_netto( riga_fattura.iva) if viaggio.prezzo_sosta > 0: # se ho una sosta, aggiungo il prezzo della sosta in fattura riga_fattura.prezzo += viaggio.prezzo_sosta if viaggio.cliente: riga_fattura.note = viaggio.cliente.nome elif viaggio.passeggero: riga_fattura.note = viaggio.passeggero.nome else: riga_fattura.prezzo = elemento.prezzo # ... if or price of the item riga_fattura.riga_fattura_consorzio = elemento else: # fattura da un viaggio riga_fattura.descrizione = "%s-%s %s %dpax %s" % \ (viaggio.da, viaggio.a, viaggio.data.astimezone( tamdates.tz_italy).strftime( "%d/%m/%Y"), viaggio.numero_passeggeri, "taxi" if viaggio.esclusivo else "collettivo") riga_fattura.qta = 1 riga_fattura.iva = 0 if fatturazione.esente_iva else 10 riga_fattura.prezzo = viaggio.prezzo_netto( riga_fattura.iva) if viaggio.prezzo_sosta > 0: # se ho una sosta, aggiungo il prezzo della sosta in fattura riga_fattura.prezzo += viaggio.prezzo_sosta riga_fattura.descrizione += " + sosta" riga_fattura.viaggio = viaggio riga_fattura.fattura = fattura riga_fattura.save() riga += 10 if fattura: on_fattura_end(fattura, esente_iva) message = "Generate %d %s." % (fatture_generate, plurale) messages.success(request, message) logAction('C', description=message, user=request.user) return HttpResponseRedirect(reverse("tamGenerazioneFatture")) return render( request, template_name, { # riporto i valori che mi arrivano dalla selezione "anno": anno, "progressivo_iniziale": progressivo_iniziale, "lista": lista, "mediabundleJS": ('tamUI', ), "mediabundleCSS": ('tamUI', ), "singolare": nomi_fatture[tipo], "fatture": fatture, "plurale": plurale, # "error_message":error_message, 'conducenti_ricevute': conducenti_ricevute, 'data_generazione': data_generazione, 'fatturazione': fatturazione, 'PREZZO_VIAGGIO_NETTO': PREZZO_VIAGGIO_NETTO, }, )