some actions by role

This commit is contained in:
Michele Artini 2020-10-20 12:03:23 +02:00
parent 8f30e4c8a5
commit 9099e62b9b
7 changed files with 92 additions and 56 deletions

View File

@ -44,7 +44,6 @@ import eu.dnetlib.organizations.repository.readonly.OrganizationSimpleViewReposi
import eu.dnetlib.organizations.repository.readonly.OrganizationViewRepository; import eu.dnetlib.organizations.repository.readonly.OrganizationViewRepository;
import eu.dnetlib.organizations.repository.readonly.SuggestionInfoViewByCountryRepository; import eu.dnetlib.organizations.repository.readonly.SuggestionInfoViewByCountryRepository;
import eu.dnetlib.organizations.utils.DatabaseUtils; import eu.dnetlib.organizations.utils.DatabaseUtils;
import eu.dnetlib.organizations.utils.OrganizationStatus;
@RestController @RestController
@RequestMapping("/api/organizations") @RequestMapping("/api/organizations")
@ -127,8 +126,7 @@ public class OrganizationController {
if (UserInfo.isSuperAdmin(authentication) || UserInfo.isNationalAdmin(authentication) && if (UserInfo.isSuperAdmin(authentication) || UserInfo.isNationalAdmin(authentication) &&
userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), authentication.getName())) { userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), authentication.getName())) {
databaseUtils.updateStatus(id, OrganizationStatus.deleted, authentication.getName()); return databaseUtils.markAsDeleted(id, authentication.getName());
return organizationViewRepository.findById(id).get();
} else { } else {
throw new RuntimeException("User not authorized"); throw new RuntimeException("User not authorized");
} }

View File

@ -104,8 +104,6 @@ public class DatabaseUtils {
final boolean alreadyApproved = StringUtils.equals(oldStatus, OrganizationStatus.approved.toString()); final boolean alreadyApproved = StringUtils.equals(oldStatus, OrganizationStatus.approved.toString());
final String oldId = orgView.getId();
final String newStatus; final String newStatus;
if (!isSimpleUser) { // IS ADMIN if (!isSimpleUser) { // IS ADMIN
newStatus = OrganizationStatus.approved.toString(); newStatus = OrganizationStatus.approved.toString();
@ -117,14 +115,10 @@ public class DatabaseUtils {
throw new RuntimeException("User not authorized"); throw new RuntimeException("User not authorized");
} }
if (StringUtils.isBlank(orgView.getId())) { final String oldId = StringUtils.isNotBlank(orgView.getId()) ? new String(orgView.getId()) : null;
if (oldId == null || !oldId.startsWith(OpenOrgsConstants.OPENORGS_PREFIX)) {
orgView.setId(null); orgView.setId(null);
} else if (!alreadyApproved) {
cleanOldRelations(oldId);
organizationRepository.deleteById(oldId);
orgView.setId(null);
} else {
cleanOldRelations(orgView.getId());
} }
final Organization org = new Organization(orgView.getId(), final Organization org = new Organization(orgView.getId(),
@ -136,24 +130,31 @@ public class DatabaseUtils {
final String newId = organizationRepository.save(org).getId(); final String newId = organizationRepository.save(org).getId();
makeNewRelations(newId, orgView); final OffsetDateTime now = OffsetDateTime.now();
updateHistoryFields(newId, user, alreadyApproved); organizationRepository.updateModificationDate(newId, user, now);
if (StringUtils.equals(newId, oldId)) {
makeRelations(newId, orgView, true);
} else {
organizationRepository.updateCreationDate(newId, user, now);
makeRelations(newId, orgView, false);
if (oldId != null) {
final OpenaireDuplicate dup = new OpenaireDuplicate();
dup.setLocalId(newId);
dup.setOaOriginalId(oldId);
dup.setRelType(SimilarityType.is_similar.toString());
openaireDuplicateRepository.save(dup);
openaireConflictRepository.updateModificationDate(newId, oldId, user, now);
organizationRepository.updateStatus(oldId, OrganizationStatus.duplicate.toString());
organizationRepository.updateModificationDate(oldId, user, now);
}
}
return newId; return newId;
} }
private void updateHistoryFields(final String id, final String user, final boolean update) {
final OffsetDateTime now = OffsetDateTime.now();
if (update) {
organizationRepository.updateModificationDate(id, user, now);
} else {
organizationRepository.updateCreationDate(id, user, now);
organizationRepository.updateModificationDate(id, user, now);
}
}
@Transactional @Transactional
public void saveDuplicates(final List<OpenaireDuplicate> simrels, final String user) { public void saveDuplicates(final List<OpenaireDuplicate> simrels, final String user) {
final OffsetDateTime now = OffsetDateTime.now(); final OffsetDateTime now = OffsetDateTime.now();
@ -164,15 +165,23 @@ public class DatabaseUtils {
openaireDuplicateRepository.updateModificationDate(d.getLocalId(), d.getOaOriginalId(), user, now); openaireDuplicateRepository.updateModificationDate(d.getLocalId(), d.getOaOriginalId(), user, now);
if (d.getRelType().equals(SimilarityType.is_similar.toString())) { if (d.getRelType().equals(SimilarityType.is_similar.toString())) {
updateStatus(d.getOaOriginalId(), OrganizationStatus.duplicate, user); updateStatus(d.getOaOriginalId(), OrganizationStatus.duplicate, user, now);
} else { } else {
updateStatus(d.getOaOriginalId(), OrganizationStatus.suggested, user); updateStatus(d.getOaOriginalId(), OrganizationStatus.suggested, user, now);
} }
}); });
} }
private void makeNewRelations(final String orgId, final OrganizationView orgView) { private void makeRelations(final String orgId, final OrganizationView orgView, final boolean update) {
if (update) {
acronymRepository.deleteByOrgId(orgId);
otherNameRepository.deleteByOrgId(orgId);
otherIdentifierRepository.deleteByOrgId(orgId);
urlRepository.deleteByOrgId(orgId);
relationshipRepository.deleteById1(orgId);
relationshipRepository.deleteById2(orgId);
}
orgView.getAcronyms().forEach(s -> acronymRepository.save(new Acronym(orgId, s))); orgView.getAcronyms().forEach(s -> acronymRepository.save(new Acronym(orgId, s)));
orgView.getOtherNames().forEach(n -> otherNameRepository.save(new OtherName(orgId, n.getName(), n.getLang()))); orgView.getOtherNames().forEach(n -> otherNameRepository.save(new OtherName(orgId, n.getName(), n.getLang())));
orgView.getOtherIdentifiers().forEach(id -> otherIdentifierRepository.save(new OtherIdentifier(orgId, id.getId(), id.getType()))); orgView.getOtherIdentifiers().forEach(id -> otherIdentifierRepository.save(new OtherIdentifier(orgId, id.getId(), id.getType())));
@ -180,15 +189,6 @@ public class DatabaseUtils {
orgView.getRelations().forEach(r -> makeRelation(orgId, r.getRelatedOrgId(), RelationType.valueOf(r.getType()))); orgView.getRelations().forEach(r -> makeRelation(orgId, r.getRelatedOrgId(), RelationType.valueOf(r.getType())));
} }
private void cleanOldRelations(final String id) {
acronymRepository.deleteByOrgId(id);
otherNameRepository.deleteByOrgId(id);
otherIdentifierRepository.deleteByOrgId(id);
urlRepository.deleteByOrgId(id);
relationshipRepository.deleteById1(id);
relationshipRepository.deleteById2(id);
}
@Cacheable("vocs") @Cacheable("vocs")
public List<VocabularyTerm> listValuesOfVocabularyTable(final VocabularyTable table) { public List<VocabularyTerm> listValuesOfVocabularyTable(final VocabularyTable table) {
final String sql = "select val as value, name as name from " + table; final String sql = "select val as value, name as name from " + table;
@ -353,9 +353,15 @@ public class DatabaseUtils {
} }
@Transactional @Transactional
public void updateStatus(final String id, final OrganizationStatus status, final String user) { public OrganizationView markAsDeleted(final String id, final String user) {
final OffsetDateTime now = OffsetDateTime.now();
updateStatus(id, OrganizationStatus.deleted, user, now);
return organizationViewRepository.findById(id).get();
}
private void updateStatus(final String id, final OrganizationStatus status, final String user, final OffsetDateTime now) {
organizationRepository.updateStatus(id, status.toString()); organizationRepository.updateStatus(id, status.toString());
updateHistoryFields(id, user, true); organizationRepository.updateModificationDate(id, user, now);
} }
@Transactional @Transactional

View File

@ -5,6 +5,7 @@
</ul> </ul>
</div> </div>
<div class="card-body"> <div class="card-body">
<org-form-metadata org="org" vocabularies="vocabularies" mode="insert"></org-form-metadata> <org-form-metadata org="org" vocabularies="vocabularies" mode="insert_full" ng-if="superAdmin"></org-form-metadata>
<org-form-metadata org="org" vocabularies="vocabularies" mode="insert_pending" ng-if="!superAdmin"></org-form-metadata>
</div> </div>
</div> </div>

View File

@ -23,9 +23,14 @@
</div> </div>
<div class="card-body" ng-if="currentTab == 1 && org.status"> <div class="card-body" ng-if="currentTab == 1 && org.status">
<org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="update" ng-if="org.status == 'approved'"></org-form-metadata> <org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="update_full" ng-if="adminMode && org.status == 'approved'"></org-form-metadata>
<org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="approve" ng-if="org.status == 'suggested'"></org-form-metadata> <org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="update_simple" ng-if="!adminMode && org.status == 'approved'"></org-form-metadata>
<org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="approve" ng-if="adminMode && org.status == 'suggested'"></org-form-metadata>
<org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="not_authorized" ng-if="!adminMode && org.status == 'suggested'"></org-form-metadata>
<org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="readonly" ng-if="org.status != 'approved' && org.status != 'suggested'"></org-form-metadata> <org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" mode="readonly" ng-if="org.status != 'approved' && org.status != 'suggested'"></org-form-metadata>
</div> </div>
<div class="card-body" ng-if="currentTab == 2 && (org.status == 'approved' || org.status == 'suggested')"> <div class="card-body" ng-if="currentTab == 2 && (org.status == 'approved' || org.status == 'suggested')">

View File

@ -4,11 +4,13 @@
This is a pending organization. Please evaluate it before approving. This is a pending organization. Please evaluate it before approving.
</div> </div>
<div ng-if="mode == 'readonly'" class="alert alert-secondary"> <div ng-if="mode == 'readonly'" class="alert alert-secondary">
This organization is managed by the system. You can not edit. <span class="badge badge-primary">{{org.status}}</span> This organization is managed by the system. You can not edit.
</div>
<div ng-if="mode == 'not_authorized'" class="alert alert-secondary">
<span class="badge badge-primary">{{org.status}}</span> You are not authorized to modify this organization.
</div> </div>
<fieldset ng-disabled="mode == 'readonly' || mode == 'not_authorized'">
<fieldset ng-disabled="mode == 'readonly'">
<legend>Official name and type</legend> <legend>Official name and type</legend>
<div class="form-group"> <div class="form-group">
@ -32,7 +34,7 @@
</div> </div>
</div> </div>
</fieldset> </fieldset>
<fieldset class="mt-4" ng-disabled="mode == 'readonly'"> <fieldset class="mt-4" ng-disabled="mode == 'readonly' || mode == 'not_authorized'">
<legend>Geographical location</legend> <legend>Geographical location</legend>
<div class="form-group"> <div class="form-group">
@ -66,7 +68,7 @@
</div> </div>
</fieldset> </fieldset>
<fieldset class="mt-4" ng-disabled="mode == 'readonly'"> <fieldset class="mt-4" ng-disabled="mode == 'readonly' || mode == 'not_authorized'">
<legend>Other names and identifiers</legend> <legend>Other names and identifiers</legend>
<div class="form-group row"> <div class="form-group row">
@ -232,7 +234,7 @@
</div> </div>
</fieldset> </fieldset>
<fieldset class="mt-4" ng-disabled="mode == 'readonly'"> <fieldset class="mt-4" ng-disabled="mode == 'readonly' || mode == 'not_authorized'">
<legend>Relations</legend> <legend>Relations</legend>
<div class="form-group row"> <div class="form-group row">
<div class="col-lg-8 mb-2"> <div class="col-lg-8 mb-2">
@ -285,10 +287,24 @@
</div> </div>
</fieldset> </fieldset>
<button type="submit" class="btn" ng-class="{'btn-primary' : mode != 'approve', 'btn-warning' : mode == 'approve'}" ng-click="save()" ng-disabled="organizationForm.$invalid" ng-hide="mode == 'readonly'">
<span ng-if="mode != 'approve'">Save</span> <fieldset ng-if="mode == 'update_full'">
<span ng-if="mode == 'approve'">Register as new Organization</span> <button type="submit" class="btn btn-primary" ng-click="save()" ng-disabled="organizationForm.$invalid">Save</button>
</button> <button type="button" class="btn btn-danger" ng-click="deleteOrg()">Delete</button>
</fieldset>
<fieldset ng-if="mode == 'update_simple'">
<button type="submit" class="btn btn-primary" ng-click="save()" ng-disabled="organizationForm.$invalid">Save</button>
</fieldset>
<fieldset ng-if="mode == 'approve'">
<button type="submit" class="btn btn-primary" ng-click="save()" ng-disabled="organizationForm.$invalid">Approve as new Organization</button>
<button type="button" class="btn btn-danger" ng-click="saveAsDiscarded()">Discard</button>
</fieldset>
<fieldset ng-if="mode == 'insert_full'">
<button type="submit" class="btn btn-primary" ng-click="save()" ng-disabled="organizationForm.$invalid">Register a new Organization</button>
</fieldset>
<fieldset ng-if="mode == 'insert_pending'">
<button type="submit" class="btn btn-primary" ng-click="save()" ng-disabled="organizationForm.$invalid">Suggest a new Organization</button>
</fieldset>
</form> </form>

View File

@ -126,12 +126,11 @@ orgsModule.directive('orgFormMetadata', function($http, $location, $route, $rout
'orgId' : '@', 'orgId' : '@',
'org' : '=', 'org' : '=',
'vocabularies' : '=', 'vocabularies' : '=',
'mode' : '@', // insert, update or approve 'mode' : '@', // insert_full, insert_pending, update_simple, update_full, approve, readonly, not_authorized
'infoMethod' : '&' 'infoMethod' : '&'
}, },
templateUrl: 'resources/html/parts/org_metadata.form.html', templateUrl: 'resources/html/parts/org_metadata.form.html',
link: function(scope, element, attrs, ctrl) { link: function(scope, element, attrs, ctrl) {
scope.newRelation = {}; scope.newRelation = {};
scope.newRelType = ''; scope.newRelType = '';
@ -161,6 +160,9 @@ orgsModule.directive('orgFormMetadata', function($http, $location, $route, $rout
alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')'); alert('ERROR: ' + res.data.error + ' (' + res.data.message + ')');
}); });
} }
scope.deleteOrg = function() { alert('TODO'); };
scope.saveAsDiscarded = function() { alert('TODO'); };
} }
} }
}); });
@ -293,10 +295,9 @@ orgsModule.controller('newOrgCtrl', function ($scope, $http, $routeParams, $loca
"urls": [], "urls": [],
"relations": [] "relations": []
}; };
$scope.adminMode = adminMode();
$scope.vocabularies = {}; $scope.vocabularies = {};
vocabulariesService.getVocs(function(vocs) { $scope.vocabularies = vocs; }); vocabulariesService.getVocs(function(vocs) { $scope.vocabularies = vocs; });
}); });
orgsModule.controller('searchCtrl', function ($scope, $location) { orgsModule.controller('searchCtrl', function ($scope, $location) {
@ -424,6 +425,7 @@ orgsModule.controller('showEditCtrl', function ($scope, $http, $routeParams, $ro
$scope.info = {}; $scope.info = {};
$scope.currentTab = 1 $scope.currentTab = 1
$scope.vocabularies = {}; $scope.vocabularies = {};
$scope.adminMode = adminMode();
$scope.getInfo = function() { $scope.getInfo = function() {
$http.get('api/organizations/info?id=' + $scope.orgId).then(function successCallback(res) { $http.get('api/organizations/info?id=' + $scope.orgId).then(function successCallback(res) {

View File

@ -61,6 +61,8 @@ fieldset > legend { font-size : 1.2rem !important; }
<a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Advanced</a> <a class="nav-link dropdown-toggle" href="javascript:void(0)" data-toggle="dropdown">Advanced</a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/duplicates/_"><span class="pr-2">duplicates</span><span class="badge badge-primary badge-pill">{{info.total.nDuplicates}}</span></a> <a class="dropdown-item d-flex justify-content-between align-items-center" href="#!/duplicates/_"><span class="pr-2">duplicates</span><span class="badge badge-primary badge-pill">{{info.total.nDuplicates}}</span></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#!/new">suggest a new organization</a>
</div> </div>
</li> </li>
</ul> </ul>
@ -96,6 +98,12 @@ fieldset > legend { font-size : 1.2rem !important; }
<script sec:authorize="!hasRole('ROLE_ADMIN')"> <script sec:authorize="!hasRole('ROLE_ADMIN')">
function superAdminMode() { return false; } function superAdminMode() { return false; }
</script> </script>
<script sec:authorize="hasRole('ROLE_ADMIN') or hasRole('ROLE_NATIONAL_ADMIN')">
function adminMode() { return true; }
</script>
<script sec:authorize="!hasRole('ROLE_ADMIN') and !hasRole('ROLE_NATIONAL_ADMIN')">
function adminMode() { return false; }
</script>
<script src="resources/js/jquery-3.4.1.min.js"></script> <script src="resources/js/jquery-3.4.1.min.js"></script>
<script src="resources/js/popper.min.js"></script> <script src="resources/js/popper.min.js"></script>