diff --git a/mifosng-db/migrations/core_db/V47__staff-hierarchy-link-to-users.sql b/mifosng-db/migrations/core_db/V47__staff-hierarchy-link-to-users.sql new file mode 100644 index 000000000..1531b04d1 --- /dev/null +++ b/mifosng-db/migrations/core_db/V47__staff-hierarchy-link-to-users.sql @@ -0,0 +1,14 @@ +ALTER TABLE `m_appuser` +ADD COLUMN `staff_id` BIGINT(20) NULL DEFAULT NULL AFTER `office_id` ; + +ALTER TABLE m_appuser +ADD CONSTRAINT `fk_m_appuser_002` +FOREIGN KEY (`staff_id`) +REFERENCES m_staff (`id`) +ON DELETE NO ACTION +ON UPDATE NO ACTION +,ADD INDEX `fk_m_appuser_002x` (`staff_id` ASC); + +ALTER TABLE `m_staff` +ADD COLUMN `organisational_role_enum` SMALLINT NULL DEFAULT NULL AFTER `external_id`, +ADD COLUMN `organisational_role_parent_staff_id` BIGINT(20) NULL DEFAULT NULL AFTER `organisational_role_enum`; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java index 0edea3483..6d985da05 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java @@ -16,6 +16,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.data.AuthenticatedUserData; import org.mifosplatform.useradministration.data.RoleData; @@ -73,8 +74,12 @@ public class AuthenticationApiResource { roles.add(role.toData()); } - authenticatedUserData = new AuthenticatedUserData(username, roles, permissions, principal.getId(), new String( - base64EncodedAuthenticationKey)); + final Long officeId = principal.getOffice().getId(); + final String officeName = principal.getOffice().getName(); + final EnumOptionData organisationalRole = principal.organisationalRoleData(); + + authenticatedUserData = new AuthenticatedUserData(username, officeId, officeName, organisationalRole, roles, permissions, + principal.getId(), new String(base64EncodedAuthenticationKey)); } return this.apiJsonSerializerService.serialize(authenticatedUserData); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/data/AuthenticatedUserData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/data/AuthenticatedUserData.java index d60f0b883..a87920111 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/data/AuthenticatedUserData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/data/AuthenticatedUserData.java @@ -7,6 +7,7 @@ package org.mifosplatform.infrastructure.security.data; import java.util.Collection; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.useradministration.data.RoleData; /** @@ -23,6 +24,12 @@ public class AuthenticatedUserData { @SuppressWarnings("unused") private final boolean authenticated; @SuppressWarnings("unused") + private final Long officeId; + @SuppressWarnings("unused") + private final String officeName; + @SuppressWarnings("unused") + private final EnumOptionData organisationalRole; + @SuppressWarnings("unused") private final Collection roles; @SuppressWarnings("unused") private final Collection permissions; @@ -32,13 +39,20 @@ public class AuthenticatedUserData { this.userId = null; this.base64EncodedAuthenticationKey = null; this.authenticated = false; + this.officeId = null; + this.officeName = null; + this.organisationalRole = null; this.roles = null; this.permissions = permissions; } - public AuthenticatedUserData(final String username, final Collection roles, final Collection permissions, + public AuthenticatedUserData(final String username, final Long officeId, final String officeName, + final EnumOptionData organisationalRole, final Collection roles, final Collection permissions, final Long userId, final String base64EncodedAuthenticationKey) { this.username = username; + this.officeId = officeId; + this.officeName = officeName; + this.organisationalRole = organisationalRole; this.userId = userId; this.base64EncodedAuthenticationKey = base64EncodedAuthenticationKey; this.authenticated = true; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/Staff.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/Staff.java index fcefcffe2..79a3d8ddb 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/Staff.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/Staff.java @@ -17,6 +17,7 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.organisation.office.domain.Office; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -24,7 +25,6 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Table(name = "m_staff", uniqueConstraints = { @UniqueConstraint(columnNames = { "display_name" }, name = "display_name") }) public class Staff extends AbstractPersistable { - @Column(name = "firstname", length = 50) private String firstname; @@ -44,6 +44,13 @@ public class Staff extends AbstractPersistable { @Column(name = "is_loan_officer ", nullable = false) private boolean loanOfficer; + @Column(name = "organisational_role_enum", nullable = true) + private Integer organisationalRoleType; + + @ManyToOne + @JoinColumn(name = "organisational_role_parent_staff_id", nullable = true) + private Staff organisationalRoleParentStaff; + public static Staff fromJson(final Office staffOffice, final JsonCommand command) { final String firstnameParamName = "firstname"; @@ -58,7 +65,7 @@ public class Staff extends AbstractPersistable { return new Staff(staffOffice, firstname, lastname, isLoanOfficer); } - public static Staff createNew(Office staffOffice, final String firstname, final String lastname, boolean isLoanOfficer) { + public static Staff createNew(final Office staffOffice, final String firstname, final String lastname, final boolean isLoanOfficer) { return new Staff(staffOffice, firstname, lastname, isLoanOfficer); } @@ -74,6 +81,14 @@ public class Staff extends AbstractPersistable { deriveDisplayName(firstname); } + public EnumOptionData organisationalRoleData() { + EnumOptionData organisationalRole = null; + if (this.organisationalRoleType != null) { + organisationalRole = StaffEnumerations.organisationalRole(this.organisationalRoleType); + } + return organisationalRole; + } + public void changeOffice(final Office newOffice) { this.office = newOffice; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffEnumerations.java new file mode 100644 index 000000000..f6f58236b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffEnumerations.java @@ -0,0 +1,37 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.organisation.staff.domain; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; + +public class StaffEnumerations { + + public static EnumOptionData organisationalRole(final Integer id) { + return organisationalRole(StaffOrganisationalRoleType.fromInt(id)); + } + + public static EnumOptionData organisationalRole(final StaffOrganisationalRoleType type) { + EnumOptionData optionData = new EnumOptionData(StaffOrganisationalRoleType.INVALID.getValue().longValue(), + StaffOrganisationalRoleType.INVALID.getCode(), "Invalid"); + switch (type) { + case PROGRAM_DIRECTOR: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Program Director"); + break; + case BRANCH_MANAGER: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Branch Manager"); + break; + case FIELD_OFFICER_COORDINATOR: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Field Officer Coordinator"); + break; + case FIELD_OFFICER: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Field Officer"); + break; + case INVALID: + break; + } + return optionData; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffOrganisationalRoleType.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffOrganisationalRoleType.java new file mode 100644 index 000000000..14382496c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffOrganisationalRoleType.java @@ -0,0 +1,50 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.organisation.staff.domain; + +public enum StaffOrganisationalRoleType { + + INVALID(0, "staffOrganisationalRoleType.invalid"), // + PROGRAM_DIRECTOR(100, "staffOrganisationalRoleType.programDirector"), // + BRANCH_MANAGER(200, "staffOrganisationalRoleType.branchManager"), // + FIELD_OFFICER_COORDINATOR(300, "staffOrganisationalRoleType.coordinator"), // + FIELD_OFFICER(400, "staffOrganisationalRoleType.fieldAgent"); + + private final Integer value; + private final String code; + + private StaffOrganisationalRoleType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public Integer getValue() { + return value; + } + + public String getCode() { + return code; + } + + public static StaffOrganisationalRoleType fromInt(final Integer chargeCalculation) { + StaffOrganisationalRoleType chargeCalculationType = StaffOrganisationalRoleType.INVALID; + switch (chargeCalculation) { + case 100: + chargeCalculationType = PROGRAM_DIRECTOR; + break; + case 200: + chargeCalculationType = BRANCH_MANAGER; + break; + case 300: + chargeCalculationType = FIELD_OFFICER_COORDINATOR; + break; + case 400: + chargeCalculationType = FIELD_OFFICER; + break; + } + return chargeCalculationType; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/AppUser.java b/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/AppUser.java index 5644803b5..e5b88b0aa 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/AppUser.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/useradministration/domain/AppUser.java @@ -25,10 +25,12 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.security.domain.PlatformUser; import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.service.PlatformPasswordEncoder; import org.mifosplatform.organisation.office.domain.Office; +import org.mifosplatform.organisation.staff.domain.Staff; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.jpa.domain.AbstractPersistable; @@ -77,9 +79,13 @@ public class AppUser extends AbstractPersistable implements PlatformUser { private boolean deleted; @ManyToOne - @JoinColumn(name = "office_id") + @JoinColumn(name = "office_id", nullable = false) private Office office; + @ManyToOne + @JoinColumn(name = "staff_id", nullable = true) + private Staff staff; + @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "m_appuser_role", joinColumns = @JoinColumn(name = "appuser_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private Set roles; @@ -132,6 +138,14 @@ public class AppUser extends AbstractPersistable implements PlatformUser { this.firstTimeLoginRemaining = true; } + public EnumOptionData organisationalRoleData() { + EnumOptionData organisationalRole = null; + if (this.staff != null) { + organisationalRole = this.staff.organisationalRoleData(); + } + return organisationalRole; + } + public void updatePassword(final String encodePassword) { this.password = encodePassword; this.firstTimeLoginRemaining = false;