diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/UserController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/UserController.java index 637570b5989997a5422fda31e340869aacbdc9af..7eeab3880caf9cb5777a5f5493908ff0e9f6ceba 100755 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/UserController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/UserController.java @@ -41,6 +41,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import no.nibio.vips.i18n.LanguageUtil; +import no.nibio.vips.logic.controller.session.DeleteUserException; import no.nibio.vips.logic.controller.session.UserBean; import no.nibio.vips.logic.entity.Organization; import no.nibio.vips.logic.entity.UserAuthentication; @@ -464,12 +465,10 @@ public class UserController extends HttpServlet { return; } } - //em.remove(viewUser); userBean.deleteUser(viewUser); response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://").append(ServletUtil.getServerName(request)).append("/user").append("?messageKey=").append("userDeleted").toString()); - } - catch(NullPointerException | NumberFormatException ex) + catch(NullPointerException | NumberFormatException | DeleteUserException ex) { response.sendError(500, ex.getMessage()); } diff --git a/src/main/java/no/nibio/vips/logic/controller/session/DeleteUserException.java b/src/main/java/no/nibio/vips/logic/controller/session/DeleteUserException.java new file mode 100644 index 0000000000000000000000000000000000000000..577971b60962eefc75a25085c7014e62e329299c --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/controller/session/DeleteUserException.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.controller.session; + +/** + * @copyright 2019 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class DeleteUserException extends Exception { + + public DeleteUserException(String msg) { + super(msg); + } + +} diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java index 01ce00b1a17579c07e88c93525450c0d4ef53822..8f8d4036cafef4c60105787b42f62cb4d42252aa 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java @@ -1102,4 +1102,27 @@ public class ForecastBean { .filter(modelInfo -> ModelRunPreprocessorFactory.getModelRunPreprocessor(modelInfo.getModelId()) != null) .collect(Collectors.toList()); } + + public void deleteAllPrivateForecastConfigurationsForUser(VipsLogicUser user) { + + em.createNativeQuery( + "DELETE FROM public.forecast_result WHERE forecast_configuration_id IN " + + "(" + + " SELECT forecast_configuration_id " + + " FROM public.forecast_configuration " + + " WHERE is_private IS TRUE " + + " AND vips_logic_user_id = :userId " + + ")" + ) + .setParameter("userId", user.getUserId()) + .executeUpdate(); + + em.createNativeQuery( + "DELETE FROM public.forecast_configuration " + + " WHERE is_private IS TRUE " + + " AND vips_logic_user_id = :userId" + ) + .setParameter("userId", user.getUserId()) + .executeUpdate(); + } } diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java index 09683391ca3d062a4e097366c46d115d352e15b3..4baea740c53fed8adf796acf1607a423e1f2895b 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -123,6 +124,28 @@ public class ObservationBean { return retVal; } + public List<Observation> getObservationsLastEditedByUser(VipsLogicUser user) { + List<Observation> retVal = this.getObservationsWithGeoInfo(em.createNamedQuery("Observation.findByLastEditedBy") + .setParameter("lastEditedBy", user.getUserId()) + .getResultList()); + + retVal = this.getObservationsWithLocations(retVal); + retVal = this.getObservationsWithObservers(retVal); + + return retVal; + } + + public List<Observation> getObservationsStatusChangedByUser(VipsLogicUser user) { + List<Observation> retVal = this.getObservationsWithGeoInfo(em.createNamedQuery("Observation.findByStatusChangedByUserId") + .setParameter("statusChangedByUserId", user.getUserId()) + .getResultList()); + + retVal = this.getObservationsWithLocations(retVal); + retVal = this.getObservationsWithObservers(retVal); + + return retVal; + } + public List<Observation> getObservationsForUser(VipsLogicUser user, Date periodStart, Date periodEnd) { List<Observation> retVal = this.getObservationsWithGeoInfo(em.createNamedQuery("Observation.findByUserIdAndPeriod") @@ -714,5 +737,9 @@ public class ObservationBean { } } + + + + } diff --git a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java index 30180926c14fda836a4e30867a0db480bce741f7..ad0fcba6c1ecf5b45d7d167cdb1e440bc35794ec 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java @@ -93,6 +93,24 @@ public class PointOfInterestBean { } } + /** + * Returns POIs of all types for a given user + * @param user + * @return + */ + public List<PointOfInterest> getPoisForUser(VipsLogicUser user) { + Query q = em.createNamedQuery("PointOfInterest.findByUserId"); + q.setParameter("userId", user); + try + { + return q.getResultList(); + } + catch(NoResultException ex) + { + return null; + } + } + public List<PointOfInterestWeatherStation> getWeatherstationsForUserOrganization(VipsLogicUser user) { Query q = em.createNamedQuery("PointOfInterestWeatherStation.findByOrganizationId"); @@ -465,5 +483,7 @@ public class PointOfInterestBean { .setParameter("name", dataSourceName) .getSingleResult(); } + + } diff --git a/src/main/java/no/nibio/vips/logic/controller/session/UserBean.java b/src/main/java/no/nibio/vips/logic/controller/session/UserBean.java index 44d8c6438d2f1630eeb07c381e5b4fb4367fccf1..2c5de313dec72f56308d94a6b257b2bf8c800025 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/UserBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/UserBean.java @@ -29,6 +29,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.TimeZone; import java.util.Date; import java.util.List; @@ -40,7 +41,6 @@ import java.util.Set; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.ejb.EJBException; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.persistence.EntityManager; @@ -55,8 +55,10 @@ import no.nibio.vips.logic.entity.Country; import no.nibio.vips.logic.entity.ForecastConfiguration; import no.nibio.vips.logic.entity.MapLayer; import no.nibio.vips.logic.entity.MessageLocale; +import no.nibio.vips.logic.entity.Observation; import no.nibio.vips.logic.entity.Organization; import no.nibio.vips.logic.entity.OrganizationGroup; +import no.nibio.vips.logic.entity.PointOfInterest; import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; import no.nibio.vips.logic.entity.UserAuthentication; import no.nibio.vips.logic.entity.UserAuthenticationPK; @@ -210,44 +212,84 @@ public class UserBean { * * @param user */ - public void deleteUser(VipsLogicUser user) + public void deleteUser(VipsLogicUser user) throws DeleteUserException { + // Must double check: NO user can be force deleted without first + // transferring resources to another user + UserResources userResources = SessionControllerGetter.getUserBean().getUserResources(user); + if(! userResources.isEmpty()) + { + throw new DeleteUserException("User still has resources connected to them."); + } user = em.find(VipsLogicUser.class, user.getUserId()); + // If it's an archive user, do NOT delete it! + if(user.getOrganizationId().getArchiveUser().getUserId().equals(user.getUserId())) + { + throw new DeleteUserException("User is an archive user for organization " + user.getOrganizationId().getOrganizationName() + ". Can't delete it"); + } // Remove all notification subscriptions SessionControllerGetter.getMessagingBean().deleteAllNotificationSubscriptions(user); - // TODO: Move these objects from user to be deleted to the organization's archive user - // * All observations - // * All messages - // * All POIs - // * All non-private forecast configurations - // - // TODO: Delete all of the user's private forecast configurations and results + // Remove all User UUIDs + this.deleteAllUserUuidsForUser(user); + + // Delete all of the user's private forecast configurations and results + SessionControllerGetter.getForecastBean().deleteAllPrivateForecastConfigurationsForUser(user); + em.remove(user); } public UserResources getUserResources(VipsLogicUser user) { UserResources retVal = new UserResources(); - retVal.setWeatherStations(SessionControllerGetter.getPointOfInterestBean().getWeatherstationsForUser(user)); + retVal.setPois(SessionControllerGetter.getPointOfInterestBean().getPoisForUser(user)); retVal.setMessageLocales(SessionControllerGetter.getMessageBean().getMessageLocaleList(user)); retVal.setForecastConfigurations(SessionControllerGetter.getForecastBean().getForecastConfigurationsForUser(user.getUserId())); + List<Observation> observations = SessionControllerGetter.getObservationBean().getObservationsForUser(user); + observations.addAll(SessionControllerGetter.getObservationBean().getObservationsLastEditedByUser(user)); + observations.addAll(SessionControllerGetter.getObservationBean().getObservationsStatusChangedByUser(user)); + retVal.setObservations(observations); return retVal; } + /** + * Transfers all user resources (may need to update this method to keep up with the system) + * <ul> + * <li>Weather Stations</li> + * <li>Messages</li> + * <li>Forecast Configurations</li> + * <li>Observations</li> + * </ul> + * @param fromUser + * @param toUser + */ public void transferUserResources(VipsLogicUser fromUser, VipsLogicUser toUser) { UserResources userResources = this.getUserResources(fromUser); - for(PointOfInterestWeatherStation ws:userResources.getWeatherStations()) - { + (userResources.getPois() != null ? userResources.getPois() : Collections.<PointOfInterest>emptyList()).forEach((ws) -> { ws.setUserId(toUser); - } - for(MessageLocale ml:userResources.getMessageLocales()) - { + }); + (userResources.getMessageLocales() != null ? userResources.getMessageLocales() : Collections.<MessageLocale>emptyList()).forEach((ml) -> { ml.setCreatedBy(toUser); - } - for(ForecastConfiguration fc: userResources.getForecastConfigurations()) - { + }); + (userResources.getForecastConfigurations() != null ? userResources.getForecastConfigurations() : Collections.<ForecastConfiguration>emptyList()).forEach((fc) -> { fc.setVipsCoreUserId(toUser); - } + }); + //HMMMMMMM - noe med transaksjoner som ikke er oppdatert elns???? + (userResources.getObservations() != null ? userResources.getObservations() : Collections.<Observation>emptyList()).forEach((obs) -> { + if(obs.getUserId().equals(fromUser.getUserId())) + { + obs.setUserId(toUser.getUserId()); + obs.setUser(toUser); + } + if(obs.getLastEditedBy() != null && obs.getLastEditedBy().equals(fromUser.getUserId())) + { + obs.setLastEditedBy(toUser.getUserId()); + obs.setLastEditedByUser(toUser); + } + if(obs.getStatusChangedByUserId() != null && obs.getStatusChangedByUserId().equals(fromUser.getUserId())) + { + obs.setStatusChangedByUserId(toUser.getUserId()); + } + }); } @@ -680,6 +722,10 @@ public class UserBean { em.createNativeQuery("DELETE FROM public.user_uuid WHERE expires_at < now()").executeUpdate(); } + public void deleteAllUserUuidsForUser(VipsLogicUser user){ + em.createNativeQuery("DELETE FROM public.user_uuid WHERE user_id=:userId").setParameter("userId", user.getUserId()).executeUpdate(); + } + public String getMapLayerJSONForUser(VipsLogicUser user) { try { diff --git a/src/main/java/no/nibio/vips/logic/entity/Observation.java b/src/main/java/no/nibio/vips/logic/entity/Observation.java index 56f5468a65993b2629e403972bd556f56c483003..314c78198eb9093acceebbd5588d5c23e868c32d 100755 --- a/src/main/java/no/nibio/vips/logic/entity/Observation.java +++ b/src/main/java/no/nibio/vips/logic/entity/Observation.java @@ -66,6 +66,8 @@ import org.hibernate.annotations.TypeDefs; @NamedQuery(name = "Observation.findAll", query = "SELECT o FROM Observation o"), @NamedQuery(name = "Observation.findByObservationId", query = "SELECT o FROM Observation o WHERE o.observationId = :observationId"), @NamedQuery(name = "Observation.findByUserId", query = "SELECT o FROM Observation o WHERE o.userId IN(:userId)"), + @NamedQuery(name = "Observation.findByLastEditedBy", query = "SELECT o FROM Observation o WHERE o.lastEditedBy IN(:lastEditedBy)"), + @NamedQuery(name = "Observation.findByStatusChangedByUserId", query = "SELECT o FROM Observation o WHERE o.statusChangedByUserId IN(:statusChangedByUserId)"), @NamedQuery(name = "Observation.findByUserIdAndPeriod", query = "SELECT o FROM Observation o WHERE o.timeOfObservation BETWEEN :start AND :end AND o.userId IN(:userId)"), @NamedQuery(name = "Observation.findByUserIdAndStatusTypeId", query = "SELECT o FROM Observation o WHERE o.userId IN(:userId) AND o.statusTypeId= :statusTypeId"), @NamedQuery(name = "Observation.findByUserIdAndOrganism", query = "SELECT o FROM Observation o WHERE o.userId IN(:userId) AND o.organism = :organism"), diff --git a/src/main/java/no/nibio/vips/logic/entity/Organization.java b/src/main/java/no/nibio/vips/logic/entity/Organization.java index 5da5b37227b942e80aa35ca9d6d2e146754fc0db..a02f5f55c5ddd011e90ca43606cb85550ea7657e 100755 --- a/src/main/java/no/nibio/vips/logic/entity/Organization.java +++ b/src/main/java/no/nibio/vips/logic/entity/Organization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 NIBIO <http://www.nibio.no/>. + * Copyright (c) 2019 NIBIO <http://www.nibio.no/>. * * This file is part of VIPSLogic. * VIPSLogic is free software: you can redistribute it and/or modify @@ -39,9 +39,10 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import com.fasterxml.jackson.annotation.JsonIgnore; import javax.persistence.FetchType; +import javax.persistence.OneToOne; /** - * @copyright 2013 <a href="http://www.nibio.no/">NIBIO</a> + * @copyright 2019 <a href="http://www.nibio.no/">NIBIO</a> * @author Tor-Einar Skog <tor-einar.skog@nibio.no> */ @Entity @@ -104,6 +105,12 @@ public class Organization implements Serializable { private Set<VipsLogicUser> vipsLogicUserSet; @Column(name = "vipsweb_url") private String vipswebUrl; + // The user for that organization that we can move resources to (messages, observations etc) + // from a regular user that we are deleting + @JoinColumn(name = "archive_user_id") + @OneToOne + @JsonIgnore + private VipsLogicUser archiveUser; public Organization() { } @@ -311,4 +318,18 @@ public class Organization implements Serializable { this.vipswebUrl = vipswebUrl; } + /** + * @return the archiveUser + */ + public VipsLogicUser getArchiveUser() { + return archiveUser; + } + + /** + * @param archiveUser the archiveUser to set + */ + public void setArchiveUser(VipsLogicUser archiveUser) { + this.archiveUser = archiveUser; + } + } diff --git a/src/main/java/no/nibio/vips/logic/entity/misc/UserResources.java b/src/main/java/no/nibio/vips/logic/entity/misc/UserResources.java index 2fea325fc3997fe34f8e0232a45f1d1d0015677d..717fad5d16672d1a12f75ef7cf064f0ca851e84a 100755 --- a/src/main/java/no/nibio/vips/logic/entity/misc/UserResources.java +++ b/src/main/java/no/nibio/vips/logic/entity/misc/UserResources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 NIBIO <http://www.nibio.no/>. + * Copyright (c) 2019 NIBIO <http://www.nibio.no/>. * * This file is part of VIPSLogic. * VIPSLogic is free software: you can redistribute it and/or modify @@ -23,40 +23,43 @@ import java.util.ArrayList; import java.util.List; import no.nibio.vips.logic.entity.ForecastConfiguration; import no.nibio.vips.logic.entity.MessageLocale; -import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; +import no.nibio.vips.logic.entity.Observation; +import no.nibio.vips.logic.entity.PointOfInterest; /** * Utility class for collecting user's resources in a uniform way - * @copyright 2015 <a href="http://www.nibio.no/">NIBIO</a> + * @copyright 2019 <a href="http://www.nibio.no/">NIBIO</a> * @author Tor-Einar Skog <tor-einar.skog@nibio.no> */ public class UserResources { - private List<PointOfInterestWeatherStation> weatherStations; + private List<PointOfInterest> pois; private List<MessageLocale> messageLocales; private List<ForecastConfiguration> forecastConfigurations; + private List<Observation> observations; public boolean isEmpty(){ - return (this.getWeatherStations() == null || this.getWeatherStations().isEmpty()) + return (this.getPois() == null || this.getPois().isEmpty()) && (this.getMessageLocales() == null || this.getMessageLocales().isEmpty()) - && (this.getForecastConfigurations() == null || this.getForecastConfigurations().isEmpty()); + && (this.getForecastConfigurations() == null || this.getForecastConfigurations().isEmpty()) + && (this.getObservations() == null || this.getObservations().isEmpty()); } /** * @return the weatherStations */ - public List<PointOfInterestWeatherStation> getWeatherStations() { - if(this.weatherStations == null) + public List<PointOfInterest> getPois() { + if(this.pois == null) { - this.weatherStations = new ArrayList<>(); + this.pois = new ArrayList<>(); } - return weatherStations; + return pois; } /** - * @param weatherStations the weatherStations to set + * @param pois the weatherStations to set */ - public void setWeatherStations(List<PointOfInterestWeatherStation> weatherStations) { - this.weatherStations = weatherStations; + public void setPois(List<PointOfInterest> pois) { + this.pois = pois; } /** @@ -94,6 +97,20 @@ public class UserResources { public void setForecastConfigurations(List<ForecastConfiguration> forecastConfigurations) { this.forecastConfigurations = forecastConfigurations; } + + /** + * @return the observations + */ + public List<Observation> getObservations() { + return observations; + } + + /** + * @param observations the observations to set + */ + public void setObservations(List<Observation> observations) { + this.observations = observations; + } } diff --git a/src/main/resources/db/migration/V4__Add_org_archive_user.sql b/src/main/resources/db/migration/V4__Add_org_archive_user.sql new file mode 100644 index 0000000000000000000000000000000000000000..1419447bf9f2d2dbcf1c03a18a99cbf19d9a1352 --- /dev/null +++ b/src/main/resources/db/migration/V4__Add_org_archive_user.sql @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2019 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +/** + * Author: Tor-Einar Skog <tor-einar.skog@nibio.no> + * Created: Jan 14, 2019 + */ + +ALTER TABLE public.organization +ADD COLUMN archive_user_id INTEGER REFERENCES public.vips_logic_user (user_id); + diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties index 8b215d03e32d2274b9d3671eb293a715a5d84174..53c3b33031c03b7ca1efed1bbfc2182cc250a971 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties @@ -463,3 +463,4 @@ fieldSowingDate=Field sowing date previousCrop=Previous crop tillageMethod=Tillage method cropSusceptibility=Crop susceptibility +organizationsArchiveUser=The organization's standard archive user diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties index 700a9c085d64460e81e215e128a5c0420bba908f..4c3ef394a1a4730e31afbe80acac14f94361c89b 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties @@ -463,3 +463,4 @@ fieldSowingDate=Field sowing date previousCrop=Previous crop tillageMethod=Tillage method cropSusceptibility=Crop susceptibility +organizationsArchiveUser=The organization's standard archive user diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties index a6e80eb38ac2e6a9cb0393513050a6666632306b..440c0415d87b01877ccc01c056ab70cba9573933 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties @@ -462,3 +462,4 @@ fieldSowingDate=Field sowing date previousCrop=Previous crop tillageMethod=Tillage method cropSusceptibility=Crop susceptibility +organizationsArchiveUser=The organization's standard archive user diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties index 9990e774d1400b1f28faa2f84b64ea8e0dcaaf5b..d1b1548ecd2f2c8383725983c224a54b517bf2fa 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties @@ -463,3 +463,4 @@ fieldSowingDate=S\u00e5dato for felt previousCrop=Forrige kulturvekst tillageMethod=Pl\u00f8yemetode cropSusceptibility=Kulturvekstens sykdomsmottakelighet +organizationsArchiveUser=Organisasjonens standard arkivbrukerkonto diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties index ffe49f3aef3aa7daf60399a931060ae51c4884d1..d0d19cc16b25f850dbfbd08fcd29acb177e625ae 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties @@ -463,3 +463,4 @@ fieldSowingDate=Field sowing date previousCrop=Previous crop tillageMethod=Tillage method cropSusceptibility=Crop susceptibility +organizationsArchiveUser=The organization's standard archive user diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties index 7a35aa5e60223fe0d3282097ffa928115d52231f..8d0b2432cd17f59fcefc088d0b145751f2c48897 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties @@ -460,3 +460,4 @@ fieldSowingDate=Field sowing date previousCrop=Previous crop tillageMethod=Tillage method cropSusceptibility=Crop susceptibility +organizationsArchiveUser=The organization's standard archive user diff --git a/src/main/webapp/templates/userDeleteForm.ftl b/src/main/webapp/templates/userDeleteForm.ftl index 728578dc94a106688fe50854e7f89699dec8cfb6..7cf11937fa862a50ea4a04c357497bcad530c436 100755 --- a/src/main/webapp/templates/userDeleteForm.ftl +++ b/src/main/webapp/templates/userDeleteForm.ftl @@ -32,9 +32,10 @@ <p>${i18nBundle.deleteUserDescription}</p> <h2>${i18nBundle.userResources}</h2> <ul> - <li>${i18nBundle.weatherStations}: ${userResources.weatherStations?size}</li> + <li>${i18nBundle.weatherStations}: ${userResources.pois?size}</li> <li>${i18nBundle.messages}: ${userResources.messageLocales?size}</li> <li>${i18nBundle.forecasts}: ${userResources.forecastConfigurations?size}</li> + <li>${i18nBundle.observations}: ${userResources.observations?size}</li> </ul> <h2>${i18nBundle.transferResources}</h2> <form action="/user?action=deleteUser" method="POST" onsubmit="return confirm('${i18nBundle.confirmDelete}');"/> @@ -42,6 +43,9 @@ <p> <select class="form-control" name="transferToUserId"> <option value="-1">-- ${i18nBundle.select} --</option> + <#if viewUser.organizationId.archiveUser?has_content> + <option value="${viewUser.organizationId.archiveUser.userId}">${i18nBundle.organizationsArchiveUser}</option> + </#if> <#list users as user> <#if user.userId != viewUser.userId> <option value="${user.userId}">${user.firstName!""} ${user.lastName}</option>