def update_single_unit_from_bulk(self, user, org_unit, *, validation_status, org_unit_type_id, groups_ids_added, groups_ids_removed): """Used within the context of a bulk operation""" original_copy = deepcopy(org_unit) if validation_status is not None: org_unit.validation_status = validation_status if org_unit_type_id is not None: org_unit_type = OrgUnitType.objects.get(pk=org_unit_type_id) org_unit.org_unit_type = org_unit_type if groups_ids_added is not None: for group_id in groups_ids_added: group = Group.objects.get(pk=group_id) group.org_units.add(org_unit) if groups_ids_removed is not None: for group_id in groups_ids_removed: group = Group.objects.get(pk=group_id) group.org_units.remove(org_unit) org_unit.save() audit_models.log_modification(original_copy, org_unit, source=audit_models.ORG_UNIT_API_BULK, user=user)
def post(self, request, format=None): """UPDATE""" if request.FILES: main_file = request.FILES["xml_submission_file"] xml = main_file.read() soup = Soup(xml, "xml") # should we add form_id criteria or instanceID is enough ? for c in soup: if c.attrs.get("iasoInstance", None): instanceid = c.attrs["iasoInstance"] try: user_id = soup.meta.editUserID.contents[0].strip() user = User.objects.filter(id=user_id).first() except: user = None original = Instance.objects.get(id=instanceid) instance = Instance.objects.get(id=instanceid) instance.file = main_file instance.json = {} instance.save() # copy pasted from the create try: instance.get_and_save_json_of_xml() try: instance.convert_location_from_field() instance.convert_device() except ValueError as error: print(error) except: pass for file_name in request.FILES: if file_name != "xml_submission_file": fi = InstanceFile() fi.file = request.FILES[file_name] fi.instance_id = instance.id fi.name = file_name fi.save() log_modification(original, instance, source=INSTANCE_API, user=user) return Response({"result": "success"}, status=status.HTTP_201_CREATED) return Response()
def patch(self, request, pk=None): original = get_object_or_404(Instance.objects.with_status(), pk=pk) instance = get_object_or_404(Instance.objects.with_status(), pk=pk) self.check_object_permissions(request, instance) instance_serializer = InstanceSerializer( instance, data=request.data, partial=True, context={"request": self.request}) instance_serializer.is_valid(raise_exception=True) instance_serializer.save() log_modification(original, instance, INSTANCE_API, user=request.user) return Response(instance.as_full_model())
def change_password(request): if request.method == "POST": form = PasswordChangeForm(request.user, request.POST) if form.is_valid(): original_user = copy(request.user) user = form.save() user.profile.password_reset = False user.save() update_session_auth_hash(request, user) log_modification(original_user, user, PASSWORD_API, original_user) messages.success(request, _("Your password was successfully updated")) return redirect("/dashboard/home") else: form = PasswordChangeForm(request.user) return render(request, "dashboard/change_password.html", {"form": form})
def partial_update(self, request, pk=None): link = get_object_or_404(Link, id=pk) original_copy = deepcopy(link) validated = request.data.get("validated", None) if validated is not None: link.validated = validated if validated == True: link.validator = request.user if validated == False: link.validator = None log_modification(original_copy, link, source=ORG_UNIT_API, user=request.user) link.save() res = link.as_dict() return Response(res)
def create_org_unit(self, request): errors = [] org_unit = OrgUnit() profile = request.user.iaso_profile if request.user: org_unit.creator = request.user name = request.data.get("name", None) version_id = request.data.get("version_id", None) if version_id: authorized_ids = list( SourceVersion.objects.filter( data_source__projects__account=profile.account). values_list("id", flat=True)) if version_id in authorized_ids: org_unit.version_id = version_id else: errors.append({ "errorKey": "version_id", "errorMessage": _("Unauthorized version id") + ": " + str(version_id) + " | authorized ones are " + str(authorized_ids), }) else: org_unit.version = profile.account.default_version if not name: errors.append({ "errorKey": "name", "errorMessage": _("Org unit name is required") }) org_unit.name = name source_ref = request.data.get("source_ref", None) if source_ref: org_unit.source_ref = source_ref org_unit.short_name = request.data.get("short_name", "") org_unit.source = request.data.get("source", "") validation_status = request.data.get("validation_status", None) if validation_status is None: org_unit.validation_status = OrgUnit.VALIDATION_NEW else: org_unit.validation_status = validation_status org_unit_type_id = request.data.get("org_unit_type_id", None) parent_id = request.data.get("parent_id", None) groups = request.data.get("groups", []) org_unit.aliases = request.data.get("aliases", []) geom = request.data.get("geom") if geom: try: g = GEOSGeometry(json.dumps(geom)) org_unit.geom = g org_unit.simplified_geom = g # maybe think of a standard simplification here? except Exception as e: errors.append({ "errorKey": "geom", "errorMessage": _("Can't parse geom") }) latitude = request.data.get("latitude") longitude = request.data.get("longitude") altitude = request.data.get("altitude", 0) if latitude and longitude: org_unit.location = Point(x=longitude, y=latitude, z=altitude, srid=4326) if not org_unit_type_id: errors.append({ "errorKey": "org_unit_type_id", "errorMessage": _("Org unit type is required") }) if parent_id: parent_org_unit = get_object_or_404(self.get_queryset(), id=parent_id) if org_unit.version_id != parent_org_unit.version_id: errors.append({ "errorKey": "parent_id", "errorMessage": _("Parent is not in the same version") }) org_unit.parent = parent_org_unit if not errors: org_unit.save() else: return Response(errors, status=400) org_unit_type = get_object_or_404(OrgUnitType, id=org_unit_type_id) org_unit.org_unit_type = org_unit_type new_groups = [] for group in groups: temp_group = get_object_or_404(Group, id=group) new_groups.append(temp_group) org_unit.groups.set(new_groups) audit_models.log_modification(None, org_unit, source=audit_models.ORG_UNIT_API, user=request.user) org_unit.save() res = org_unit.as_dict_with_parents() return Response(res)
def partial_update(self, request, pk=None): errors = [] org_unit = get_object_or_404(self.get_queryset(), id=pk) self.check_object_permissions(request, org_unit) original_copy = deepcopy(org_unit) name = request.data.get("name", None) if not name: errors.append({ "errorKey": "name", "errorMessage": _("Org unit name is required") }) org_unit.name = name org_unit.short_name = request.data.get("short_name", "") org_unit.source = request.data.get("source", "") validation_status = request.data.get("validation_status", None) if validation_status is None: org_unit.validation_status = OrgUnit.VALIDATION_NEW else: org_unit.validation_status = validation_status geo_json = request.data.get("geo_json", None) catchment = request.data.get("catchment", None) simplified_geom = request.data.get("simplified_geom", None) org_unit_type_id = request.data.get("org_unit_type_id", None) parent_id = request.data.get("parent_id", None) groups = request.data.get("groups") if False: # simplified geom shape editing is currently disabled if geo_json and geo_json["features"][0]["geometry"] and geo_json[ "features"][0]["geometry"]["coordinates"]: if len(geo_json["features"][0]["geometry"] ["coordinates"]) == 1: org_unit.simplified_geom = Polygon( geo_json["features"][0]["geometry"]["coordinates"][0]) else: # DB has a single Polygon, refuse if we have more, or less. return Response( "Only one polygon should be saved in the geo_json shape", status=status.HTTP_400_BAD_REQUEST) elif simplified_geom: org_unit.simplified_geom = simplified_geom else: org_unit.simplified_geom = None if False: # catchment shape editing is currently disabled if (catchment and catchment["features"][0]["geometry"] and catchment["features"][0]["geometry"]["coordinates"]): if len(catchment["features"][0]["geometry"] ["coordinates"]) == 1: org_unit.catchment = Polygon( catchment["features"][0]["geometry"]["coordinates"][0]) else: # DB has a single Polygon, refuse if we have more, or less. return Response( "Only one polygon should be saved in the catchment shape", status=status.HTTP_400_BAD_REQUEST) else: org_unit.catchment = None latitude = request.data.get("latitude", None) longitude = request.data.get("longitude", None) if latitude and longitude: # TODO: remove this mess once the frontend handles altitude edition if "altitude" in request.data: # provided explicitly altitude = request.data["altitude"] elif org_unit.location is not None: # not provided but we have a current location: keep altitude altitude = org_unit.location.z else: # no location yet, no altitude provided, set to 0 altitude = 0 org_unit.location = Point(x=longitude, y=latitude, z=altitude, srid=4326) else: org_unit.location = None org_unit.aliases = request.data.get("aliases", "") if org_unit_type_id: org_unit_type = get_object_or_404(OrgUnitType, id=org_unit_type_id) org_unit.org_unit_type = org_unit_type else: errors.append({ "errorKey": "org_unit_type_id", "errorMessage": _("Org unit type is required") }) if parent_id: parent_org_unit = get_object_or_404(self.get_queryset(), id=parent_id) org_unit.parent = parent_org_unit else: org_unit.parent = None new_groups = [] for group in groups: temp_group = get_object_or_404(Group, id=group) new_groups.append(temp_group) org_unit.groups.set(new_groups) audit_models.log_modification(original_copy, org_unit, source=audit_models.ORG_UNIT_API, user=request.user) if not errors: org_unit.save() res = org_unit.as_dict_with_parents() res["geo_json"] = None res["catchment"] = None if org_unit.simplified_geom or org_unit.catchment: queryset = self.get_queryset().filter(id=org_unit.id) if org_unit.simplified_geom: res["geo_json"] = geojson_queryset( queryset, geometry_field="simplified_geom") if org_unit.catchment: res["catchment"] = geojson_queryset( queryset, geometry_field="catchment") return Response(res) else: return Response(errors, status=400)
def soft_delete(self, user: typing.Optional[User] = None): with transaction.atomic(): original = copy(self) self.deleted = True self.save() log_modification(original, self, INSTANCE_API, user=user)