diff --git a/sci-types-department/pom.xml b/sci-types-department/pom.xml
index 18241a6..71c8b51 100644
--- a/sci-types-department/pom.xml
+++ b/sci-types-department/pom.xml
@@ -45,6 +45,13 @@
${project.parent.version}
provided
+
+
+ org.scientificcms
+ sci-types-project
+ ${project.parent.version}
+ provided
+
org.hibernate
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/Contact.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/Contact.java
new file mode 100644
index 0000000..6720fbd
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/Contact.java
@@ -0,0 +1,194 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import org.hibernate.envers.Audited;
+import org.libreccm.core.CcmObjects;
+import org.librecms.assets.ContactableEntity;
+
+import java.io.Serializable;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Entity(name = "DepartmentContact")
+@Audited
+@Table(name = "DEPARTMENT_CONTACTS", schema = DB_SCHEMA)
+@JsonIdentityInfo(
+ generator = ObjectIdGenerators.PropertyGenerator.class,
+ property = "uuid"
+)
+public class Contact implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "CONTACT_ID")
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long contactId;
+
+ @Column(name = "CONTACT_TYPE", length = 255, nullable = true)
+ private String contactType;
+
+ @Column(name = "CONTACT_ORDER")
+ private long order;
+
+ @ManyToOne
+ @JoinColumn(name = "DEPARTMENT_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private SciDepartment department;
+
+ @ManyToOne
+ @JoinColumn(name = "CONTACTABLE_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private ContactableEntity contactable;
+
+ public long getContactId() {
+ return contactId;
+ }
+
+ protected void setContactId(final long contactId) {
+ this.contactId = contactId;
+ }
+
+ public String getContactType() {
+ return contactType;
+ }
+
+ public void setContactType(final String contactType) {
+ this.contactType = contactType;
+ }
+
+ public long getOrder() {
+ return order;
+ }
+
+ public void setOrder(final long order) {
+ this.order = order;
+ }
+
+ public SciDepartment getDepartment() {
+ return department;
+ }
+
+ protected void setDepartment(final SciDepartment department) {
+ this.department = department;
+ }
+
+ public ContactableEntity getContactable() {
+ return contactable;
+ }
+
+ protected void setContactable(final ContactableEntity contactable) {
+ this.contactable = contactable;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 41 * hash + (int) (contactId ^ (contactId >>> 32));
+ hash = 41 * hash + Objects.hashCode(contactType);
+ hash = 41 * hash + (int) (order ^ (order >>> 32));
+ hash = 41 * hash + CcmObjects.hashCodeUsingUuid(department);
+ hash = 41 * hash + CcmObjects.hashCodeUsingUuid(contactable);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Contact)) {
+ return false;
+ }
+ final Contact other = (Contact) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+ if (contactId != other.getContactId()) {
+ return false;
+ }
+ if (!Objects.equals(contactType, other.getContactType())) {
+ return false;
+ }
+ if (!CcmObjects.equalsUsingUuid(department, other.getDepartment())) {
+ return false;
+ }
+ if (!CcmObjects.equalsUsingUuid(contactable, other.getContactable())) {
+ return false;
+ }
+ return order == other.getOrder();
+ }
+
+ public boolean canEqual(final Object obj) {
+
+ return obj instanceof Contact;
+ }
+
+ @Override
+ public final String toString() {
+ return toString("");
+ }
+
+ public String toString(final String data) {
+ return String.format(
+ "%s{ "
+ + "contactId = %d, "
+ + "contactType = \"%s\", "
+ + "order = %d, "
+ + "project = { %s } "
+ + "contactableUuid = %s%s"
+ + " }",
+ super.toString(),
+ contactId,
+ contactType,
+ order,
+ Optional
+ .ofNullable(department)
+ .map(
+ dep -> String.format(
+ "objectId = %d,"
+ + "uuid = \"%s\", "
+ + "name = \"%s\"",
+ dep.getObjectId(),
+ dep.getUuid(),
+ dep.getDisplayName()
+ )
+ )
+ .orElse(""),
+ Optional
+ .ofNullable(contactable)
+ .map(
+ entity -> String.format(
+ "objectId = %d,"
+ + "uuid = \"%s\", "
+ + "name = \"%s\"",
+ entity.getObjectId(),
+ entity.getUuid(),
+ entity.getDisplayName()
+ )
+ )
+ .orElse(""),
+ data
+ );
+ }
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/ContactRepository.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/ContactRepository.java
new file mode 100644
index 0000000..7baf47d
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/ContactRepository.java
@@ -0,0 +1,42 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class ContactRepository
+ extends AbstractAuditedEntityRepository {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Long getEntityId(final Contact contact) {
+ return contact.getContactId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return Contact.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "contactId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final Contact contact) {
+ return contact.getContactId();
+ }
+
+ @Override
+ public boolean isNew(final Contact contact) {
+ return contact.getContactId() == 0;
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentProject.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentProject.java
new file mode 100644
index 0000000..814a2eb
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentProject.java
@@ -0,0 +1,157 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import org.hibernate.envers.Audited;
+import org.libreccm.core.CcmObjects;
+import org.scientificcms.contenttypes.sciproject.SciProject;
+
+import java.io.Serializable;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Audited
+@Table(name = "DEPARTMENT_PROJECTS", schema = DB_SCHEMA)
+public class DepartmentProject implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "DEPARTMENT_PROJECT_ID")
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long departmentProjectId;
+
+ @ManyToOne
+ @JoinColumn(name = "DEPARTMENT_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private SciDepartment department;
+
+ @ManyToOne
+ @JoinColumn(name = "PROJECT_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private SciProject project;
+
+ public long getDepartmentProjectId() {
+ return departmentProjectId;
+ }
+
+ protected void setDepartmentProjectId(final long departmentProjectId) {
+ this.departmentProjectId = departmentProjectId;
+ }
+
+ public SciDepartment getDepartment() {
+ return department;
+ }
+
+ protected void setDepartment(final SciDepartment department) {
+ this.department = department;
+ }
+
+ public SciProject getProject() {
+ return project;
+ }
+
+ protected void setProject(final SciProject project) {
+ this.project = project;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash
+ = 59 * hash + (int) (departmentProjectId ^ (departmentProjectId
+ >>> 32));
+ hash = 59 * hash + CcmObjects.hashCodeUsingUuid(department);
+ hash = 59 * hash + CcmObjects.hashCodeUsingUuid(project);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof DepartmentProject)) {
+ return false;
+ }
+ final DepartmentProject other = (DepartmentProject) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+
+ if (departmentProjectId != other.getDepartmentProjectId()) {
+ return false;
+ }
+ if (!CcmObjects.equalsUsingUuid(department, other.getDepartment())) {
+ return false;
+ }
+ return CcmObjects.equalsUsingUuid(project, other.getProject());
+ }
+
+ public boolean canEqual(final Object obj) {
+ return obj instanceof DepartmentProject;
+ }
+
+ @Override
+ public String toString() {
+ return toString("");
+ }
+
+ public String toString(final String data) {
+ return String.format(
+ "%s{ "
+ + "departmentProjectId = %d, "
+ + "department = { %s }, "
+ + "project = { %s}%s"
+ + " }",
+ super.toString(),
+ departmentProjectId,
+ Optional
+ .ofNullable(department)
+ .map(
+ dep -> String.format(
+ "objectId = %d,"
+ + "uuid = \"%s\", "
+ + "name = \"%s\"",
+ dep.getObjectId(),
+ dep.getUuid(),
+ dep.getDisplayName()
+ )
+ )
+ .orElse(""),
+ Optional
+ .ofNullable(project)
+ .map(
+ proj -> String.format(
+ "objectId = %d,"
+ + "uuid = \"%s\", "
+ + "name = \"%s\"",
+ project.getObjectId(),
+ project.getUuid(),
+ project.getDisplayName()
+ )
+ )
+ .orElse(""),
+ data
+ );
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentProjectRepository.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentProjectRepository.java
new file mode 100644
index 0000000..b3266c8
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentProjectRepository.java
@@ -0,0 +1,42 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class DepartmentProjectRepository
+ extends AbstractAuditedEntityRepository {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Long getEntityId(final DepartmentProject project) {
+ return project.getDepartmentProjectId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return DepartmentProject.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "departmentProjectId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final DepartmentProject project) {
+ return project.getDepartmentProjectId();
+ }
+
+ @Override
+ public boolean isNew(final DepartmentProject project) {
+ return project.getDepartmentProjectId() == 0;
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentText.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentText.java
new file mode 100644
index 0000000..dc1f781
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentText.java
@@ -0,0 +1,185 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import org.hibernate.envers.Audited;
+import org.libreccm.core.CcmObjects;
+import org.libreccm.l10n.LocalizedString;
+
+import java.io.Serializable;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.persistence.AssociationOverride;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Entity
+@Audited
+@Table(name = "DEPARTMENT_TEXTS", schema = DB_SCHEMA)
+public class DepartmentText implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "TEXT_ID")
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long textId;
+
+ @Column(name = "key", length = 255, nullable = false)
+ private String key;
+
+ @Column(name = "CONTACT_ORDER")
+ private long order;
+
+ @ManyToOne
+ @JoinColumn(name = "DEPARTMENT_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private SciDepartment department;
+
+ @Embedded
+ @AssociationOverride(
+ name = "values",
+ joinTable = @JoinTable(
+ name = "DEPARTMENT_TEXT_VALUES",
+ schema = DB_SCHEMA,
+ joinColumns = {
+ @JoinColumn(name = "OBJECT_ID")
+ }
+ )
+ )
+ private LocalizedString text;
+
+ public long getTextId() {
+ return textId;
+ }
+
+ protected void setTextId(final long textId) {
+ this.textId = textId;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public long getOrder() {
+ return order;
+ }
+
+ public void setOrder(final long order) {
+ this.order = order;
+ }
+
+ public SciDepartment getDepartment() {
+ return department;
+ }
+
+ public void setDepartment(final SciDepartment department) {
+ this.department = department;
+ }
+
+ public LocalizedString getText() {
+ return text;
+ }
+
+ public void setText(final LocalizedString text) {
+ this.text = text;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 67 * hash + (int) (textId ^ (textId >>> 32));
+ hash = 67 * hash + Objects.hashCode(key);
+ hash = 67 * hash + (int) (order ^ (order >>> 32));
+ hash = 67 * hash + CcmObjects.hashCodeUsingUuid(department);
+ hash = 67 * hash + Objects.hashCode(text);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof DepartmentText)) {
+ return false;
+ }
+ final DepartmentText other = (DepartmentText) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+
+ if (textId != other.getTextId()) {
+ return false;
+ }
+ if (order != other.getOrder()) {
+ return false;
+ }
+ if (!Objects.equals(key, other.getKey())) {
+ return false;
+ }
+ if (!Objects.equals(department, other.getDepartment())) {
+ return false;
+ }
+ return Objects.equals(text, other.getText());
+ }
+
+ public boolean canEqual(final Object obj) {
+ return obj instanceof DepartmentText;
+ }
+
+ @Override
+ public String toString() {
+ return toString("");
+ }
+
+ public String toString(final String data) {
+ return String.format(
+ "textId = %d, "
+ + "key = %s, "
+ + "order = %d, "
+ + "department = { %s }, "
+ + "text = { %s }%s",
+ textId,
+ key,
+ order,
+ Optional
+ .ofNullable(department)
+ .map(
+ dep -> String.format(
+ "objectId = %d,"
+ + "uuid = \"%s\", "
+ + "name = \"%s\"",
+ dep.getObjectId(),
+ dep.getUuid(),
+ dep.getDisplayName()
+ )
+ )
+ .orElse(""),
+ Objects.toString(text),
+ data
+ );
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentTextRepository.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentTextRepository.java
new file mode 100644
index 0000000..a0dc64b
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/DepartmentTextRepository.java
@@ -0,0 +1,40 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class DepartmentTextRepository
+ extends AbstractAuditedEntityRepository {
+
+ @Override
+ public Long getEntityId(final DepartmentText text) {
+ return text.getTextId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return DepartmentText.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "textId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final DepartmentText text) {
+ return text.getTextId();
+ }
+
+ @Override
+ public boolean isNew(final DepartmentText text) {
+ return text.getTextId() == 0;
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/Membership.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/Membership.java
new file mode 100644
index 0000000..2418459
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/Membership.java
@@ -0,0 +1,207 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonIdentityReference;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import org.hibernate.envers.Audited;
+import org.libreccm.core.CcmObjects;
+import org.librecms.assets.Person;
+
+import java.io.Serializable;
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import static org.scientificcms.contenttypes.scidepartment.SciDepartmentConstants.DB_SCHEMA;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Entity(name = "DepartmentMembership")
+@Audited
+@Table(name = "DEPARTMENT_MEMBERSHIPS", schema = DB_SCHEMA)
+@JsonIdentityInfo(
+ generator = ObjectIdGenerators.PropertyGenerator.class,
+ property = "uuid"
+)
+public class Membership implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "MEMBERSHIP_ID")
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private long membershipId;
+
+ @Column(name = "MEMBER_ROLE", length = 255, nullable = true)
+ private String role;
+
+ @Column(name = "STATUS")
+ @Enumerated(EnumType.STRING)
+ private MembershipStatus status;
+
+ @ManyToOne
+ @JoinColumn(name = "DEPARTMENT_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private SciDepartment department;
+
+ @ManyToOne
+ @JoinColumn(name = "MEMBER_ID")
+ @JsonIdentityReference(alwaysAsId = true)
+ private Person member;
+
+ public long getMembershipId() {
+ return membershipId;
+ }
+
+ protected void setMembershipId(final long membershipId) {
+ this.membershipId = membershipId;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(final String role) {
+ this.role = role;
+ }
+
+ public MembershipStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(final MembershipStatus status) {
+ this.status = status;
+ }
+
+ public SciDepartment getDepartment() {
+ return department;
+ }
+
+ protected void setProject(final SciDepartment department) {
+ this.department = department;
+ }
+
+ public Person getMember() {
+ return member;
+ }
+
+ protected void setMember(final Person member) {
+ this.member = member;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 37 * hash
+ + (int) (membershipId ^ (membershipId >>> 32));
+ hash = 37 * hash + Objects.hashCode(role);
+ hash = 37 * hash + Objects.hashCode(status);
+ hash = 37 * hash + CcmObjects.hashCodeUsingUuid(department);
+ hash = 37 * hash + CcmObjects.hashCodeUsingUuid(member);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Membership)) {
+ return false;
+ }
+ final Membership other = (Membership) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+
+ if (membershipId != other.getMembershipId()) {
+ return false;
+ }
+ if (!Objects.equals(role, other.getRole())) {
+ return false;
+ }
+
+ if (!CcmObjects.equalsUsingUuid(department, other.getDepartment())) {
+ return false;
+ }
+ if (!CcmObjects.equalsUsingUuid(member, other.getMember())) {
+ return false;
+ }
+ return status == other.getStatus();
+ }
+
+ public boolean canEqual(final Object obj) {
+ return obj instanceof Membership;
+ }
+
+ @Override
+ public final String toString() {
+ return toString("");
+ }
+
+ public String toString(final String data) {
+ return String.format(
+ "%s{ "
+ + "membershipId = %d, "
+ + "role = \"%s\", "
+ + "status = \"%s\","
+ + "project = { %s }, "
+ + "member = { %s }%s"
+ + " }",
+ super.toString(),
+ membershipId,
+ role,
+ Objects.toString(status),
+ Optional
+ .ofNullable(department)
+ .map(
+ dep -> String.format(
+ "objectId = %d,"
+ + "uuid = \"%s\", "
+ + "name = \"%s\"",
+ dep.getObjectId(),
+ dep.getUuid(),
+ dep.getDisplayName()
+ )
+ )
+ .orElse(""),
+ Optional
+ .ofNullable(member)
+ .map(
+ person -> String.format(
+ "objectId = %d, "
+ + "uuid = \"%s\", "
+ + "name = \"%s\", "
+ + "surname = \"%s\", "
+ + "givenName = \"%s\", "
+ + "prefix = \"%s\", "
+ + "suffix = \"%s\"",
+ person.getObjectId(),
+ person.getUuid(),
+ person.getDisplayName(),
+ person.getPersonName().getSurname(),
+ person.getPersonName().getGivenName(),
+ person.getPersonName().getPrefix(),
+ person.getPersonName().getSuffix())
+ )
+ .orElse(""),
+ data
+ );
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/MembershipRepository.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/MembershipRepository.java
new file mode 100644
index 0000000..6ba1116
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/MembershipRepository.java
@@ -0,0 +1,40 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class MembershipRepository
+ extends AbstractAuditedEntityRepository {
+
+ @Override
+ public Long getEntityId(final Membership membership) {
+ return membership.getMembershipId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return Membership.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "membershipId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final Membership membership) {
+ return membership.getMembershipId();
+ }
+
+ @Override
+ public boolean isNew(final Membership membership) {
+ return membership.getMembershipId() == 0;
+ }
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/MembershipStatus.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/MembershipStatus.java
new file mode 100644
index 0000000..f353de2
--- /dev/null
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/MembershipStatus.java
@@ -0,0 +1,13 @@
+package org.scientificcms.contenttypes.scidepartment;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public enum MembershipStatus {
+
+ ACTIVE,
+ ASSOCIATED,
+ FORMER,
+
+}
diff --git a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/SciDepartment.java b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/SciDepartment.java
index a4914b3..0f01fce 100644
--- a/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/SciDepartment.java
+++ b/sci-types-department/src/main/java/org/scientificcms/contenttypes/scidepartment/SciDepartment.java
@@ -14,8 +14,12 @@ import org.scientificcms.contenttypes.scidepartment.ui.SciDepartmentExtendedProp
import org.scientificcms.contenttypes.scidepartment.ui.SciDepartmentPropertiesStep;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import javax.persistence.AssociationOverride;
import javax.persistence.CascadeType;
@@ -95,8 +99,7 @@ public class SciDepartment extends ContentItem implements Serializable {
)
)
private LocalizedString addendum;
-
-
+
@OneToMany(cascade = CascadeType.ALL, mappedBy = "department")
@OrderBy("order ASC")
@JsonIgnore
@@ -111,11 +114,197 @@ public class SciDepartment extends ContentItem implements Serializable {
@OrderBy("member ASC")
@JsonIgnore
private List members;
-
+
@OneToMany(cascade = CascadeType.ALL, mappedBy = "project")
- @OrderBy("member ASC")
+ @OrderBy("project ASC")
@JsonIgnore
private List projects;
-
-
+
+ public SciDepartment() {
+ super();
+
+ shortDescription = new LocalizedString();
+ departmentDescription = new LocalizedString();
+ addendum = new LocalizedString();
+ additionalTexts = new HashMap<>();
+ contacts = new ArrayList<>();
+ members = new ArrayList<>();
+ projects = new ArrayList<>();
+ }
+
+ public LocalizedString getShortDescription() {
+ return shortDescription;
+ }
+
+ public void setShortDescription(final LocalizedString shortDescription) {
+ this.shortDescription = shortDescription;
+ }
+
+ public LocalizedString getDepartmentDescription() {
+ return departmentDescription;
+ }
+
+ public void setDepartmentDescription(
+ final LocalizedString departmentDescription
+ ) {
+ this.departmentDescription = departmentDescription;
+ }
+
+ public LocalizedString getAddendum() {
+ return addendum;
+ }
+
+ public void setAddendum(final LocalizedString addendum) {
+ this.addendum = addendum;
+ }
+
+ public Map getAdditionalTexts() {
+ return Collections.unmodifiableMap(additionalTexts);
+ }
+
+ protected void putAdditionalText(
+ final String key, final DepartmentText text
+ ) {
+ additionalTexts.put(key, text);
+ }
+
+ protected void removeAdditionalText(final String key) {
+ additionalTexts.remove(key);
+ }
+
+ protected void setAdditionalTexts(
+ final Map additionalTexts
+ ) {
+ this.additionalTexts = new HashMap<>(additionalTexts);
+ }
+
+ public List getContacts() {
+ return Collections.unmodifiableList(contacts);
+ }
+
+ protected void addContact(final Contact contact) {
+ contacts.add(contact);
+ }
+
+ protected void removeContact(final Contact contact) {
+ contacts.remove(contact);
+ }
+
+ protected void setContacts(final List contacts) {
+ this.contacts = new ArrayList<>(contacts);
+ }
+
+ public List getMembers() {
+ return Collections.unmodifiableList(members);
+ }
+
+ protected void addMember(final Membership member) {
+ members.add(member);
+ }
+
+ protected void removeMember(final Membership member) {
+ members.remove(member);
+ }
+
+ protected void setMembers(final List members) {
+ this.members = new ArrayList<>(members);
+ }
+
+ public List getProjects() {
+ return Collections.unmodifiableList(projects);
+ }
+
+ protected void addProject(final DepartmentProject project) {
+ projects.add(project);
+ }
+
+ protected void removeProject(final DepartmentProject project) {
+ projects.remove(project);
+ }
+
+ protected void setProjects(final List projects) {
+ this.projects = new ArrayList<>(projects);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+ hash = 83 * hash + Objects.hashCode(shortDescription);
+ hash = 83 * hash + Objects.hashCode(departmentDescription);
+ hash = 83 * hash + Objects.hashCode(addendum);
+ hash = 83 * hash + Objects.hashCode(additionalTexts);
+ hash = 83 * hash + Objects.hashCode(contacts);
+ hash = 83 * hash + Objects.hashCode(members);
+ hash = 83 * hash + Objects.hashCode(projects);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof SciDepartment)) {
+ return false;
+ }
+ final SciDepartment other = (SciDepartment) obj;
+ if (!other.canEqual(this)) {
+ return false;
+ }
+
+ if (!Objects.equals(shortDescription, other.getShortDescription())) {
+ return false;
+ }
+ if (!Objects.equals(
+ departmentDescription,
+ other.getDepartmentDescription()
+ )) {
+ return false;
+ }
+ if (!Objects.equals(addendum, other.getAddendum())) {
+ return false;
+ }
+ if (!Objects.equals(additionalTexts, other.getAdditionalTexts())) {
+ return false;
+ }
+ if (!Objects.equals(contacts, other.getContacts())) {
+ return false;
+ }
+ if (!Objects.equals(members, other.getMembers())) {
+ return false;
+ }
+ return Objects.equals(projects, other.getProjects());
+ }
+
+ @Override
+ public boolean canEqual(final Object obj) {
+ return obj instanceof SciDepartment;
+ }
+
+ @Override
+ public String toString(final String data) {
+ return super.toString(
+ String.format(
+ "shortDescription = %s, "
+ + "departmentDescription = %s, "
+ + "addendum = %s, "
+ + "additionalTexts = %s, "
+ + "contacts = %s, "
+ + "members = %s, "
+ + "projects = %s%s",
+ Objects.toString(shortDescription),
+ Objects.toString(departmentDescription),
+ Objects.toString(addendum),
+ Objects.toString(additionalTexts),
+ Objects.toString(contacts),
+ Objects.toString(members),
+ Objects.toString(projects),
+ data
+ )
+ );
+ }
+
}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Contact.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Contact.java
index 1186f54..ee1e076 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Contact.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Contact.java
@@ -30,7 +30,7 @@ import static org.scientificcms.contenttypes.sciproject.SciProjectConstants.*;
*
* @author Jens Pelzetter
*/
-@Entity
+@Entity(name = "ProjectContact")
@Audited
@Table(name = "PROJECT_CONTACTS", schema = DB_SCHEMA)
@JsonIdentityInfo(
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Membership.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Membership.java
index d0ab075..e22b97f 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Membership.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/Membership.java
@@ -32,7 +32,7 @@ import static org.scientificcms.contenttypes.sciproject.SciProjectConstants.*;
*
* @author Jens Pelzetter
*/
-@Entity
+@Entity(name = "PROJECT_MEMBERSHIP")
@Audited
@Table(name = "PROJECT_MEMBERSHIPS", schema = DB_SCHEMA)
@JsonIdentityInfo(
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProject.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProject.java
index 7fc269a..f49b907 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProject.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProject.java
@@ -7,7 +7,6 @@ package org.scientificcms.contenttypes.sciproject;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import javax.persistence.Entity;