mirror of
https://github.com/AdrienHallet/HaitiWater.git
synced 2026-11-10 00:06:02 +00:00
521 lines
20 KiB
Python
521 lines
20 KiB
Python
import re
|
|
|
|
from django.core.cache import cache
|
|
|
|
from ..api.add_table import *
|
|
from ..api.edit_table import *
|
|
from ..log.utils import *
|
|
from ..utils.get_data import is_user_zone, is_user_fountain, get_outlets
|
|
from ..water_network.models import ElementType, ElementStatus
|
|
|
|
success_200 = HttpResponse(status=200)
|
|
|
|
|
|
def graph(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
json_object = {"jsonarray": []}
|
|
|
|
export_format = request.GET.get('type', None)
|
|
if export_format == "consumer_gender_pie":
|
|
json_object["jsonarray"].append({'label': "Femmes", 'data': 0})
|
|
json_object["jsonarray"].append({'label': "Hommes", 'data': 0})
|
|
json_object["jsonarray"].append({'label': "Autres", 'data': 0})
|
|
|
|
consumers = None
|
|
if is_user_fountain(request):
|
|
consumers = Consumer.objects.filter(water_outlet__id__in=request.user.profile.outlets)
|
|
elif is_user_zone(request):
|
|
consumers = Consumer.objects.filter(water_outlet__zone__name__in=request.user.profile.zone.subzones)
|
|
|
|
for consumer in consumers:
|
|
if consumer.gender == "F" or consumer.gender == "Femme":
|
|
json_object['jsonarray'][0]['data'] += 1 # One more women
|
|
elif consumer.gender == "M" or consumer.gender == "Homme":
|
|
json_object['jsonarray'][1]['data'] += 1 # One more man
|
|
else:
|
|
json_object['jsonarray'][2]['data'] += 1 # One more other
|
|
|
|
if export_format == "average_monthly_volume_per_zone":
|
|
elements = []
|
|
data = []
|
|
|
|
if is_user_fountain(request):
|
|
for outlet in Element.objects.filter(id__in=request.user.profile.outlets):
|
|
elements.append(outlet.name)
|
|
|
|
total = 0
|
|
no_data = True
|
|
for report in Report.objects.filter(water_outlet=outlet):
|
|
if report.was_active and report.has_data:
|
|
no_data = False
|
|
total += report.quantity_distributed
|
|
|
|
data.append(total if not no_data else None)
|
|
|
|
elif is_user_zone(request):
|
|
for zone in Zone.objects.filter(name__in=request.user.profile.zone.subzones):
|
|
elements.append(zone.name)
|
|
|
|
total = 0
|
|
no_data = True
|
|
for report in Report.objects.filter(water_outlet__zone__name__in=zone.subzones):
|
|
if report.was_active and report.has_data:
|
|
no_data = False
|
|
total += report.quantity_distributed
|
|
|
|
data.append(total if not no_data else None)
|
|
|
|
json_object["jsonarray"].append({"label": elements, "data": data})
|
|
|
|
return HttpResponse(json.dumps(json_object))
|
|
|
|
|
|
def gis_infos(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
if request.method == "GET":
|
|
locations = None
|
|
if is_user_fountain(request):
|
|
locations = Location.objects.filter(elem_id__in=request.user.profile.outlets)
|
|
elif is_user_zone(request):
|
|
locations = Location.objects.filter(elem__zone__name__in=request.user.profile.zone.subzones)
|
|
|
|
markers = request.GET.get("marker", None)
|
|
if markers == "fountain":
|
|
locations = locations.filter(elem__type=ElementType.FOUNTAIN.name)
|
|
elif markers == "kiosk":
|
|
locations = locations.filter(elem__type=ElementType.KIOSK.name)
|
|
elif markers == "individual":
|
|
locations = locations.filter(elem__type=ElementType.INDIVIDUAL.name)
|
|
elif markers == "not in service":
|
|
locations = locations.exclude(elem__status=ElementStatus.OK.name)
|
|
|
|
results = {}
|
|
for location in locations:
|
|
results[location.elem.id] = [location.elem.name, location.json_representation]
|
|
return HttpResponse(json.dumps(results))
|
|
|
|
elif request.method == "POST":
|
|
elem_id = request.GET.get("id", None)
|
|
elem = Element.objects.filter(id=elem_id).first()
|
|
if elem is None:
|
|
return HttpResponse("Impossible de trouver l'élément demandé", status=400)
|
|
elif not has_access(elem, request):
|
|
return HttpResponse("Vous n'avez pas les droits sur cet élément de réseau", status=403)
|
|
|
|
action = request.GET.get("action", None)
|
|
if action == "add":
|
|
return add_location_element(request, elem)
|
|
elif action == "remove":
|
|
loc = Location.objects.filter(elem_id=elem_id).first()
|
|
if loc is None:
|
|
return HttpResponse("Impossible de trouver l'élément demandé", status=400)
|
|
|
|
log_element(loc, request)
|
|
loc.delete()
|
|
return success_200
|
|
else:
|
|
return HttpResponse("Impossible de traiter cette requête", status=400)
|
|
|
|
|
|
# https://datatables.net/manual/server-side
|
|
def table(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
params = parse(request)
|
|
table_name = params["table_name"]
|
|
last_draw = request.GET.get('draw', "0") # 1 ?
|
|
json_object = {
|
|
"draw": str(int(last_draw) + 1),
|
|
"editable": True, # custom field, true to display edit/delete buttons
|
|
"data": []
|
|
}
|
|
|
|
cache_key = table_name + request.user.username
|
|
cache_result = cache.get(cache_key) if table_name != "payment" else None
|
|
|
|
if cache_result:
|
|
result = json.loads(cache_result)
|
|
cache.touch(cache_key, 60)
|
|
elif table_name == "water_element":
|
|
if is_user_fountain(request):
|
|
json_object["editable"] = False
|
|
result = get_water_elements(request)
|
|
elif table_name == "consumer":
|
|
result = get_consumer_elements(request)
|
|
elif table_name == "zone":
|
|
if is_user_fountain(request):
|
|
return HttpResponse("Vous ne pouvez pas accéder à ces informations", status=403)
|
|
result = get_zone_elements(request)
|
|
elif table_name == "manager":
|
|
if is_user_fountain(request):
|
|
return HttpResponse("Vous ne pouvez pas accéder à ces informations", status=403)
|
|
result = get_manager_elements(request)
|
|
elif table_name == "report":
|
|
if is_user_zone(request):
|
|
return HttpResponse("Vous ne pouvez pas accéder à ces informations", status=403)
|
|
result = get_last_reports(request)
|
|
elif table_name == "ticket":
|
|
result = get_ticket_elements(request)
|
|
elif table_name == "logs":
|
|
result = get_logs_elements(request, archived=False)
|
|
elif table_name == "logs_history":
|
|
result = get_logs_elements(request, archived=True)
|
|
elif table_name == "payment":
|
|
if is_user_fountain(request):
|
|
json_object["editable"] = False
|
|
result = get_payment_elements(request)
|
|
if result is None:
|
|
return success_200
|
|
else:
|
|
return HttpResponse("Impossible de charger la table demandée (" + table_name + ").", status=404)
|
|
|
|
if result is None:
|
|
return HttpResponse("Problème à la récupération des données", status=400)
|
|
|
|
cache.set(cache_key, json.dumps(result), 60)
|
|
json_object["recordsTotal"] = len(result)
|
|
|
|
filtered = filter_search(params, result)
|
|
|
|
if table_name == "logs" or table_name == "logs_history" or table_name == "report":
|
|
if len(filtered) > 1:
|
|
keys = list(filtered[0].keys())
|
|
final = sorted(filtered, key=lambda x: x[keys[params["column_ordered"]]],
|
|
reverse=params["type_order"] != "asc")
|
|
else:
|
|
final = filtered
|
|
else:
|
|
final = sorted(filtered, key=lambda x: x[params["column_ordered"]],
|
|
reverse=params["type_order"] != "asc")
|
|
|
|
if params["length_max"] == -1:
|
|
json_object["data"] = final
|
|
else:
|
|
start = params["start"]
|
|
stop = start + params["length_max"]
|
|
json_object["data"] = final[start:stop]
|
|
|
|
json_object["recordsFiltered"] = len(final)
|
|
return HttpResponse(json.dumps(json_object), status=200)
|
|
|
|
|
|
def add_element(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
element = request.POST.get("table", "")
|
|
|
|
cache_key = element + request.user.username
|
|
cache.delete(cache_key)
|
|
|
|
if element == "water_element":
|
|
return add_network_element(request)
|
|
elif element == "consumer":
|
|
return add_consumer_element(request)
|
|
elif element == "zone":
|
|
return add_zone_element(request)
|
|
elif element == "manager":
|
|
cache_key = "water_element" + request.user.username
|
|
cache.delete(cache_key)
|
|
return add_collaborator_element(request)
|
|
elif element == "ticket":
|
|
return add_ticket_element(request)
|
|
elif element == "payment":
|
|
return add_payment_element(request)
|
|
else:
|
|
return HttpResponse("Impossible d'ajouter l'élément " + element, status=400)
|
|
|
|
|
|
def remove_element(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
element = request.POST.get("table", "")
|
|
|
|
cache_key = element + request.user.username
|
|
cache.delete(cache_key)
|
|
|
|
if element == "water_element":
|
|
element_id = request.POST.get("id", None)
|
|
|
|
consumers = Consumer.objects.filter(water_outlet=element_id)
|
|
if len(consumers) > 0:
|
|
return HttpResponse("Vous ne pouvez pas supprimer cet élément, il est encore attribué à " +
|
|
"des consommateurs", status=400)
|
|
|
|
elem_delete = Element.objects.filter(id=element_id).first()
|
|
if elem_delete is None:
|
|
return HttpResponse("Impossible de supprimer cet élément, il n'existe pas", status=400)
|
|
elif not has_access(elem_delete, request):
|
|
return HttpResponse("Impossible de supprimer cet élément, vous n'avez pas les droits", status=403)
|
|
|
|
transaction = Transaction(user=request.user)
|
|
if not is_same(elem_delete, request.user):
|
|
transaction.save()
|
|
elem_delete.log_delete(transaction)
|
|
|
|
elem_delete.delete()
|
|
|
|
tickets = Ticket.objects.filter(water_outlet=element_id)
|
|
for t in tickets:
|
|
if not is_same(t, request.user):
|
|
t.log_delete(transaction)
|
|
t.delete()
|
|
|
|
for user in User.objects.filter(profile__outlets__contains=[str(element_id)]):
|
|
old = user.profile.infos()
|
|
user.profile.outlets.remove(str(element_id))
|
|
user.save()
|
|
user.profile.log_edit(old, transaction)
|
|
|
|
return success_200
|
|
|
|
elif element == "consumer":
|
|
consumer_id = request.POST.get("id", None)
|
|
to_delete = Consumer.objects.filter(id=consumer_id).first()
|
|
if to_delete is None:
|
|
return HttpResponse("Impossible de supprimer ce consommateur, il n'existe pas", status=400)
|
|
elif not has_access(to_delete.water_outlet, request):
|
|
return HttpResponse("Impossible de supprimer ce consommateur, vous n'avez pas les droits", status=403)
|
|
|
|
log_element(to_delete, request)
|
|
to_delete.delete()
|
|
|
|
return HttpResponse({"draw": request.POST.get("draw", 0) + 1}, status=200)
|
|
|
|
elif element == "manager":
|
|
if request.user.profile.zone is None:
|
|
return HttpResponse("Vous n'êtes pas connecté en tant que gestionnaire de zone", status=403)
|
|
|
|
manager_id = request.POST.get("id", None)
|
|
to_delete = User.objects.filter(username=manager_id).first()
|
|
if to_delete is None:
|
|
return HttpResponse("Impossible de supprimer cet utilisateur, il n'existe pas", status=400)
|
|
if to_delete.id == 1 or to_delete.id == 2: # IDs 1 and 2 are superuser and admin, should not be removed
|
|
return HttpResponse("Impossible de supprimer cet utilisateur, il est nécéssaire au fonctionnement de"
|
|
" l'application. Vous pouvez cependant le modifier", status=400)
|
|
elif to_delete.profile.zone and to_delete.profile.zone.name not in request.user.profile.zone.subzones:
|
|
return HttpResponse("Impossible de supprimer cet utilisateur, vous n'avez pas les droits", status=403)
|
|
else:
|
|
for outlet_id in to_delete.profile.outlets:
|
|
outlet = Element.objects.filter(id=outlet_id).first()
|
|
if outlet is None:
|
|
return HttpResponse("Impossible de supprimer cet utilisateur, " +
|
|
"il est lié à une fontaine dont la zone n'existe pas", status=400)
|
|
elif outlet.zone.name not in request.user.profile.zone.subzones:
|
|
return HttpResponse("Impossible de supprimer cet utilisateur, vous n'avez pas les droits",
|
|
status=403)
|
|
|
|
log_element(to_delete.profile, request)
|
|
to_delete.delete()
|
|
|
|
cache_key = "water_element" + request.user.username
|
|
cache.delete(cache_key)
|
|
|
|
return HttpResponse({"draw": request.POST.get("draw", 0) + 1}, status=200)
|
|
|
|
elif element == "ticket":
|
|
ticket_id = request.POST.get("id", None)
|
|
to_delete = Ticket.objects.filter(id=ticket_id).first()
|
|
if to_delete is None:
|
|
return HttpResponse("Impossible de supprimer ce ticket, il n'existe pas", status=400)
|
|
elif not has_access(to_delete.water_outlet, request):
|
|
return HttpResponse("Impossible de supprimer ce ticket, vous n'avez pas les droits", status=403)
|
|
|
|
log_element(to_delete, request)
|
|
to_delete.delete()
|
|
|
|
return HttpResponse({"draw": request.POST.get("draw", 0) + 1}, status=200)
|
|
|
|
elif element == "payment":
|
|
payment_id = request.POST.get("id", None)
|
|
to_delete = Payment.objects.filter(id=payment_id).first()
|
|
if to_delete is None:
|
|
return HttpResponse("Impossible de supprimer ce ticket, il n'existe pas", status=400)
|
|
elif not has_access(to_delete.water_outlet, request):
|
|
return HttpResponse("Impossible de supprimer ce ticket, vous n'avez pas les droits", status=403)
|
|
|
|
log_element(to_delete, request)
|
|
to_delete.delete()
|
|
|
|
return HttpResponse({"draw": request.POST.get("draw", 0) + 1}, status=200)
|
|
|
|
elif element == "zone":
|
|
if request.user.profile.zone is None:
|
|
return HttpResponse("Vous n'êtes pas connecté en tant que gestionnaire de zone", status=403)
|
|
|
|
zone_id = request.POST.get("id", None)
|
|
to_delete = Zone.objects.filter(id=zone_id).first()
|
|
if to_delete is None:
|
|
return HttpResponse("Impossible de supprimer cette zone, elle n'existe pas", status=400)
|
|
if to_delete.id == 1:
|
|
return HttpResponse("Impossible de supprimer cette zone, elle est essentielle au fonctionnement de "
|
|
"l'application. Vous pouvez cependant la modifier.", status=400)
|
|
elif to_delete.name not in request.user.profile.zone.subzones:
|
|
return HttpResponse("Impossible de supprimer cette zone, vous n'avez pas les droits", status=403)
|
|
|
|
if len(to_delete.subzones) > 1:
|
|
return HttpResponse("Vous ne pouvez pas supprimer cette zone, elle contient encore" +
|
|
" d'autres zones", status=400)
|
|
elements = Element.objects.filter(zone=zone_id)
|
|
if len(elements) > 0:
|
|
return HttpResponse("Vous ne pouvez pas supprimer cette zone, elle contient encore" +
|
|
" des élements du réseau", status=400)
|
|
users = User.objects.filter(profile__zone=to_delete)
|
|
if len(users) > 0:
|
|
return HttpResponse("Vous ne pouvez pas supprimer cette zone, elle est encore attribuée à" +
|
|
" un gestionnaire de zone", status=400)
|
|
|
|
transaction = Transaction(user=request.user)
|
|
for zone in Zone.objects.filter(subzones__contains=[to_delete.name]):
|
|
old = zone.infos()
|
|
zone.subzones.remove(str(to_delete.name))
|
|
zone.save()
|
|
zone.log_edit(old, transaction)
|
|
|
|
if not is_same(to_delete, request.user):
|
|
to_delete.log_delete(transaction)
|
|
transaction.save()
|
|
to_delete.delete()
|
|
|
|
return HttpResponse({"draw": request.POST.get("draw", 0) + 1}, status=200)
|
|
|
|
else:
|
|
return HttpResponse("Impossible de trouver l'élement " + element, status=400)
|
|
|
|
|
|
def edit_element(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
element = request.POST.get("table", "")
|
|
|
|
cache_key = element + request.user.username
|
|
cache.delete(cache_key)
|
|
|
|
if not element:
|
|
element = request.GET.get("table", None)
|
|
if element == "water_element":
|
|
return edit_water_element(request)
|
|
elif element == "consumer":
|
|
return edit_consumer(request)
|
|
elif element == "zone":
|
|
return edit_zone(request)
|
|
elif element == "ticket":
|
|
return edit_ticket(request)
|
|
elif element == "manager":
|
|
cache_key = "water_element" + request.user.username
|
|
cache.delete(cache_key)
|
|
return edit_manager(request)
|
|
elif element == "payment":
|
|
return edit_payment(request)
|
|
elif element == "report":
|
|
return edit_report(request)
|
|
else:
|
|
return HttpResponse("Impossible d'éditer la table " + element + ", elle n'est pas reconnue", status=400)
|
|
|
|
|
|
def details(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
table_name = request.GET.get("table", None)
|
|
if table_name == "payment":
|
|
return get_payment_details(request)
|
|
elif table_name == "water_element":
|
|
return get_details_network(request)
|
|
else:
|
|
return HttpResponse("Impossible d'obtenir des détails pour la table " + table_name +
|
|
", elle n'est pas reconnue", status=400)
|
|
|
|
|
|
def outlets(request):
|
|
if not request.user.is_authenticated:
|
|
return HttpResponse("Vous n'êtes pas connecté", status=403)
|
|
|
|
result = {"data": get_outlets(request)}
|
|
return HttpResponse(json.dumps(result))
|
|
|
|
|
|
def compute_logs(request):
|
|
id_val = request.GET.get("id", -1)
|
|
action = request.GET.get("action", None)
|
|
if id_val == -1 or action is None:
|
|
return HttpResponse("Impossible de valider/annuler ce changement", status=400)
|
|
|
|
cache_key = "logs" + request.user.username
|
|
cache_key2 = "logs_history" + request.user.username
|
|
|
|
transaction = Transaction.objects.filter(id=id_val).first()
|
|
if transaction is None:
|
|
return HttpResponse("Impossible d'identifier le changement", status=400)
|
|
|
|
if action == "accept":
|
|
log_finished(transaction, "ACCEPT")
|
|
cache.delete(cache_key)
|
|
cache.delete(cache_key2)
|
|
return success_200
|
|
elif action == "revert":
|
|
roll_back(transaction)
|
|
cache.delete(cache_key)
|
|
cache.delete(cache_key2)
|
|
return success_200
|
|
else:
|
|
return HttpResponse("Action non reconnue", status=400)
|
|
|
|
|
|
def log_element(element, request):
|
|
if not is_same(element, request.user):
|
|
transaction = Transaction(user=request.user)
|
|
transaction.save()
|
|
element.log_delete(transaction)
|
|
|
|
|
|
def is_same(element, user):
|
|
log = Log.objects.filter(action="ADD", column_name="ID", table_name=element._meta.model_name,
|
|
new_value=element.id, transaction__archived=False).first()
|
|
if log is None:
|
|
return False
|
|
|
|
transaction = log.transaction
|
|
if transaction.user != user or transaction.archived:
|
|
return False
|
|
|
|
all_logs = Log.objects.filter(transaction=transaction)
|
|
for log in all_logs:
|
|
log.delete()
|
|
|
|
transaction.delete()
|
|
return True
|
|
|
|
|
|
def parse(request):
|
|
column_regex = re.compile('order\[\d*\]\[column\]')
|
|
dir_regex = re.compile('order\[\d*\]\[dir\]')
|
|
|
|
columns = list(filter(column_regex.match, dict(request.GET).keys()))
|
|
dirs = list(filter(dir_regex.match, dict(request.GET).keys()))
|
|
|
|
searchable_cols = []
|
|
for i in range(25):
|
|
if request.GET.get('columns[' + str(i) + '][searchable]', False):
|
|
searchable_cols.append(i)
|
|
|
|
params = {
|
|
"table_name": request.GET.get('name', None),
|
|
"length_max": int(request.GET.get('length', 10)),
|
|
"start": int(request.GET.get('start', 0)),
|
|
"column_ordered": int(request.GET.get(columns[0], 0)),
|
|
"type_order": request.GET.get(dirs[0], 'asc'),
|
|
"search": request.GET.get('search[value]', ""),
|
|
"searchable": searchable_cols,
|
|
"month_wanted": request.GET.get("month", "none")
|
|
}
|
|
|
|
return params
|