From 72389cf933137d8ddaf4070bb471292e04baab24 Mon Sep 17 00:00:00 2001 From: MithunKashyap Date: Tue, 3 Mar 2015 10:40:16 +0530 Subject: [PATCH] MIFOSX-1737: Center Staff Assignment History --- .../CenterIntegrationTest.java | 67 +++++++- .../integrationtests/common/CenterDomain.java | 81 ++++++++-- .../integrationtests/common/CenterHelper.java | 146 +++++++++++++++++- .../portfolio/group/domain/Group.java | 52 +++++++ .../group/domain/StaffAssignmentHistory.java | 80 ++++++++++ ...WritePlatformServiceJpaRepositoryImpl.java | 6 +- .../Staff Assignment History.prpt | Bin 0 -> 6565 bytes .../staff assigment history.properties | 17 ++ .../V244__staff_assignment_history_table.sql | 22 +++ 9 files changed, 446 insertions(+), 25 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/StaffAssignmentHistory.java create mode 100644 mifosng-provider/src/main/pentahoReports/Staff Assignment History.prpt create mode 100644 mifosng-provider/src/main/pentahoReports/staff assigment history.properties create mode 100644 mifosng-provider/src/main/resources/sql/migrations/core_db/V244__staff_assignment_history_table.sql diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/CenterIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/CenterIntegrationTest.java index 64b075bf4..82866cb66 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/CenterIntegrationTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/CenterIntegrationTest.java @@ -5,6 +5,8 @@ */ package org.mifosplatform.integrationtests; +import static org.junit.Assert.assertEquals; + import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; @@ -147,7 +149,7 @@ public class CenterIntegrationTest { Assert.assertNotNull(center); Assert.assertEquals(newName, center.getName()); Assert.assertEquals(newExternalId, center.getExternalId()); - Assert.assertEquals(newStaffId, center.getStaffId()); + Assert.assertEquals((Integer)newStaffId, center.getStaffId()); Assert.assertArrayEquals(newGroupMembers, center.getGroupMembers()); } @@ -180,4 +182,67 @@ public class CenterIntegrationTest { } return groupMembers; } + + @Test + public void testStaffAssignmentDuringCenterCreation() { + + Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec); + System.out.println("--------------creating first staff with id-------------" + staffId); + Assert.assertNotNull(staffId); + + int centerWithStaffId = CenterHelper.createCenterWithStaffId(this.requestSpec, this.responseSpec, staffId); + CenterDomain center = CenterHelper.retrieveByID(centerWithStaffId, requestSpec, responseSpec); + Assert.assertNotNull(center); + Assert.assertTrue(center.getId() == centerWithStaffId); + Assert.assertTrue(center.getStaffId() == staffId); + Assert.assertTrue(center.isActive() == true); + } + + @Test + public void testAssignStaffToCenter() { + Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec); + System.out.println("--------------creating first staff with id-------------" + staffId); + Assert.assertNotNull(staffId); + + Integer groupID = CenterHelper.createCenter(this.requestSpec, this.responseSpec); + CenterHelper.verifyCenterCreatedOnServer(this.requestSpec, this.responseSpec, groupID); + + HashMap assignStaffToCenterResponseMap = (HashMap) CenterHelper.assignStaff(this.requestSpec, this.responseSpec, groupID.toString(), + staffId.longValue()); + assertEquals("Verify assigned staff id is the same as id sent", assignStaffToCenterResponseMap.get("staffId"), staffId); + + CenterDomain center = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec); + Assert.assertNotNull(center); + Assert.assertTrue(center.getId() == groupID); + Assert.assertTrue(center.getStaffId() == staffId); + + } + + @Test + public void testUnassignStaffToCenter() { + Integer staffId = StaffHelper.createStaff(this.requestSpec, this.responseSpec); + System.out.println("--------------creating first staff with id-------------" + staffId); + Assert.assertNotNull(staffId); + + Integer groupID = CenterHelper.createCenter(this.requestSpec, this.responseSpec); + CenterHelper.verifyCenterCreatedOnServer(this.requestSpec, this.responseSpec, groupID); + + HashMap assignStaffToCenterResponseMap = (HashMap) CenterHelper.assignStaff(this.requestSpec, this.responseSpec, groupID.toString(), + staffId.longValue()); + assertEquals("Verify assigned staff id is the same as id sent", assignStaffToCenterResponseMap.get("staffId"), staffId); + CenterDomain centerWithStaffAssigned = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec); + Assert.assertNotNull(centerWithStaffAssigned); + Assert.assertTrue(centerWithStaffAssigned.getId() == groupID); + Assert.assertTrue(centerWithStaffAssigned.getStaffId() == staffId); + + HashMap unassignStaffToCenterResponseMap = (HashMap) CenterHelper.unassignStaff(this.requestSpec, this.responseSpec, groupID.toString(), + staffId.longValue()); + assertEquals("Verify staffId is null after unassigning ", unassignStaffToCenterResponseMap.get("staffId"), null); + CenterDomain centerWithStaffUnssigned = CenterHelper.retrieveByID(groupID, requestSpec, responseSpec); + Assert.assertNotNull(centerWithStaffUnssigned); + Assert.assertTrue(centerWithStaffUnssigned.getId() == groupID); + Assert.assertTrue(centerWithStaffUnssigned.getStaffId() == null); + + } + } diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterDomain.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterDomain.java index e9031eb05..89b8df04f 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterDomain.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterDomain.java @@ -8,25 +8,27 @@ package org.mifosplatform.integrationtests.common; import java.util.ArrayList; import java.util.HashMap; +import org.mifosplatform.infrastructure.core.service.DateUtils; + import com.google.gson.Gson; public class CenterDomain implements Comparable { public static class Builder { - private int id; + private Integer id; private HashMap status; private boolean active; private String name; private String externalId; - private int staffId; - private int officeId; + private Integer staffId; + private Integer officeId; private String officeName; private String hierarchy; private ArrayList groupMembers; - private Builder(final int id, final int statusid, final String statuscode, final String statusvalue, final boolean active, - final String name, final String externalId, final int staffId, final int officeID, final String officeName, + private Builder(final Integer id, final Integer statusid, final String statuscode, final String statusvalue, final boolean active, + final String name, final String externalId, final Integer staffId, final int officeID, final String officeName, final String hierarchy, final ArrayList groupMembers) { this.id = id; this.status = new HashMap(); @@ -48,25 +50,26 @@ public class CenterDomain implements Comparable { (String) this.status.get("value"), this.active, this.name, this.externalId, this.staffId, this.officeId, this.officeName, this.hierarchy, groupMembers); } + } - private int id; + private Integer id; private HashMap status; private boolean active; private String name; private String externalId; - private int staffId; - private int officeId; + private Integer staffId; + private Integer officeId; private String officeName; private String hierarchy; private ArrayList groupMembers; CenterDomain() { - super(); + /* super(); */ } - private CenterDomain(final int id, final int statusid, final String statuscode, final String statusvalue, final boolean active, - final String name, final String externalId, final int staffId, final int officeID, final String officeName, + private CenterDomain(final Integer id, final Integer statusid, final String statuscode, final String statusvalue, final boolean active, + final String name, final String externalId, final Integer staffId, final Integer officeID, final String officeName, final String hierarchy, final ArrayList groupMembers) { this.id = id; this.status = new HashMap(); @@ -91,22 +94,66 @@ public class CenterDomain implements Comparable { return new Gson().fromJson(jsonData, CurrencyDomain.class); } - public static Builder create(final int id, final int statusid, final String statuscode, final String statusvalue, final boolean active, - final String name, final String externalId, final int staffId, final int officeID, final String officeName, - final String hierarchy, final ArrayList groupMembers) { + public static Builder create(final Integer id, final Integer statusid, final String statuscode, final String statusvalue, + final boolean active, final String name, final String externalId, final Integer staffId, final Integer officeID, + final String officeName, final String hierarchy, final ArrayList groupMembers) { return new Builder(id, statusid, statuscode, statusvalue, active, name, externalId, staffId, officeID, officeName, hierarchy, groupMembers); } + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static String jsonRequestToCreateCenter(Integer id, Integer statusId, String statusCode, String statusValue, Boolean active, + String activationDate, String submittedDate, String name, String externalId, Integer staffId, Integer officeID, + String officeName, String hierarchy, final int[] groupMembers) { + // String ids = String.valueOf(id); + final HashMap map = new HashMap<>(); + if (id != null) map.put("id", id); + if (statusId != null) map.put("statusId", statusId); + if (statusCode != null) map.put("statusCode", statusCode); + if (statusValue != null) map.put("statusValue", statusValue); + map.put("officeId", "1"); + map.put("name", randomNameGenerator("Center_Name_", 5)); + map.put("externalId", randomIDGenerator("ID_", 7)); + map.put("dateFormat", "dd MMMM yyyy"); + map.put("locale", "en"); + if (staffId != null) { + map.put("staffId", String.valueOf(staffId)); + } + if (active) { + map.put("active", "true"); + map.put("locale", "en"); + map.put("dateFormat", "dd MMM yyyy"); + map.put("activationDate", activationDate); + } else { + map.put("active", "false"); + if (submittedDate == null) + map.put("submittedOnDate", DateUtils.getDateOfTenant()); + else + map.put("submittedOnDate", submittedDate); + } + if (externalId != null) map.put("externalId", externalId); + if (groupMembers != null) map.put("groupMembers", groupMembers); + System.out.println(map); + return new Gson().toJson(map); + } + + public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) { + return Utils.randomStringGenerator(prefix, lenOfRandomSuffix); + } + + private static String randomIDGenerator(final String prefix, final int lenOfRandomSuffix) { + return Utils.randomStringGenerator(prefix, lenOfRandomSuffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } + public String getExternalId() { return this.externalId; } - public int getStaffId() { + public Integer getStaffId() { return this.staffId; } - public int getId() { + public Integer getId() { return this.id; } @@ -122,7 +169,7 @@ public class CenterDomain implements Comparable { return this.name; } - public int getOfficeId() { + public Integer getOfficeId() { return this.officeId; } diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterHelper.java index 08df09043..9dd97794c 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterHelper.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/CenterHelper.java @@ -6,8 +6,9 @@ package org.mifosplatform.integrationtests.common; import java.util.ArrayList; +import static org.junit.Assert.assertEquals; import java.util.HashMap; - +import org.apache.commons.lang3.StringUtils; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.jayway.restassured.specification.RequestSpecification; @@ -18,6 +19,9 @@ public class CenterHelper { private static final String CENTERS_URL = "/mifosng-provider/api/v1/centers"; + public static final String CREATED_DATE = "29 December 2014"; + private static final String CREATE_CENTER_URL = "/mifosng-provider/api/v1/centers?" + Utils.TENANT_IDENTIFIER; + public static CenterDomain retrieveByID(int id, final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { final String GET_CENTER_BY_ID_URL = CENTERS_URL + "/" + id + "?associations=groupMembers&" + Utils.TENANT_IDENTIFIER; System.out.println("------------------------ RETRIEVING CENTER AT " + id + "-------------------------"); @@ -73,7 +77,7 @@ public class CenterHelper { hm.put("dateFormat", "dd MMM yyyy"); hm.put("activationDate", activationDate); } - + System.out.println("------------------------CREATING CENTER-------------------------"); return Utils.performServerPost(requestSpec, responseSpec, CREATE_CENTER_URL, new Gson().toJson(hm), "resourceId"); } @@ -110,4 +114,142 @@ public class CenterHelper { Utils.performServerDelete(requestSpec, responseSpec, DELETE_CENTER_URL, ""); } + public static Integer createCenter(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + @SuppressWarnings("unused") final boolean active) { + System.out.println("---------------------------------CREATING A CENTER---------------------------------------------"); + return createCenter(requestSpec, responseSpec, "CREATED_DATE"); + } + + public static Integer createCenter(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String activationDate) { + System.out.println("---------------------------------CREATING A CENTER---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, CREATE_CENTER_URL, getTestCenterAsJSON(true, activationDate), "groupId"); + } + + public static Integer createCenter(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) { + System.out.println("---------------------------------CREATING A CENTER---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, CREATE_CENTER_URL, getTestCenterAsJSON(true, CenterHelper.CREATED_DATE), + "groupId"); + } + + public static int createCenterWithStaffId(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final Integer staffId) { + System.out.println("---------------------------------CREATING A CENTER---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, CREATE_CENTER_URL, + getTestCenterWithStaffAsJSON(true, CenterHelper.CREATED_DATE, staffId), "groupId"); + } + + public static void verifyCenterCreatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final Integer generatedCenterID) { + System.out.println("------------------------------CHECK CENTER DETAILS------------------------------------\n"); + final String CENTER_URL = "/mifosng-provider/api/v1/centers/" + generatedCenterID + "?" + Utils.TENANT_IDENTIFIER; + final Integer responseCenterID = Utils.performServerGet(requestSpec, responseSpec, CENTER_URL, "id"); + assertEquals("ERROR IN CREATING THE CENTER", generatedCenterID, responseCenterID); + } + + public static void verifyCenterActivatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final Integer generatedCenterID, final boolean generatedCenterStatus) { + System.out.println("------------------------------CHECK CENTER STATUS------------------------------------\n"); + final String CENTER_URL = "/mifosng-provider/api/v1/centers/" + generatedCenterID + "?" + Utils.TENANT_IDENTIFIER; + final Boolean responseCenterStatus = Utils.performServerGet(requestSpec, responseSpec, CENTER_URL, "active"); + assertEquals("ERROR IN ACTIVATING THE CENTER", generatedCenterStatus, responseCenterStatus); + } + + public static Integer activateCenter(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String centerId) { + final String CENTER_ASSOCIATE_URL = "/mifosng-provider/api/v1/centers/" + centerId + "?command=activate&" + Utils.TENANT_IDENTIFIER; + System.out.println("---------------------------------ACTIVATE A CENTER---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, CENTER_ASSOCIATE_URL, activateCenterAsJSON(""), "groupId"); + } + + public static String getTestCenterWithStaffAsJSON(final boolean active, final String activationDate, final Integer staffId) { + + Integer id = null; + Integer statusid = null; + String statuscode = null; + String statusvalue = null; + String name = null; + String externalId = null; + Integer officeID = null; + String officeName = null; + String hierarchy = null; + int[] groupMembers = null; + String submittedDate = null; + + return CenterDomain.jsonRequestToCreateCenter(id, statusid, statuscode, statusvalue, active, activationDate,submittedDate,name, + externalId, staffId, officeID, officeName, hierarchy, groupMembers); + } + + public static String getTestCenterAsJSON(final boolean active, final String activationDate) { + + Integer id = null; + Integer statusid = null; + String statuscode = null; + String statusvalue = null; + String name = null; + String externalId = null; + Integer officeID = null; + String officeName = null; + Integer staffId = null; + String hierarchy = null; + final int[] groupMembers = null; + String submittedDate = null; + + return CenterDomain.jsonRequestToCreateCenter(id, statusid, statuscode, statusvalue, active, activationDate,submittedDate,name, + externalId, staffId, officeID, officeName, hierarchy, groupMembers); + + } + + public static String assignStaffAsJSON(final Long staffId) { + final HashMap map = new HashMap<>(); + map.put("staffId", staffId); + System.out.println("map : " + map); + return new Gson().toJson(map); + } + + public static String unassignStaffAsJSON(final Long staffId) { + final HashMap map = new HashMap<>(); + map.put("staffId", staffId); + System.out.println("map : " + map); + return new Gson().toJson(map); + } + + public static String activateCenterAsJSON(final String activationDate) { + final HashMap map = new HashMap<>(); + map.put("dateFormat", "dd MMMM yyyy"); + map.put("locale", "en"); + if (StringUtils.isNotEmpty(activationDate)) { + map.put("activationDate", activationDate); + } else { + map.put("activationDate", "CREATED_DATE"); + System.out.println("defaulting to fixed date: CREATED_DATE"); + } + System.out.println("map : " + map); + return new Gson().toJson(map); + } + + public static String randomNameGenerator(final String prefix, final int lenOfRandomSuffix) { + return Utils.randomStringGenerator(prefix, lenOfRandomSuffix); + } + + private static String randomIDGenerator(final String prefix, final int lenOfRandomSuffix) { + return Utils.randomStringGenerator(prefix, lenOfRandomSuffix, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + } + + public static Object assignStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String groupId, final Long staffId) { + final String GROUP_ASSIGN_STAFF_URL = "/mifosng-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER + + "&command=assignStaff"; + System.out.println("---------------------------------Assign Staff---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSIGN_STAFF_URL, assignStaffAsJSON(staffId), "changes"); + } + + public static Object unassignStaff(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String groupId, final Long staffId) { + final String GROUP_ASSIGN_STAFF_URL = "/mifosng-provider/api/v1/groups/" + groupId + "?" + Utils.TENANT_IDENTIFIER + + "&command=unassignStaff"; + System.out.println("---------------------------------Unassign Staff---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, GROUP_ASSIGN_STAFF_URL, unassignStaffAsJSON(staffId), "changes"); + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java index 17c06e6cd..45a23ddd1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -118,6 +119,9 @@ public final class Group extends AbstractPersistable { @JoinColumn(name = "submittedon_userid", nullable = true) private AppUser submittedBy; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "center", orphanRemoval = true) + private Set staffHistory; + // JPA default constructor for entity protected Group() { this.name = null; @@ -174,6 +178,7 @@ public final class Group extends AbstractPersistable { this.submittedOnDate = submittedOnDate.toDate(); this.submittedBy = currentUser; + this.staffHistory = null; associateClients(clientMembers); @@ -372,10 +377,18 @@ public final class Group extends AbstractPersistable { } public void updateStaff(final Staff staff) { + if (this.isCenter() && this.isActive()) { + LocalDate updatedDate = DateUtils.getLocalDateOfTenant(); + reassignStaff(staff, updatedDate); + } this.staff = staff; } public void unassignStaff() { + if (this.isCenter() && this.isActive()) { + LocalDate dateOfStaffUnassigned = DateUtils.getLocalDateOfTenant(); + removeStaff(dateOfStaffUnassigned); + } this.staff = null; } @@ -620,4 +633,43 @@ public final class Group extends AbstractPersistable { public Set getClientMembers() { return this.clientMembers; } + + // StaffAssignmentHistory[during center creation] + public void caputreStaffHistoryDuringCenterCreation(final Staff newStaff, final LocalDate assignmentDate) { + if (this.isCenter() && this.isActive() && staff != null) { + this.staff = newStaff; + final StaffAssignmentHistory staffAssignmentHistory = StaffAssignmentHistory.createNew(this, this.staff, assignmentDate); + if (staffAssignmentHistory != null) { + staffHistory = new HashSet<>(); + this.staffHistory.add(staffAssignmentHistory); + } + } + } + + // StaffAssignmentHistory[assign staff] + public void reassignStaff(final Staff newStaff, final LocalDate assignmentDate) { + this.staff = newStaff; + final StaffAssignmentHistory staffAssignmentHistory = StaffAssignmentHistory.createNew(this, this.staff, assignmentDate); + this.staffHistory.add(staffAssignmentHistory); + } + + // StaffAssignmentHistory[unassign staff] + public void removeStaff(final LocalDate unassignDate) { + final StaffAssignmentHistory latestHistoryRecord = findLatestIncompleteHistoryRecord(); + if (latestHistoryRecord != null) { + latestHistoryRecord.updateEndDate(unassignDate); + } + } + + private StaffAssignmentHistory findLatestIncompleteHistoryRecord() { + + StaffAssignmentHistory latestRecordWithNoEndDate = null; + for (final StaffAssignmentHistory historyRecord : this.staffHistory) { + if (historyRecord.isCurrentRecord()) { + latestRecordWithNoEndDate = historyRecord; + break; + } + } + return latestRecordWithNoEndDate; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/StaffAssignmentHistory.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/StaffAssignmentHistory.java new file mode 100644 index 000000000..b60c147f3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/StaffAssignmentHistory.java @@ -0,0 +1,80 @@ +/** + * 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.portfolio.group.domain; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; +import org.mifosplatform.organisation.staff.domain.Staff; +import org.mifosplatform.useradministration.domain.AppUser; + +@Entity +@Table(name = "m_staff_assignment_history") +public class StaffAssignmentHistory extends AbstractAuditableCustom { + + @ManyToOne + @JoinColumn(name = "centre_id", nullable = true) + private Group center; + + @ManyToOne + @JoinColumn(name = "staff_id", nullable = true) + private Staff staff; + + @Temporal(TemporalType.DATE) + @Column(name = "start_date") + private Date startDate; + + @Temporal(TemporalType.DATE) + @Column(name = "end_date") + private Date endDate; + + public static StaffAssignmentHistory createNew(final Group center, final Staff staff, final LocalDate startDate) { + return new StaffAssignmentHistory(center, staff, startDate.toDate(), null); + } + + protected StaffAssignmentHistory() { + // + } + + private StaffAssignmentHistory(final Group center, final Staff staff, final Date startDate, final Date endDate) { + this.center = center; + this.staff = staff; + this.startDate = startDate; + this.endDate = endDate; + } + + public void updateStaff(final Staff staff) { + this.staff = staff; + } + + public void updateStartDate(final LocalDate startDate) { + this.startDate = startDate.toDate(); + } + + public void updateEndDate(final LocalDate endDate) { + this.endDate = endDate.toDate(); + } + + public boolean matchesStartDateOf(final LocalDate matchingDate) { + return getStartDate().isEqual(matchingDate); + } + + public LocalDate getStartDate() { + return new LocalDate(this.startDate); + } + + public boolean isCurrentRecord() { + return this.endDate == null; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java index f40bdd709..239561407 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java @@ -189,7 +189,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group newGroup.generateHierarchy(); this.groupRepository.saveAndFlush(newGroup); - + newGroup.caputreStaffHistoryDuringCenterCreation(staff, activationDate); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withOfficeId(groupOffice.getId()) // @@ -404,9 +404,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group final Map actualChanges = new LinkedHashMap<>(9); this.fromApiJsonDeserializer.validateForUnassignStaff(command.json()); - final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(grouptId); - final Staff presentStaff = groupForUpdate.getStaff(); Long presentStaffId = null; if (presentStaff == null) { throw new GroupHasNoStaffException(grouptId); } @@ -442,7 +440,6 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group Staff staff = null; final Long staffId = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName); - final boolean inheritStaffForClientAccounts = command .booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.inheritStaffForClientAccounts); staff = this.staffRepository.findByOfficeHierarchyWithNotFoundDetection(staffId, groupForUpdate.getOffice().getHierarchy()); @@ -476,7 +473,6 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group } } } - this.groupRepository.saveAndFlush(groupForUpdate); actualChanges.put(GroupingTypesApiConstants.staffIdParamName, staffId); diff --git a/mifosng-provider/src/main/pentahoReports/Staff Assignment History.prpt b/mifosng-provider/src/main/pentahoReports/Staff Assignment History.prpt new file mode 100644 index 0000000000000000000000000000000000000000..d50d9716902d051e82f0507d6dccdc0c0ceda344 GIT binary patch literal 6565 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 t`R_NX;{9IF{`C8O**