MIFOSX-1892:Bug fix for Teller cash management

This commit is contained in:
MithunKashyap
2015-03-25 22:09:24 +05:30
parent 5624da89ea
commit 3cb99328eb
10 changed files with 529 additions and 282 deletions
@@ -5,7 +5,6 @@
*/ */
package org.mifosplatform.organisation.teller.domain; package org.mifosplatform.organisation.teller.domain;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
@@ -18,21 +17,21 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
/** /**
* Provides the base model for a cashier. Represents a row in the "m_cashiers" database table, with * Provides the base model for a cashier. Represents a row in the
* each column mapped to a property of this class. * "m_cashiers" database table, with each column mapped to a property
* * of this class.
*
* @author Markus Geiss * @author Markus Geiss
* @since 2.0.0 * @since 2.0.0
*/ */
@Entity @Entity
@Table(name = "m_cashiers", uniqueConstraints = { @Table(name = "m_cashiers", uniqueConstraints = { @UniqueConstraint(name = "ux_cashiers_staff_teller", columnNames = { "staff_id",
@UniqueConstraint(name = "ux_cashiers_staff_teller", columnNames = {"staff_id", "teller_id"}) "teller_id" }) })
})
public class Cashier extends AbstractPersistable<Long> { public class Cashier extends AbstractPersistable<Long> {
// ManyToOne(fetch = FetchType.LAZY) // ManyToOne(fetch = FetchType.LAZY)
// JoinColumn(name = "office_id", nullable = false) // JoinColumn(name = "office_id", nullable = false)
@Transient @Transient
private Office office; private Office office;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@@ -69,45 +68,44 @@ public class Cashier extends AbstractPersistable<Long> {
public Cashier() { public Cashier() {
super(); super();
} }
public static Cashier fromJson(final Office cashierOffice, public static Cashier fromJson(final Office cashierOffice, final Teller teller, final Staff staff, final String startTime,
final Teller teller, final String endTime, final JsonCommand command) {
final Staff staff,
final JsonCommand command) {
// final Long tellerId = teller.getId(); // final Long tellerId = teller.getId();
// final Long staffId = command.longValueOfParameterNamed("staffId"); // final Long staffId = command.longValueOfParameterNamed("staffId");
final String description = command.stringValueOfParameterNamed("description"); final String description = command.stringValueOfParameterNamed("description");
final LocalDate startDate = command.localDateValueOfParameterNamed("startDate"); final LocalDate startDate = command.localDateValueOfParameterNamed("startDate");
final LocalDate endDate = command.localDateValueOfParameterNamed("endDate"); final LocalDate endDate = command.localDateValueOfParameterNamed("endDate");
final Boolean isFullDay = command.booleanObjectValueOfParameterNamed("isFullDay"); final Boolean isFullDay = command.booleanObjectValueOfParameterNamed("isFullDay");
final String startTime = command.stringValueOfParameterNamed("startTime"); /*
final String endTime = command.stringValueOfParameterNamed("endTime"); * final String startTime =
* command.stringValueOfParameterNamed("startTime"); final String
* endTime = command.stringValueOfParameterNamed("endTime");
*/
return new Cashier (cashierOffice, teller, staff, description, startDate, endDate, return new Cashier(cashierOffice, teller, staff, description, startDate, endDate, isFullDay, startTime, endTime);
isFullDay, startTime, endTime);
} }
public Cashier (Office office, Teller teller, Staff staff, public Cashier(Office office, Teller teller, Staff staff, String description, LocalDate startDate, LocalDate endDate,
String description, LocalDate startDate, LocalDate endDate, Boolean isFullDay, String startTime, String endTime) {
Boolean isFullDay, String startTime, String endTime) { this.office = office;
this.office = office; this.teller = teller;
this.teller = teller; this.staff = staff;
this.staff = staff; this.description = description;
this.description = description; this.startDate = startDate.toDate();
this.startDate = startDate.toDate(); this.endDate = endDate.toDate();
this.endDate = endDate.toDate(); this.isFullDay = isFullDay;
this.isFullDay = isFullDay; this.startTime = startTime;
this.startTime = startTime; this.endTime = endTime;
this.endTime = endTime;
} }
public Map<String, Object> update(final JsonCommand command) { public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<>(7); final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
final String dateFormatAsInput = command.dateFormat(); final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale(); final String localeAsInput = command.locale();
final String descriptionParamName = "description"; final String descriptionParamName = "description";
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName); final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
@@ -136,38 +134,66 @@ public class Cashier extends AbstractPersistable<Long> {
final LocalDate newValue = command.localDateValueOfParameterNamed(endDateParamName); final LocalDate newValue = command.localDateValueOfParameterNamed(endDateParamName);
this.endDate = newValue.toDate(); this.endDate = newValue.toDate();
} }
final Boolean isFullDay = command.booleanObjectValueOfParameterNamed("isFullDay"); final Boolean isFullDay = command.booleanObjectValueOfParameterNamed("isFullDay");
final String isFullDayParamName = "isFullDay"; final String isFullDayParamName = "isFullDay";
if (command.isChangeInBooleanParameterNamed(isFullDayParamName, this.isFullDay)) { if (command.isChangeInBooleanParameterNamed(isFullDayParamName, this.isFullDay)) {
final Boolean newValue = command.booleanObjectValueOfParameterNamed(isFullDayParamName); final Boolean newValue = command.booleanObjectValueOfParameterNamed(isFullDayParamName);
actualChanges.put(isFullDayParamName, newValue); actualChanges.put(isFullDayParamName, newValue);
/*
* this.startTime="00"; this.endTime="00";
*/
this.isFullDay = newValue; this.isFullDay = newValue;
} }
final String startTimeParamName = "startTime"; if (!isFullDay) {
if (command.isChangeInStringParameterNamed(startTimeParamName, this.startTime)) { String newStartHour = "";
final String newValue = command.stringValueOfParameterNamed(startTimeParamName); String newStartMin = "";
actualChanges.put(startTimeParamName, newValue); String newEndHour = "";
this.startTime = newValue; String newEndMin = "";
final String hourStartTimeParamName = "hourStartTime";
final String minStartTimeParamName = "minStartTime";
final String hourEndTimeParamName = "hourEndTime";
final String minEndTimeParamName = "minEndTime";
if (command.isChangeInLongParameterNamed(hourStartTimeParamName, this.getHourFromStartTime())
|| command.isChangeInLongParameterNamed(minStartTimeParamName, this.getMinFromStartTime())) {
newStartHour = command.stringValueOfParameterNamed(hourStartTimeParamName);
if(newEndHour.equalsIgnoreCase("0")){
newEndHour= newEndHour + "0";
}
actualChanges.put(hourStartTimeParamName, newStartHour);
newStartMin = command.stringValueOfParameterNamed(minStartTimeParamName);
if(newStartMin.equalsIgnoreCase("0")){
newStartMin= newStartMin + "0";
}
actualChanges.put(minStartTimeParamName, newStartMin);
this.startTime = newStartHour + ":" + newStartMin;
}
if (command.isChangeInLongParameterNamed(hourEndTimeParamName, this.getHourFromEndTime())
|| command.isChangeInLongParameterNamed(minEndTimeParamName, this.getMinFromEndTime())) {
newEndHour = command.stringValueOfParameterNamed(hourEndTimeParamName);
if(newEndHour.equalsIgnoreCase("0")){
newEndHour= newEndHour + "0";
}
actualChanges.put(hourEndTimeParamName, newEndHour);
newEndMin = command.stringValueOfParameterNamed(minEndTimeParamName);
if(newEndMin.equalsIgnoreCase("0")){
newEndMin= newEndMin + "0";
}
actualChanges.put(minEndTimeParamName, newEndMin);
this.endTime = newEndHour + ":" + newEndMin;
}
} }
final String endTimeParamName = "endTime";
if (command.isChangeInStringParameterNamed(endTimeParamName, this.endTime)) {
final String newValue = command.stringValueOfParameterNamed(endTimeParamName);
actualChanges.put(endTimeParamName, newValue);
this.endTime = newValue;
}
return actualChanges; return actualChanges;
} }
/** /**
* Returns the office of this cashier. * Returns the office of this cashier.
* *
* @return the office of this cashier * @return the office of this cashier
* @see org.mifosplatform.organisation.office.domain.Office * @see org.mifosplatform.organisation.office.domain.Office
*/ */
@@ -175,10 +201,47 @@ public class Cashier extends AbstractPersistable<Long> {
return office; return office;
} }
public Long getHourFromStartTime() {
if (this.startTime != null && !this.startTime.equalsIgnoreCase("")) {
String[] extractHourFromStartTime = this.startTime.split(":");
Long hour = Long.parseLong(extractHourFromStartTime[1]);
return hour;
}
return null;
}
public Long getMinFromStartTime() {
if (this.startTime != null && !this.startTime.equalsIgnoreCase("")) {
String[] extractMinFromStartTime = this.startTime.split(":");
Long min = Long.parseLong(extractMinFromStartTime[1]);
return min;
}
return null;
}
public Long getHourFromEndTime() {
if (this.endTime != null && !this.endTime.equalsIgnoreCase("")) {
String[] extractHourFromEndTime = this.endTime.split(":");
Long hour = Long.parseLong(extractHourFromEndTime[0]);
return hour;
}
return null;
}
public Long getMinFromEndTime() {
if (this.endTime != null && !this.endTime.equalsIgnoreCase("")) {
String[] extractMinFromEndTime = this.endTime.split(":");
Long min = Long.parseLong(extractMinFromEndTime[1]);
return min;
}
return null;
}
/** /**
* Sets the office of this cashier. * Sets the office of this cashier.
* *
* @param office the office of this cashier * @param office
* the office of this cashier
* @see org.mifosplatform.organisation.office.domain.Office * @see org.mifosplatform.organisation.office.domain.Office
*/ */
public void setOffice(Office office) { public void setOffice(Office office) {
@@ -187,7 +250,7 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Returns the staff of this cashier. * Returns the staff of this cashier.
* *
* @return the staff of this cashier * @return the staff of this cashier
* @see org.mifosplatform.organisation.staff.domain.Staff * @see org.mifosplatform.organisation.staff.domain.Staff
*/ */
@@ -197,8 +260,9 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the staff of this cashier. * Sets the staff of this cashier.
* *
* @param staff the staff of this cashier * @param staff
* the staff of this cashier
* @see org.mifosplatform.organisation.staff.domain.Staff * @see org.mifosplatform.organisation.staff.domain.Staff
*/ */
public void setStaff(Staff staff) { public void setStaff(Staff staff) {
@@ -207,7 +271,7 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Returns the teller of this cashier. * Returns the teller of this cashier.
* *
* @return the teller of this cashier * @return the teller of this cashier
* @see org.mifosplatform.organisation.teller.domain.Teller * @see org.mifosplatform.organisation.teller.domain.Teller
*/ */
@@ -217,8 +281,9 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the teller of this cashier. * Sets the teller of this cashier.
* *
* @param teller the teller of this cashier * @param teller
* the teller of this cashier
* @see org.mifosplatform.organisation.teller.domain.Teller * @see org.mifosplatform.organisation.teller.domain.Teller
*/ */
public void setTeller(Teller teller) { public void setTeller(Teller teller) {
@@ -226,9 +291,8 @@ public class Cashier extends AbstractPersistable<Long> {
} }
/** /**
* Returns the description of this cashier. * Returns the description of this cashier. .
* . *
*
* @return the description of this cashier or {@code null} if not present. * @return the description of this cashier or {@code null} if not present.
*/ */
public String getDescription() { public String getDescription() {
@@ -237,8 +301,9 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the description of this cashier. * Sets the description of this cashier.
* *
* @param description the description of this cashier * @param description
* the description of this cashier
*/ */
public void setDescription(String description) { public void setDescription(String description) {
this.description = description; this.description = description;
@@ -247,15 +312,17 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Returns the valid from date of this cashier. * Returns the valid from date of this cashier.
* <p/> * <p/>
* <p>The valid from/to dates may be used to define a time period in which * <p>
* the cashier is assignable to a teller.</p> * The valid from/to dates may be used to define a time period in which the
* * cashier is assignable to a teller.
* </p>
*
* @return the valid from date of this cashier * @return the valid from date of this cashier
*/ */
public Date getStartDate() { public Date getStartDate() {
return startDate; return startDate;
} }
public LocalDate getStartLocalDate() { public LocalDate getStartLocalDate() {
LocalDate startLocalDate = null; LocalDate startLocalDate = null;
if (this.startDate != null) { if (this.startDate != null) {
@@ -267,10 +334,13 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the valid from date of this cashier. * Sets the valid from date of this cashier.
* <p/> * <p/>
* <p>The valid from/to dates may be used to define a time period in which * <p>
* the cashier is assignable to a teller.</p> * The valid from/to dates may be used to define a time period in which the
* * cashier is assignable to a teller.
* @param validFrom the valid from date of this cashier * </p>
*
* @param validFrom
* the valid from date of this cashier
*/ */
public void setStartDate(Date startDate) { public void setStartDate(Date startDate) {
this.startDate = startDate; this.startDate = startDate;
@@ -279,15 +349,17 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Returns the valid to date of this cashier. * Returns the valid to date of this cashier.
* <p/> * <p/>
* <p>The valid from/to dates may be used to define a time period in which * <p>
* the cashier is assignable to a teller.</p> * The valid from/to dates may be used to define a time period in which the
* * cashier is assignable to a teller.
* </p>
*
* @return the valid to date of this cashier * @return the valid to date of this cashier
*/ */
public Date getEndDate() { public Date getEndDate() {
return endDate; return endDate;
} }
public LocalDate getEndLocalDate() { public LocalDate getEndLocalDate() {
LocalDate endLocalDate = null; LocalDate endLocalDate = null;
if (this.endDate != null) { if (this.endDate != null) {
@@ -299,10 +371,13 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the valid to date of this cashier. * Sets the valid to date of this cashier.
* <p/> * <p/>
* <p>The valid from/to dates may be used to define a time period in which * <p>
* the cashier is assignable to a teller.</p> * The valid from/to dates may be used to define a time period in which the
* * cashier is assignable to a teller.
* @param validTo the valid to date of this cashier * </p>
*
* @param validTo
* the valid to date of this cashier
*/ */
public void setEndDate(Date endDate) { public void setEndDate(Date endDate) {
this.endDate = endDate; this.endDate = endDate;
@@ -310,8 +385,9 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Returns whether this cashier works part time or not. * Returns whether this cashier works part time or not.
* *
* @return {@code true} if this cashier works part time; {@code false} otherwise * @return {@code true} if this cashier works part time; {@code false}
* otherwise
*/ */
public Boolean isFullDay() { public Boolean isFullDay() {
return isFullDay; return isFullDay;
@@ -319,19 +395,22 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the part time flag of this cashier. * Sets the part time flag of this cashier.
* *
* @param partTime the part time flag of this cashier * @param partTime
* the part time flag of this cashier
*/ */
public void setFullDay (Boolean isFullDay) { public void setFullDay(Boolean isFullDay) {
this.isFullDay = isFullDay; this.isFullDay = isFullDay;
} }
/** /**
* Returns the start time of this cashier. * Returns the start time of this cashier.
* <p/> * <p/>
* <p>The start/end times may be used to define a time period in which * <p>
* the cashier works part time.</p> * The start/end times may be used to define a time period in which the
* * cashier works part time.
* </p>
*
* @return the start time of this cashier * @return the start time of this cashier
*/ */
public String getStartTime() { public String getStartTime() {
@@ -341,10 +420,13 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Set the start time of this cashier. * Set the start time of this cashier.
* <p/> * <p/>
* <p>The start/end times may be used to define a time period in which * <p>
* the cashier works part time.</p> * The start/end times may be used to define a time period in which the
* * cashier works part time.
* @param startTime the start time of this cashier * </p>
*
* @param startTime
* the start time of this cashier
*/ */
public void setStartTime(String startTime) { public void setStartTime(String startTime) {
this.startTime = startTime; this.startTime = startTime;
@@ -353,9 +435,11 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Returns the end time of this cashier. * Returns the end time of this cashier.
* <p/> * <p/>
* <p>The start/end times may be used to define a time period in which * <p>
* the cashier works part time.</p> * The start/end times may be used to define a time period in which the
* * cashier works part time.
* </p>
*
* @return the end time of this cashier * @return the end time of this cashier
*/ */
public String getEndTime() { public String getEndTime() {
@@ -365,10 +449,13 @@ public class Cashier extends AbstractPersistable<Long> {
/** /**
* Sets the end time of this cashier. * Sets the end time of this cashier.
* <p/> * <p/>
* <p>The start/end times may be used to define a time period in which * <p>
* the cashier works part time.</p> * The start/end times may be used to define a time period in which the
* * cashier works part time.
* @param endTime the end time of this cashier * </p>
*
* @param endTime
* the end time of this cashier
*/ */
public void setEndTime(String endTime) { public void setEndTime(String endTime) {
this.endTime = endTime; this.endTime = endTime;
@@ -0,0 +1,26 @@
/**
* 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.teller.domain;
import org.mifosplatform.organisation.teller.exception.TellerNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CashierRepositoryWrapper {
private final CashierRepository repository;
@Autowired
public CashierRepositoryWrapper(final CashierRepository repository) {
this.repository = repository;
}
public Cashier findOneWithNotFoundDetection(final Long id) {
final Cashier cashier = this.repository.findOne(id);
if (cashier == null) { throw new TellerNotFoundException(id); }
return cashier;
}
}
@@ -5,21 +5,29 @@
*/ */
package org.mifosplatform.organisation.teller.domain; package org.mifosplatform.organisation.teller.domain;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.accounting.glaccount.domain.GLAccount; import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.exception.RootOfficeParentCannotBeUpdated;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
import javax.persistence.*;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
@Entity @Entity
@Table(name = "m_tellers", uniqueConstraints = { @Table(name = "m_tellers", uniqueConstraints = {
@UniqueConstraint(name = "ux_tellers_name", columnNames = {"name"}) @UniqueConstraint(name = "ux_tellers_name", columnNames = {"name"})
@@ -0,0 +1,27 @@
/**
* 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.teller.domain;
import org.mifosplatform.organisation.teller.exception.TellerNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TellerRepositoryWrapper {
private final TellerRepository repository;
@Autowired
public TellerRepositoryWrapper(final TellerRepository repository) {
this.repository = repository;
}
public Teller findOneWithNotFoundDetection(final Long id) {
final Teller teller = this.repository.findOne(id);
if (teller == null) { throw new TellerNotFoundException(id); }
return teller;
}
}
@@ -0,0 +1,20 @@
/**
* 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.teller.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class CashierExistForTellerException extends AbstractPlatformDomainRuleException{
private static final String ERROR_MESSAGE_CODE = "error.msg.cashier.is.associated.with.this.teller";
private static final String DEFAULT_ERROR_MESSAGE = "Cannot delete teller, Cashier is associated for this teller ";
public CashierExistForTellerException(Long tellerId) {
super(ERROR_MESSAGE_CODE, DEFAULT_ERROR_MESSAGE, tellerId);
}
}
@@ -0,0 +1,16 @@
/**
* 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.teller.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class InvalidDateInputException extends AbstractPlatformResourceNotFoundException {
public InvalidDateInputException(final String startDate,final String endDate) {
super("error.msg.invalid.endDate", "EndDate " + endDate + " cannot be before StartDate "+startDate);
}
}
@@ -10,6 +10,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.organisation.teller.service.TellerWritePlatformService; import org.mifosplatform.organisation.teller.service.TellerWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/** /**
* Handles a delete teller command. * Handles a delete teller command.
@@ -18,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
* @see org.mifosplatform.organisation.teller.service.TellerWritePlatformService * @see org.mifosplatform.organisation.teller.service.TellerWritePlatformService
* @since 2.0.0 * @since 2.0.0
*/ */
@Service
public class DeleteTellerCommandHandler implements NewCommandSourceHandler { public class DeleteTellerCommandHandler implements NewCommandSourceHandler {
private final TellerWritePlatformService writePlatformService; private final TellerWritePlatformService writePlatformService;
@@ -22,6 +22,7 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.teller.exception.InvalidDateInputException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -38,11 +39,9 @@ public final class TellerCommandFromApiJsonDeserializer {
/** /**
* The parameters supported for this command. * The parameters supported for this command.
*/ */
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList( private final Set<String> supportedParameters = new HashSet<>(Arrays.asList("officeId", "name", "description", "startDate", "endDate",
"officeId", "name", "description", "startDate", "status", "dateFormat", "locale", "isFullDay", "staffId", "hourStartTime", "minStartTime", "hourEndTime", "minEndTime",
"endDate", "status", "dateFormat", "locale", "txnAmount", "txnDate", "txnNote", "entityType", "entityId", "currencyCode"));
"isFullDay", "staffId", "startTime", "endTime",
"txnAmount","txnDate", "txnNote", "entityType", "entityId", "currencyCode"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@@ -64,7 +63,7 @@ public final class TellerCommandFromApiJsonDeserializer {
final Long officeId = this.fromApiJsonHelper.extractLongNamed("officeId", element); final Long officeId = this.fromApiJsonHelper.extractLongNamed("officeId", element);
baseDataValidator.reset().parameter("officeId").value(officeId).notNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("officeId").value(officeId).notNull().integerGreaterThanZero();
final String name = this.fromApiJsonHelper.extractStringNamed("name", element); final String name = this.fromApiJsonHelper.extractStringNamed("name", element);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(50); baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(50);
@@ -75,10 +74,14 @@ public final class TellerCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("startDate").value(startDate).notNull(); baseDataValidator.reset().parameter("startDate").value(startDate).notNull();
final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed("endDate", element); final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed("endDate", element);
baseDataValidator.reset().parameter("startDate").value(endDate).ignoreIfNull();
final String status = this.fromApiJsonHelper.extractStringNamed("status", element); final String status = this.fromApiJsonHelper.extractStringNamed("status", element);
baseDataValidator.reset().parameter("status").value(status).notBlank().notExceedingLengthOf(50); baseDataValidator.reset().parameter("status").value(status).notBlank().notExceedingLengthOf(50);
if (endDate != null) {
if (endDate.isAfter(startDate)) { throw new InvalidDateInputException(startDate.toString(), endDate.toString()); }
}
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
@@ -106,14 +109,14 @@ public final class TellerCommandFromApiJsonDeserializer {
final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed("startDate", element); final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed("startDate", element);
baseDataValidator.reset().parameter("startDate").value(startDate).notNull(); baseDataValidator.reset().parameter("startDate").value(startDate).notNull();
final String status = this.fromApiJsonHelper.extractStringNamed("status", element); final String status = this.fromApiJsonHelper.extractStringNamed("status", element);
baseDataValidator.reset().parameter("status").value(status).notBlank().notExceedingLengthOf(50); baseDataValidator.reset().parameter("status").value(status).notBlank().notExceedingLengthOf(50);
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
public void validateForAllocateCashier (final String json) { public void validateForAllocateCashier(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
@@ -126,7 +129,7 @@ public final class TellerCommandFromApiJsonDeserializer {
final Long staffId = this.fromApiJsonHelper.extractLongNamed("staffId", element); final Long staffId = this.fromApiJsonHelper.extractLongNamed("staffId", element);
baseDataValidator.reset().parameter("staffId").value(staffId).notNull().integerGreaterThanZero(); baseDataValidator.reset().parameter("staffId").value(staffId).notNull().integerGreaterThanZero();
final String description = this.fromApiJsonHelper.extractStringNamed("description", element); final String description = this.fromApiJsonHelper.extractStringNamed("description", element);
baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(100); baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(100);
@@ -135,17 +138,26 @@ public final class TellerCommandFromApiJsonDeserializer {
final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed("endDate", element); final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed("endDate", element);
baseDataValidator.reset().parameter("endDate").value(endDate).notNull(); baseDataValidator.reset().parameter("endDate").value(endDate).notNull();
final Boolean isFullDay = this.fromApiJsonHelper.extractBooleanNamed("isFullDay", element); final Boolean isFullDay = this.fromApiJsonHelper.extractBooleanNamed("isFullDay", element);
baseDataValidator.reset().parameter("isFullDay").value(isFullDay).notNull(); baseDataValidator.reset().parameter("isFullDay").value(isFullDay).notNull();
final String startTime = this.fromApiJsonHelper.extractStringNamed("startTime", element); if (!isFullDay) {
final String endTime = this.fromApiJsonHelper.extractStringNamed("endTime", element); final String hourStartTime = this.fromApiJsonHelper.extractStringNamed("hourStartTime", element);
baseDataValidator.reset().parameter("startTime").value(hourStartTime).notBlank();
final String minStartTime = this.fromApiJsonHelper.extractStringNamed("minStartTime", element);
baseDataValidator.reset().parameter("startTime").value(minStartTime).notBlank();
final String hourEndTime = this.fromApiJsonHelper.extractStringNamed("hourEndTime", element);
baseDataValidator.reset().parameter("hourEndTime").value(hourEndTime).notBlank();
final String minEndTime = this.fromApiJsonHelper.extractStringNamed("minEndTime", element);
baseDataValidator.reset().parameter("minEndTime").value(minEndTime).notBlank();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
public void validateForCashTxnForCashier (final String json) { public void validateForCashTxnForCashier(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
@@ -156,15 +168,15 @@ public final class TellerCommandFromApiJsonDeserializer {
final JsonElement element = this.fromApiJsonHelper.parse(json); final JsonElement element = this.fromApiJsonHelper.parse(json);
final BigDecimal txnAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("txnAmount", element); final BigDecimal txnAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("txnAmount", element);
baseDataValidator.reset().parameter("txnAmount").value(txnAmount).notNull(); baseDataValidator.reset().parameter("txnAmount").value(txnAmount).notNull();
final LocalDate txnDate = this.fromApiJsonHelper.extractLocalDateNamed("txnDate", element); final LocalDate txnDate = this.fromApiJsonHelper.extractLocalDateNamed("txnDate", element);
baseDataValidator.reset().parameter("txnDate").value(txnDate).notNull(); baseDataValidator.reset().parameter("txnDate").value(txnDate).notNull();
final String txnNote = this.fromApiJsonHelper.extractStringNamed("txnNote", element); final String txnNote = this.fromApiJsonHelper.extractStringNamed("txnNote", element);
baseDataValidator.reset().parameter("txnNote").value(txnNote).notExceedingLengthOf(200); baseDataValidator.reset().parameter("txnNote").value(txnNote).notExceedingLengthOf(200);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed("currencyCode", element); final String currencyCode = this.fromApiJsonHelper.extractStringNamed("currencyCode", element);
baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notExceedingLengthOf(3); baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notExceedingLengthOf(3);
} }
@@ -6,14 +6,15 @@
package org.mifosplatform.organisation.teller.service; package org.mifosplatform.organisation.teller.service;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY; import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY;
import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccount; import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccount;
import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper; import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
import org.mifosplatform.accounting.glaccount.domain.GLAccount; import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.accounting.journalentry.domain.JournalEntry; import org.mifosplatform.accounting.journalentry.domain.JournalEntry;
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository; import org.mifosplatform.accounting.journalentry.domain.JournalEntryRepository;
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -33,6 +34,8 @@ import org.mifosplatform.organisation.teller.domain.CashierTransactionRepository
import org.mifosplatform.organisation.teller.domain.CashierTxnType; import org.mifosplatform.organisation.teller.domain.CashierTxnType;
import org.mifosplatform.organisation.teller.domain.Teller; import org.mifosplatform.organisation.teller.domain.Teller;
import org.mifosplatform.organisation.teller.domain.TellerRepository; import org.mifosplatform.organisation.teller.domain.TellerRepository;
import org.mifosplatform.organisation.teller.domain.TellerRepositoryWrapper;
import org.mifosplatform.organisation.teller.exception.CashierExistForTellerException;
import org.mifosplatform.organisation.teller.exception.CashierNotFoundException; import org.mifosplatform.organisation.teller.exception.CashierNotFoundException;
import org.mifosplatform.organisation.teller.exception.TellerNotFoundException; import org.mifosplatform.organisation.teller.exception.TellerNotFoundException;
import org.mifosplatform.organisation.teller.serialization.TellerCommandFromApiJsonDeserializer; import org.mifosplatform.organisation.teller.serialization.TellerCommandFromApiJsonDeserializer;
@@ -47,51 +50,50 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformService { public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(TellerWritePlatformServiceJpaImpl.class); private final static Logger logger = LoggerFactory.getLogger(TellerWritePlatformServiceJpaImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final TellerRepository tellerRepository; private final TellerRepository tellerRepository;
private final TellerRepositoryWrapper tellerRepositoryWrapper;
private final OfficeRepository officeRepository; private final OfficeRepository officeRepository;
private final StaffRepository staffRepository; private final StaffRepository staffRepository;
private final CashierRepository cashierRepository; private final CashierRepository cashierRepository;
private final CashierTransactionRepository cashierTxnRepository; private final CashierTransactionRepository cashierTxnRepository;
private final JournalEntryRepository glJournalEntryRepository; private final JournalEntryRepository glJournalEntryRepository;
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper; private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper;
@Autowired @Autowired
public TellerWritePlatformServiceJpaImpl (final PlatformSecurityContext context, public TellerWritePlatformServiceJpaImpl(final PlatformSecurityContext context,
final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer, final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer, final TellerRepository tellerRepository,
final TellerRepository tellerRepository, final OfficeRepository officeRepository, final TellerRepositoryWrapper tellerRepositoryWrapper, final OfficeRepository officeRepository,
final StaffRepository staffRepository, CashierRepository cashierRepository, final StaffRepository staffRepository, CashierRepository cashierRepository, CashierTransactionRepository cashierTxnRepository,
CashierTransactionRepository cashierTxnRepository,
JournalEntryRepository glJournalEntryRepository, JournalEntryRepository glJournalEntryRepository,
FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper) {
) {
this.context = context; this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.tellerRepository = tellerRepository; this.tellerRepository = tellerRepository;
this.tellerRepositoryWrapper = tellerRepositoryWrapper;
this.officeRepository = officeRepository; this.officeRepository = officeRepository;
this.staffRepository = staffRepository; this.staffRepository = staffRepository;
this.cashierRepository = cashierRepository; this.cashierRepository = cashierRepository;
this.cashierTxnRepository = cashierTxnRepository; this.cashierTxnRepository = cashierTxnRepository;
this.glJournalEntryRepository = glJournalEntryRepository; this.glJournalEntryRepository = glJournalEntryRepository;
this.financialActivityAccountRepositoryWrapper = financialActivityAccountRepositoryWrapper; this.financialActivityAccountRepositoryWrapper = financialActivityAccountRepositoryWrapper;
} }
@Override
@Override @Transactional
@Transactional public CommandProcessingResult createTeller(JsonCommand command) {
public CommandProcessingResult createTeller(JsonCommand command) { try {
try {
this.context.authenticatedUser(); this.context.authenticatedUser();
final Long officeId = command.longValueOfParameterNamed("officeId"); final Long officeId = command.longValueOfParameterNamed("officeId");
this.fromApiJsonDeserializer.validateForCreate(command.json()); this.fromApiJsonDeserializer.validateForCreate(command.json());
// final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId); // final Office parent =
// validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);
final Office tellerOffice = this.officeRepository.findOne(officeId); final Office tellerOffice = this.officeRepository.findOne(officeId);
if (tellerOffice == null) { throw new OfficeNotFoundException(officeId); } if (tellerOffice == null) { throw new OfficeNotFoundException(officeId); }
@@ -109,15 +111,14 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve); handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
} }
@Override @Override
@Transactional @Transactional
public CommandProcessingResult modifyTeller(Long tellerId, public CommandProcessingResult modifyTeller(Long tellerId, JsonCommand command) {
JsonCommand command) {
try { try {
final Long officeId = command.longValueOfParameterNamed("officeId"); final Long officeId = command.longValueOfParameterNamed("officeId");
final Office tellerOffice = this.officeRepository.findOne(officeId); final Office tellerOffice = this.officeRepository.findOne(officeId);
if (tellerOffice == null) { throw new OfficeNotFoundException(officeId); } if (tellerOffice == null) { throw new OfficeNotFoundException(officeId); }
@@ -143,9 +144,9 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve); handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
} }
/* /*
* used to restrict modifying operations to office that are either the users * used to restrict modifying operations to office that are either the users
* office or lower (child) in the office hierarchy * office or lower (child) in the office hierarchy
*/ */
@@ -166,14 +167,27 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
return tellerToReturn; return tellerToReturn;
} }
@Override @Override
@Transactional @Transactional
public CommandProcessingResult deleteTeller(Long tellerId) { public CommandProcessingResult deleteTeller(Long tellerId) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null;
} Teller teller = tellerRepositoryWrapper.findOneWithNotFoundDetection(tellerId);
Set<Cashier> isTellerIdPresentInCashier = teller.getCashiers();
for (final Cashier tellerIdInCashier : isTellerIdPresentInCashier) {
if (tellerIdInCashier.getTeller().getId().toString().equalsIgnoreCase(tellerId.toString())) { throw new CashierExistForTellerException(
tellerId); }
}
tellerRepository.delete(teller);
return new CommandProcessingResultBuilder() //
.withEntityId(teller.getId()) //
.build();
}
/* /*
* Guaranteed to throw an exception no matter what the data integrity issue * Guaranteed to throw an exception no matter what the data integrity issue
* is. * is.
@@ -192,27 +206,46 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
"Unknown data integrity issue with resource."); "Unknown data integrity issue with resource.");
} }
@Override
@Override public CommandProcessingResult allocateCashierToTeller(final Long tellerId, JsonCommand command) {
public CommandProcessingResult allocateCashierToTeller(final Long tellerId, JsonCommand command) { try {
try {
this.context.authenticatedUser(); this.context.authenticatedUser();
Long hourStartTime;
// final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId); Long minStartTime;
Long hourEndTime;
Long minEndTime;
String startTime = " ";
String endTime = " ";
final Teller teller = this.tellerRepository.findOne(tellerId); final Teller teller = this.tellerRepository.findOne(tellerId);
if (teller == null) { throw new TellerNotFoundException(tellerId); } if (teller == null) { throw new TellerNotFoundException(tellerId); }
final Office tellerOffice = teller.getOffice(); final Office tellerOffice = teller.getOffice();
final Long staffId = command.longValueOfParameterNamed("staffId"); final Long staffId = command.longValueOfParameterNamed("staffId");
this.fromApiJsonDeserializer.validateForAllocateCashier(command.json()); this.fromApiJsonDeserializer.validateForAllocateCashier(command.json());
final Staff staff = this.staffRepository.findOne(staffId); final Staff staff = this.staffRepository.findOne(staffId);
if (staff == null) { throw new StaffNotFoundException(staffId); } if (staff == null) { throw new StaffNotFoundException(staffId); }
final Boolean isFullDay = command.booleanObjectValueOfParameterNamed("isFullDay");
if (!isFullDay) {
hourStartTime = command.longValueOfParameterNamed("hourStartTime");
minStartTime = command.longValueOfParameterNamed("minStartTime");
final Cashier cashier = Cashier.fromJson(tellerOffice, teller, staff, if (minStartTime == 0)
command); startTime = hourStartTime.toString() + ":" + minStartTime.toString() + "0";
else
startTime = hourStartTime.toString() + ":" + minStartTime.toString();
hourEndTime = command.longValueOfParameterNamed("hourEndTime");
minEndTime = command.longValueOfParameterNamed("minEndTime");
if (minEndTime == 0)
endTime = hourEndTime.toString() + ":" + minEndTime.toString() + "0";
else
endTime = hourEndTime.toString() + ":" + minEndTime.toString();
}
final Cashier cashier = Cashier.fromJson(tellerOffice, teller, staff, startTime, endTime, command);
this.cashierRepository.save(cashier); this.cashierRepository.save(cashier);
@@ -225,26 +258,25 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve); handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
} }
@Override @Override
@Transactional @Transactional
public CommandProcessingResult updateCashierAllocation (Long tellerId, Long cashierId, public CommandProcessingResult updateCashierAllocation(Long tellerId, Long cashierId, JsonCommand command) {
JsonCommand command) {
try { try {
final AppUser currentUser = this.context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForAllocateCashier(command.json()); this.fromApiJsonDeserializer.validateForAllocateCashier(command.json());
final Long staffId = command.longValueOfParameterNamed("staffId"); final Long staffId = command.longValueOfParameterNamed("staffId");
final Staff staff = this.staffRepository.findOne(staffId); final Staff staff = this.staffRepository.findOne(staffId);
if (staff == null) { throw new StaffNotFoundException(staffId); } if (staff == null) { throw new StaffNotFoundException(staffId); }
final Cashier cashier = validateUserPriviledgeOnCashierAndRetrieve(currentUser, tellerId, cashierId); final Cashier cashier = validateUserPriviledgeOnCashierAndRetrieve(currentUser, tellerId, cashierId);
cashier.setStaff(staff); cashier.setStaff(staff);
//TODO - check if staff office and teller office match // TODO - check if staff office and teller office match
final Map<String, Object> changes = cashier.update(command); final Map<String, Object> changes = cashier.update(command);
@@ -262,22 +294,20 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve); handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
} }
private Cashier validateUserPriviledgeOnCashierAndRetrieve(final AppUser currentUser, final Long tellerId, final Long cashierId) {
validateUserPriviledgeOnTellerAndRetrieve(currentUser, tellerId);
private Cashier validateUserPriviledgeOnCashierAndRetrieve(final AppUser currentUser,
final Long tellerId, final Long cashierId) {
validateUserPriviledgeOnTellerAndRetrieve(currentUser, tellerId);
final Cashier cashierToReturn = this.cashierRepository.findOne(cashierId); final Cashier cashierToReturn = this.cashierRepository.findOne(cashierId);
return cashierToReturn; return cashierToReturn;
} }
@Override @Override
@Transactional @Transactional
public CommandProcessingResult deleteCashierAllocation (Long tellerId, Long cashierId, public CommandProcessingResult deleteCashierAllocation(Long tellerId, Long cashierId, JsonCommand command) {
JsonCommand command) {
try { try {
final AppUser currentUser = this.context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
final Cashier cashier = validateUserPriviledgeOnCashierAndRetrieve(currentUser, tellerId, cashierId); final Cashier cashier = validateUserPriviledgeOnCashierAndRetrieve(currentUser, tellerId, cashierId);
@@ -288,108 +318,115 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(cashierId) // .withEntityId(cashierId) //
.build(); .build();
}
/*
@Override
public CommandProcessingResult inwardCashToCashier (final Long cashierId,
final CashierTransaction cashierTxn) {
CashierTxnType txnType = CashierTxnType.INWARD_CASH_TXN;
// pre save to generate id for use in office hierarchy
this.cashierTxnRepository.save(cashierTxn);
} */
@Override
public CommandProcessingResult allocateCashToCashier(final Long cashierId, JsonCommand command) {
return doTransactionForCashier(cashierId, CashierTxnType.ALLOCATE, command); // For fund allocation to cashier
}
@Override
public CommandProcessingResult settleCashFromCashier(final Long cashierId, JsonCommand command) {
return doTransactionForCashier(cashierId, CashierTxnType.SETTLE, command); // For fund settlement from cashier
} }
private CommandProcessingResult doTransactionForCashier(final Long cashierId, /*
final CashierTxnType txnType, JsonCommand command) { * @Override public CommandProcessingResult inwardCashToCashier (final Long
try { * cashierId, final CashierTransaction cashierTxn) { CashierTxnType txnType
* = CashierTxnType.INWARD_CASH_TXN; // pre save to generate id for use in
* office hierarchy this.cashierTxnRepository.save(cashierTxn); }
*/
@Override
public CommandProcessingResult allocateCashToCashier(final Long cashierId, JsonCommand command) {
return doTransactionForCashier(cashierId, CashierTxnType.ALLOCATE, command); // For
// fund
// allocation
// to
// cashier
}
@Override
public CommandProcessingResult settleCashFromCashier(final Long cashierId, JsonCommand command) {
return doTransactionForCashier(cashierId, CashierTxnType.SETTLE, command); // For
// fund
// settlement
// from
// cashier
}
private CommandProcessingResult doTransactionForCashier(final Long cashierId, final CashierTxnType txnType, JsonCommand command) {
try {
final AppUser currentUser = this.context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
final Cashier cashier = this.cashierRepository.findOne(cashierId); final Cashier cashier = this.cashierRepository.findOne(cashierId);
if (cashier == null) { throw new CashierNotFoundException(cashierId); } if (cashier == null) { throw new CashierNotFoundException(cashierId); }
this.fromApiJsonDeserializer.validateForCashTxnForCashier(command.json()); this.fromApiJsonDeserializer.validateForCashTxnForCashier(command.json());
final String entityType = command.stringValueOfParameterNamed("entityType"); final String entityType = command.stringValueOfParameterNamed("entityType");
final Long entityId = command.longValueOfParameterNamed("entityId"); final Long entityId = command.longValueOfParameterNamed("entityId");
if (entityType != null) { if (entityType != null) {
if (entityType.equals("loan account")) { if (entityType.equals("loan account")) {
// TODO : Check if loan account exists // TODO : Check if loan account exists
// LoanAccount loan = null; // LoanAccount loan = null;
// if (loan == null) { throw new LoanAccountFoundException(entityId); } // if (loan == null) { throw new
} else if (entityType.equals("savings account")) { // LoanAccountFoundException(entityId); }
// TODO : Check if loan account exists } else if (entityType.equals("savings account")) {
// SavingsAccount savingsaccount = null; // TODO : Check if loan account exists
// if (savingsaccount == null) { throw new SavingsAccountNotFoundException(entityId); } // SavingsAccount savingsaccount = null;
// if (savingsaccount == null) { throw new
} if (entityType.equals("client")) { // SavingsAccountNotFoundException(entityId); }
// TODO: Check if client exists
// Client client = null; }
// if (client == null) { throw new ClientNotFoundException(entityId); } if (entityType.equals("client")) {
} else { // TODO: Check if client exists
// TODO : Invalid type handling // Client client = null;
} // if (client == null) { throw new
// ClientNotFoundException(entityId); }
} else {
// TODO : Invalid type handling
}
} }
final CashierTransaction cashierTxn = CashierTransaction.fromJson(cashier, command); final CashierTransaction cashierTxn = CashierTransaction.fromJson(cashier, command);
cashierTxn.setTxnType(txnType.getId()); cashierTxn.setTxnType(txnType.getId());
this.cashierTxnRepository.save(cashierTxn); this.cashierTxnRepository.save(cashierTxn);
// Pass the journal entries // Pass the journal entries
FinancialActivityAccount mainVaultFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper. FinancialActivityAccount mainVaultFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper
findByFinancialActivityTypeWithNotFoundDetection( .findByFinancialActivityTypeWithNotFoundDetection(FINANCIAL_ACTIVITY.CASH_AT_MAINVAULT.getValue());
FINANCIAL_ACTIVITY.CASH_AT_MAINVAULT.getValue()); FinancialActivityAccount tellerCashFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper
FinancialActivityAccount tellerCashFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper. .findByFinancialActivityTypeWithNotFoundDetection(FINANCIAL_ACTIVITY.CASH_AT_TELLER.getValue());
findByFinancialActivityTypeWithNotFoundDetection(
FINANCIAL_ACTIVITY.CASH_AT_TELLER.getValue());
GLAccount creditAccount = null; GLAccount creditAccount = null;
GLAccount debitAccount = null; GLAccount debitAccount = null;
if (txnType.equals(CashierTxnType.ALLOCATE) ) { if (txnType.equals(CashierTxnType.ALLOCATE)) {
debitAccount = tellerCashFinancialActivityAccount.getGlAccount(); debitAccount = tellerCashFinancialActivityAccount.getGlAccount();
creditAccount = mainVaultFinancialActivityAccount.getGlAccount(); creditAccount = mainVaultFinancialActivityAccount.getGlAccount();
} else if (txnType.equals(CashierTxnType.SETTLE) ) { } else if (txnType.equals(CashierTxnType.SETTLE)) {
debitAccount = mainVaultFinancialActivityAccount.getGlAccount(); debitAccount = mainVaultFinancialActivityAccount.getGlAccount();
creditAccount = tellerCashFinancialActivityAccount.getGlAccount(); creditAccount = tellerCashFinancialActivityAccount.getGlAccount();
} }
final Office cashierOffice = cashier.getTeller().getOffice(); final Office cashierOffice = cashier.getTeller().getOffice();
final Long time = System.currentTimeMillis(); final Long time = System.currentTimeMillis();
final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId(); final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId();
final String transactionId = Long.toHexString(Long.parseLong(uniqueVal)); final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
final JournalEntry debitJournalEntry = JournalEntry.createNew( final JournalEntry debitJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
cashierOffice, null, // payment detail // detail
debitAccount, "USD", // FIXME: Take currency code from the transaction debitAccount, "USD", // FIXME: Take currency code from the
transactionId, false, // manual entry // transaction
cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(), transactionId, false, // manual entry
cashierTxn.getTxnNote(), // Description cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number null, null, null, // entity Type, entityId, reference number
null, null); // Loan and Savings Txn null, null); // Loan and Savings Txn
final JournalEntry creditJournalEntry = JournalEntry.createNew( final JournalEntry creditJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
cashierOffice, null, // payment detail // detail
creditAccount, "USD", // FIXME: Take currency code from the transaction creditAccount, "USD", // FIXME: Take currency code from the
transactionId, false, // manual entry // transaction
cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(), transactionId, false, // manual entry
cashierTxn.getTxnNote(), // Description cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number null, null, null, // entity Type, entityId, reference number
null, null); // Loan and Savings Txn null, null); // Loan and Savings Txn
this.glJournalEntryRepository.saveAndFlush(debitJournalEntry); this.glJournalEntryRepository.saveAndFlush(debitJournalEntry);
this.glJournalEntryRepository.saveAndFlush(creditJournalEntry); this.glJournalEntryRepository.saveAndFlush(creditJournalEntry);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -400,7 +437,6 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve); handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
} }
} }
} }
@@ -0,0 +1,13 @@
UPDATE m_permission SET
action_name="UPDATE"
WHERE
code = "UPDATE_TELLER";
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`) VALUES ('cash_mgmt', 'DELETE_TELLER', 'TELLER', 'DELETE');
ALTER TABLE `m_cashier_transactions`
DROP FOREIGN KEY `FK_m_teller_transactions_m_cashiers`;
ALTER TABLE `m_cashier_transactions`
ADD CONSTRAINT `FK_m_teller_transactions_m_cashiers` FOREIGN KEY (`cashier_id`) REFERENCES `m_cashiers` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;