note and journal (model and api)
This commit is contained in:
parent
562e56be07
commit
13fd72b25e
|
@ -1,5 +1,6 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -25,6 +26,8 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import eu.dnetlib.common.controller.AbstractDnetController;
|
||||
import eu.dnetlib.organizations.model.JournalEntry;
|
||||
import eu.dnetlib.organizations.model.Note;
|
||||
import eu.dnetlib.organizations.model.OpenaireDuplicate;
|
||||
import eu.dnetlib.organizations.model.utils.BrowseEntry;
|
||||
import eu.dnetlib.organizations.model.utils.OrganizationConflict;
|
||||
|
@ -34,6 +37,8 @@ import eu.dnetlib.organizations.model.view.OpenaireDuplicateView;
|
|||
import eu.dnetlib.organizations.model.view.OrganizationInfoView;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationSimpleView;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationView;
|
||||
import eu.dnetlib.organizations.repository.JournalEntryRepository;
|
||||
import eu.dnetlib.organizations.repository.NoteRepository;
|
||||
import eu.dnetlib.organizations.repository.UserCountryRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.ConflictGroupViewRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.DuplicateGroupViewRepository;
|
||||
|
@ -66,6 +71,10 @@ public class OrganizationController extends AbstractDnetController {
|
|||
@Autowired
|
||||
private DuplicateGroupViewRepository duplicateGroupViewRepository;
|
||||
@Autowired
|
||||
private NoteRepository noteRepository;
|
||||
@Autowired
|
||||
private JournalEntryRepository journalEntryRepository;
|
||||
@Autowired
|
||||
private DatabaseUtils databaseUtils;
|
||||
|
||||
@PostMapping("/save")
|
||||
|
@ -324,4 +333,44 @@ public class OrganizationController extends AbstractDnetController {
|
|||
}
|
||||
}
|
||||
|
||||
@GetMapping("/note")
|
||||
public Note noteById(@RequestParam final String id, final Authentication authentication) {
|
||||
final OrganizationView org = organizationViewRepository.findById(id).get();
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication)
|
||||
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), UserInfo.getEmail(authentication))) {
|
||||
return noteRepository.findById(id).orElse(new Note(id, "", null, null));
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/note")
|
||||
public Note saveNote(@RequestBody final Note note, final Authentication authentication) {
|
||||
final OrganizationView org = organizationViewRepository.findById(note.getOrgId()).get();
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication)
|
||||
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), UserInfo.getEmail(authentication))) {
|
||||
|
||||
note.setModifiedBy(UserInfo.getEmail(authentication));
|
||||
note.setModificationDate(OffsetDateTime.now());
|
||||
|
||||
return noteRepository.save(note);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/journal")
|
||||
public List<JournalEntry> journalEntriesById(@RequestParam final String id, final Authentication authentication) {
|
||||
final OrganizationView org = organizationViewRepository.findById(id).get();
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication)
|
||||
|| userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), UserInfo.getEmail(authentication))) {
|
||||
return journalEntryRepository.findByOrgIdOrderByDateDesc(id);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import eu.dnetlib.organizations.utils.JournalOperations;
|
||||
|
||||
@Entity
|
||||
@Table(name = "journal")
|
||||
public class JournalEntry implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6861395678624671324L;
|
||||
|
||||
@Id
|
||||
@Column(name = "jid")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer journalEntryId;
|
||||
|
||||
@Column(name = "id")
|
||||
private String orgId;
|
||||
|
||||
@Column(name = "operation")
|
||||
private String operation;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "op_date")
|
||||
private OffsetDateTime date;
|
||||
|
||||
@Column(name = "email")
|
||||
private String email;
|
||||
|
||||
public JournalEntry() {}
|
||||
|
||||
public JournalEntry(final String orgId, final JournalOperations operation, final String description, final String email) {
|
||||
this(orgId, operation.name(), description, email);
|
||||
}
|
||||
|
||||
protected JournalEntry(final String orgId, final String operation, final String description, final String email) {
|
||||
this.orgId = orgId;
|
||||
this.operation = operation;
|
||||
this.description = description;
|
||||
this.date = OffsetDateTime.now();
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Integer getJournalEntryId() {
|
||||
return journalEntryId;
|
||||
}
|
||||
|
||||
public void setJournalEntryId(final Integer journalEntryId) {
|
||||
this.journalEntryId = journalEntryId;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(final String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(final String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public OffsetDateTime getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(final OffsetDateTime date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "notes")
|
||||
public class Note implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 8193034729860131949L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String orgId;
|
||||
|
||||
@Column(name = "note")
|
||||
private String note;
|
||||
|
||||
@Column(name = "modified_by")
|
||||
private String modifiedBy;
|
||||
|
||||
@Column(name = "modification_date")
|
||||
private OffsetDateTime modificationDate;
|
||||
|
||||
public Note() {}
|
||||
|
||||
public Note(final String orgId, final String note, final String modifiedBy, final OffsetDateTime modificationDate) {
|
||||
this.orgId = orgId;
|
||||
this.note = note;
|
||||
this.modifiedBy = modifiedBy;
|
||||
this.modificationDate = modificationDate;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public void setNote(final String note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
public String getModifiedBy() {
|
||||
return modifiedBy;
|
||||
}
|
||||
|
||||
public void setModifiedBy(final String modifiedBy) {
|
||||
this.modifiedBy = modifiedBy;
|
||||
}
|
||||
|
||||
public OffsetDateTime getModificationDate() {
|
||||
return modificationDate;
|
||||
}
|
||||
|
||||
public void setModificationDate(final OffsetDateTime modificationDate) {
|
||||
this.modificationDate = modificationDate;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.JournalEntry;
|
||||
|
||||
public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long> {
|
||||
|
||||
public List<JournalEntry> findByOrgIdOrderByDateDesc(String orgId);
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.Note;
|
||||
|
||||
public interface NoteRepository extends JpaRepository<Note, String> {
|
||||
|
||||
}
|
|
@ -28,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
|
||||
import eu.dnetlib.organizations.controller.UserRole;
|
||||
import eu.dnetlib.organizations.model.Acronym;
|
||||
import eu.dnetlib.organizations.model.JournalEntry;
|
||||
import eu.dnetlib.organizations.model.OpenaireConflictPK;
|
||||
import eu.dnetlib.organizations.model.OpenaireDuplicate;
|
||||
import eu.dnetlib.organizations.model.Organization;
|
||||
|
@ -44,6 +45,7 @@ import eu.dnetlib.organizations.model.utils.VocabularyTerm;
|
|||
import eu.dnetlib.organizations.model.view.OrganizationView;
|
||||
import eu.dnetlib.organizations.model.view.UserView;
|
||||
import eu.dnetlib.organizations.repository.AcronymRepository;
|
||||
import eu.dnetlib.organizations.repository.JournalEntryRepository;
|
||||
import eu.dnetlib.organizations.repository.OpenaireConflictRepository;
|
||||
import eu.dnetlib.organizations.repository.OpenaireDuplicateRepository;
|
||||
import eu.dnetlib.organizations.repository.OrganizationRepository;
|
||||
|
@ -80,6 +82,8 @@ public class DatabaseUtils {
|
|||
private OpenaireDuplicateRepository openaireDuplicateRepository;
|
||||
@Autowired
|
||||
private OrganizationViewRepository organizationViewRepository;
|
||||
@Autowired
|
||||
private JournalEntryRepository journalEntryRepository;
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
@ -164,6 +168,35 @@ public class DatabaseUtils {
|
|||
|
||||
organizationRepository.updateModificationDate(newId, user, now);
|
||||
|
||||
JournalOperations op = JournalOperations.UNKNOWN;
|
||||
String message = "-";
|
||||
|
||||
if (newStatus.equals(OrganizationStatus.suggested.toString())) {
|
||||
if (oldStatus == null) {
|
||||
op = JournalOperations.NEW_SUGG_ORG;
|
||||
message = "Created a new suggested org";
|
||||
} else if (oldStatus != null) {
|
||||
op = JournalOperations.EDIT_SUGG_ORG;
|
||||
message = "Metadata updated";
|
||||
}
|
||||
} else if (newStatus.equals(OrganizationStatus.approved.toString())) {
|
||||
if (oldStatus == null) {
|
||||
op = JournalOperations.NEW_ORG;
|
||||
message = "Created a new organization";
|
||||
} else if (oldStatus.equals(OrganizationStatus.suggested.toString())) {
|
||||
op = JournalOperations.APPROVE_SUGG_ORG;
|
||||
message = "Approved the suggested org: " + oldId;
|
||||
|
||||
} else {
|
||||
op = JournalOperations.EDIT_ORG;
|
||||
message = "Metadata updated";
|
||||
}
|
||||
} else {
|
||||
// IMPOSSIBLE ???
|
||||
}
|
||||
|
||||
journalEntryRepository.save(new JournalEntry(newId, op, message, user));
|
||||
|
||||
return newId;
|
||||
}
|
||||
|
||||
|
@ -184,6 +217,18 @@ public class DatabaseUtils {
|
|||
}
|
||||
});
|
||||
|
||||
final String message = String.format("Duplicates updated (%s similars, %s differents, %s suggested)", list.stream()
|
||||
.filter(d -> d.getRelType().equals(SimilarityType.is_similar.toString()))
|
||||
.count(), list.stream()
|
||||
.filter(d -> d.getRelType().equals(SimilarityType.is_different.toString()))
|
||||
.count(), list.stream().filter(d -> d.getRelType().equals(SimilarityType.suggested.toString())).count());
|
||||
|
||||
list.stream()
|
||||
.map(OpenaireDuplicate::getLocalId)
|
||||
.distinct()
|
||||
.map(id -> new JournalEntry(id, JournalOperations.DUPLICATES, message, user))
|
||||
.forEach(journalEntryRepository::save);
|
||||
|
||||
}
|
||||
|
||||
private void makeRelations(final String orgId, final OrganizationView orgView, final boolean update) {
|
||||
|
@ -375,7 +420,10 @@ public class DatabaseUtils {
|
|||
final String masterId = insertOrUpdateOrganization(newOrg, user, false);
|
||||
|
||||
// I hide the merged organizations
|
||||
similarIds.forEach(id -> hideConflictOrgs(masterId, id));
|
||||
similarIds.forEach(id -> {
|
||||
hideConflictOrgs(masterId, id);
|
||||
journalEntryRepository.save(new JournalEntry(masterId, JournalOperations.FIX_CONFLICT, "The org has been hidded and merged in " + masterId, user));
|
||||
});
|
||||
|
||||
// I reassign the duplicates to the new org
|
||||
final List<OpenaireDuplicate> newDuplicates = similarIds.stream()
|
||||
|
@ -400,6 +448,9 @@ public class DatabaseUtils {
|
|||
}
|
||||
}
|
||||
|
||||
journalEntryRepository
|
||||
.save(new JournalEntry(masterId, JournalOperations.FIX_CONFLICT, "New org created merging: " + StringUtils.join(similarIds, ", "), user));
|
||||
|
||||
return masterId;
|
||||
}
|
||||
|
||||
|
@ -408,11 +459,14 @@ public class DatabaseUtils {
|
|||
|
||||
final OffsetDateTime now = OffsetDateTime.now();
|
||||
|
||||
final String message = "Mark the following orgs as different: " + StringUtils.join(differentsIds, ", ");
|
||||
|
||||
for (int i = 0; i < differentsIds.size(); i++) {
|
||||
for (int j = i + 1; j < differentsIds.size(); j++) {
|
||||
openaireConflictRepository
|
||||
.updateStatusAndResetGroup(differentsIds.get(i), differentsIds.get(j), SimilarityType.is_different.toString(), user, now);
|
||||
}
|
||||
journalEntryRepository.save(new JournalEntry(differentsIds.get(i), JournalOperations.NO_CONFLICT, message, user));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package eu.dnetlib.organizations.utils;
|
||||
|
||||
public enum JournalOperations {
|
||||
NEW_ORG,
|
||||
NEW_SUGG_ORG,
|
||||
APPROVE_SUGG_ORG,
|
||||
EDIT_ORG,
|
||||
EDIT_SUGG_ORG,
|
||||
DUPLICATES,
|
||||
FIX_CONFLICT,
|
||||
NO_CONFLICT,
|
||||
UNKNOWN
|
||||
}
|
|
@ -391,6 +391,23 @@ CREATE TABLE urls (
|
|||
);
|
||||
CREATE INDEX urls_id_idx ON urls(id);
|
||||
|
||||
CREATE TABLE notes (
|
||||
id text PRIMARY KEY REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
note text,
|
||||
modified_by text,
|
||||
modification_date timestamp
|
||||
);
|
||||
|
||||
CREATE TABLE journal (
|
||||
jid SERIAL PRIMARY KEY,
|
||||
id text REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
operation text,
|
||||
description text,
|
||||
op_date timestamp DEFAULT NOW(),
|
||||
email text
|
||||
);
|
||||
CREATE INDEX journal_id_idx ON journal(id);
|
||||
|
||||
CREATE TABLE oa_duplicates (
|
||||
local_id text REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
oa_original_id text REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<div class="card-footer bg-secondary py-1">
|
||||
<button class="btn btn-sm btn-outline-primary" data-toggle="modal" data-target="#addConflictModal">add</button>
|
||||
<div class="btn-group" ng-if="showButtons && conflicts.length > 0">
|
||||
<button class="btn btn-sm btn-primary" ng-click="prepareConflictsModal()" data-toggle="modal" data-target="#resolveConflictsModal">resolve conflicts</button>
|
||||
<button class="btn btn-sm btn-primary" ng-click="prepareConflictsModal()" data-toggle="modal" data-target="#resolveConflictsModal">resolve manually</button>
|
||||
<button class="btn btn-sm btn-warning" ng-click="resolveConflicts(true)">merge all</button>
|
||||
<button class="btn btn-sm btn-danger" ng-click="resolveConflicts(false)">all different</button>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue