Merge branch 'MIFOSX-1892' of git://github.com/MithunKashyap/mifosx into MithunKashyap-MIFOSX-1892

This commit is contained in:
Vishwas Babu A J
2015-03-28 11:25:26 +05:30
10 changed files with 529 additions and 282 deletions
@@ -5,7 +5,6 @@
*/
package org.mifosplatform.organisation.teller.domain;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.organisation.office.domain.Office;
@@ -18,21 +17,21 @@ import java.util.LinkedHashMap;
import java.util.Map;
/**
* Provides the base model for a cashier. Represents a row in the "m_cashiers" database table, with
* each column mapped to a property of this class.
*
* Provides the base model for a cashier. Represents a row in the
* "m_cashiers" database table, with each column mapped to a property
* of this class.
*
* @author Markus Geiss
* @since 2.0.0
*/
@Entity
@Table(name = "m_cashiers", uniqueConstraints = {
@UniqueConstraint(name = "ux_cashiers_staff_teller", columnNames = {"staff_id", "teller_id"})
})
@Table(name = "m_cashiers", uniqueConstraints = { @UniqueConstraint(name = "ux_cashiers_staff_teller", columnNames = { "staff_id",
"teller_id" }) })
public class Cashier extends AbstractPersistable<Long> {
// ManyToOne(fetch = FetchType.LAZY)
// JoinColumn(name = "office_id", nullable = false)
@Transient
@Transient
private Office office;
@ManyToOne(fetch = FetchType.LAZY)
@@ -69,45 +68,44 @@ public class Cashier extends AbstractPersistable<Long> {
public Cashier() {
super();
}
public static Cashier fromJson(final Office cashierOffice,
final Teller teller,
final Staff staff,
final JsonCommand command) {
public static Cashier fromJson(final Office cashierOffice, final Teller teller, final Staff staff, final String startTime,
final String endTime, final JsonCommand command) {
// final Long tellerId = teller.getId();
// final Long staffId = command.longValueOfParameterNamed("staffId");
final String description = command.stringValueOfParameterNamed("description");
final LocalDate startDate = command.localDateValueOfParameterNamed("startDate");
final LocalDate endDate = command.localDateValueOfParameterNamed("endDate");
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,
isFullDay, startTime, endTime);
return new Cashier(cashierOffice, teller, staff, description, startDate, endDate, isFullDay, startTime, endTime);
}
public Cashier (Office office, Teller teller, Staff staff,
String description, LocalDate startDate, LocalDate endDate,
Boolean isFullDay, String startTime, String endTime) {
this.office = office;
this.teller = teller;
this.staff = staff;
this.description = description;
this.startDate = startDate.toDate();
this.endDate = endDate.toDate();
this.isFullDay = isFullDay;
this.startTime = startTime;
this.endTime = endTime;
public Cashier(Office office, Teller teller, Staff staff, String description, LocalDate startDate, LocalDate endDate,
Boolean isFullDay, String startTime, String endTime) {
this.office = office;
this.teller = teller;
this.staff = staff;
this.description = description;
this.startDate = startDate.toDate();
this.endDate = endDate.toDate();
this.isFullDay = isFullDay;
this.startTime = startTime;
this.endTime = endTime;
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale();
final String localeAsInput = command.locale();
final String descriptionParamName = "description";
if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) {
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
@@ -136,38 +134,66 @@ public class Cashier extends AbstractPersistable<Long> {
final LocalDate newValue = command.localDateValueOfParameterNamed(endDateParamName);
this.endDate = newValue.toDate();
}
final Boolean isFullDay = command.booleanObjectValueOfParameterNamed("isFullDay");
final String isFullDayParamName = "isFullDay";
if (command.isChangeInBooleanParameterNamed(isFullDayParamName, this.isFullDay)) {
final Boolean newValue = command.booleanObjectValueOfParameterNamed(isFullDayParamName);
actualChanges.put(isFullDayParamName, newValue);
/*
* this.startTime="00"; this.endTime="00";
*/
this.isFullDay = newValue;
}
final String startTimeParamName = "startTime";
if (command.isChangeInStringParameterNamed(startTimeParamName, this.startTime)) {
final String newValue = command.stringValueOfParameterNamed(startTimeParamName);
actualChanges.put(startTimeParamName, newValue);
this.startTime = newValue;
if (!isFullDay) {
String newStartHour = "";
String newStartMin = "";
String newEndHour = "";
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;
}
/**
* Returns the office of this cashier.
*
*
* @return the office of this cashier
* @see org.mifosplatform.organisation.office.domain.Office
*/
@@ -175,10 +201,47 @@ public class Cashier extends AbstractPersistable<Long> {
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.
*
* @param office the office of this cashier
*
* @param office
* the office of this cashier
* @see org.mifosplatform.organisation.office.domain.Office
*/
public void setOffice(Office office) {
@@ -187,7 +250,7 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Returns the staff of this cashier.
*
*
* @return the staff of this cashier
* @see org.mifosplatform.organisation.staff.domain.Staff
*/
@@ -197,8 +260,9 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* 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
*/
public void setStaff(Staff staff) {
@@ -207,7 +271,7 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Returns the teller of this cashier.
*
*
* @return the teller of this cashier
* @see org.mifosplatform.organisation.teller.domain.Teller
*/
@@ -217,8 +281,9 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* 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
*/
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.
*/
public String getDescription() {
@@ -237,8 +301,9 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* 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) {
this.description = description;
@@ -247,15 +312,17 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Returns the valid from date of this cashier.
* <p/>
* <p>The valid from/to dates may be used to define a time period in which
* the cashier is assignable to a teller.</p>
*
* <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
*/
public Date getStartDate() {
return startDate;
}
public LocalDate getStartLocalDate() {
LocalDate startLocalDate = null;
if (this.startDate != null) {
@@ -267,10 +334,13 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Sets the valid from date of this cashier.
* <p/>
* <p>The valid from/to dates may be used to define a time period in which
* the cashier is assignable to a teller.</p>
*
* @param validFrom the valid from date of this cashier
* <p>
* The valid from/to dates may be used to define a time period in which the
* cashier is assignable to a teller.
* </p>
*
* @param validFrom
* the valid from date of this cashier
*/
public void setStartDate(Date startDate) {
this.startDate = startDate;
@@ -279,15 +349,17 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Returns the valid to date of this cashier.
* <p/>
* <p>The valid from/to dates may be used to define a time period in which
* the cashier is assignable to a teller.</p>
*
* <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
*/
public Date getEndDate() {
return endDate;
}
public LocalDate getEndLocalDate() {
LocalDate endLocalDate = null;
if (this.endDate != null) {
@@ -299,10 +371,13 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Sets the valid to date of this cashier.
* <p/>
* <p>The valid from/to dates may be used to define a time period in which
* the cashier is assignable to a teller.</p>
*
* @param validTo the valid to date of this cashier
* <p>
* The valid from/to dates may be used to define a time period in which the
* cashier is assignable to a teller.
* </p>
*
* @param validTo
* the valid to date of this cashier
*/
public void setEndDate(Date endDate) {
this.endDate = endDate;
@@ -310,8 +385,9 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* 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() {
return isFullDay;
@@ -319,19 +395,22 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* 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;
}
/**
* Returns the start time of this cashier.
* <p/>
* <p>The start/end times may be used to define a time period in which
* the cashier works part time.</p>
*
* <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
*/
public String getStartTime() {
@@ -341,10 +420,13 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Set the start time of this cashier.
* <p/>
* <p>The start/end times may be used to define a time period in which
* the cashier works part time.</p>
*
* @param startTime the start time of this cashier
* <p>
* The start/end times may be used to define a time period in which the
* cashier works part time.
* </p>
*
* @param startTime
* the start time of this cashier
*/
public void setStartTime(String startTime) {
this.startTime = startTime;
@@ -353,9 +435,11 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Returns the end time of this cashier.
* <p/>
* <p>The start/end times may be used to define a time period in which
* the cashier works part time.</p>
*
* <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
*/
public String getEndTime() {
@@ -365,10 +449,13 @@ public class Cashier extends AbstractPersistable<Long> {
/**
* Sets the end time of this cashier.
* <p/>
* <p>The start/end times may be used to define a time period in which
* the cashier works part time.</p>
*
* @param endTime the end time of this cashier
* <p>
* The start/end times may be used to define a time period in which the
* cashier works part time.
* </p>
*
* @param endTime
* the end time of this cashier
*/
public void setEndTime(String 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;
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.joda.time.LocalDate;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.exception.RootOfficeParentCannotBeUpdated;
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
@Table(name = "m_tellers", uniqueConstraints = {
@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.organisation.teller.service.TellerWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Handles a delete teller command.
@@ -18,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
* @see org.mifosplatform.organisation.teller.service.TellerWritePlatformService
* @since 2.0.0
*/
@Service
public class DeleteTellerCommandHandler implements NewCommandSourceHandler {
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.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.teller.exception.InvalidDateInputException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -38,11 +39,9 @@ public final class TellerCommandFromApiJsonDeserializer {
/**
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList(
"officeId", "name", "description", "startDate",
"endDate", "status", "dateFormat", "locale",
"isFullDay", "staffId", "startTime", "endTime",
"txnAmount","txnDate", "txnNote", "entityType", "entityId", "currencyCode"));
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList("officeId", "name", "description", "startDate", "endDate",
"status", "dateFormat", "locale", "isFullDay", "staffId", "hourStartTime", "minStartTime", "hourEndTime", "minEndTime",
"txnAmount", "txnDate", "txnNote", "entityType", "entityId", "currencyCode"));
private final FromJsonHelper fromApiJsonHelper;
@@ -64,7 +63,7 @@ public final class TellerCommandFromApiJsonDeserializer {
final Long officeId = this.fromApiJsonHelper.extractLongNamed("officeId", element);
baseDataValidator.reset().parameter("officeId").value(officeId).notNull().integerGreaterThanZero();
final String name = this.fromApiJsonHelper.extractStringNamed("name", element);
baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(50);
@@ -75,10 +74,14 @@ public final class TellerCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("startDate").value(startDate).notNull();
final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed("endDate", element);
baseDataValidator.reset().parameter("startDate").value(endDate).ignoreIfNull();
final String status = this.fromApiJsonHelper.extractStringNamed("status", element);
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);
}
@@ -106,14 +109,14 @@ public final class TellerCommandFromApiJsonDeserializer {
final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed("startDate", element);
baseDataValidator.reset().parameter("startDate").value(startDate).notNull();
final String status = this.fromApiJsonHelper.extractStringNamed("status", element);
baseDataValidator.reset().parameter("status").value(status).notBlank().notExceedingLengthOf(50);
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
public void validateForAllocateCashier (final String json) {
public void validateForAllocateCashier(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
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);
baseDataValidator.reset().parameter("staffId").value(staffId).notNull().integerGreaterThanZero();
final String description = this.fromApiJsonHelper.extractStringNamed("description", element);
baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(100);
@@ -135,17 +138,26 @@ public final class TellerCommandFromApiJsonDeserializer {
final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed("endDate", element);
baseDataValidator.reset().parameter("endDate").value(endDate).notNull();
final Boolean isFullDay = this.fromApiJsonHelper.extractBooleanNamed("isFullDay", element);
baseDataValidator.reset().parameter("isFullDay").value(isFullDay).notNull();
final String startTime = this.fromApiJsonHelper.extractStringNamed("startTime", element);
final String endTime = this.fromApiJsonHelper.extractStringNamed("endTime", element);
if (!isFullDay) {
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);
}
public void validateForCashTxnForCashier (final String json) {
public void validateForCashTxnForCashier(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
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 BigDecimal txnAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("txnAmount", element);
final BigDecimal txnAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("txnAmount", element);
baseDataValidator.reset().parameter("txnAmount").value(txnAmount).notNull();
final LocalDate txnDate = this.fromApiJsonHelper.extractLocalDateNamed("txnDate", element);
baseDataValidator.reset().parameter("txnDate").value(txnDate).notNull();
final String txnNote = this.fromApiJsonHelper.extractStringNamed("txnNote", element);
baseDataValidator.reset().parameter("txnNote").value(txnNote).notExceedingLengthOf(200);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed("currencyCode", element);
baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notExceedingLengthOf(3);
}
@@ -6,14 +6,15 @@
package org.mifosplatform.organisation.teller.service;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY;
import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccount;
import org.mifosplatform.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
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.JournalEntryType;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
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.Teller;
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.TellerNotFoundException;
import org.mifosplatform.organisation.teller.serialization.TellerCommandFromApiJsonDeserializer;
@@ -47,51 +50,50 @@ import org.springframework.transaction.annotation.Transactional;
@Service
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 TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final TellerRepository tellerRepository;
private final TellerRepositoryWrapper tellerRepositoryWrapper;
private final OfficeRepository officeRepository;
private final StaffRepository staffRepository;
private final CashierRepository cashierRepository;
private final CashierTransactionRepository cashierTxnRepository;
private final JournalEntryRepository glJournalEntryRepository;
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper;
@Autowired
public TellerWritePlatformServiceJpaImpl (final PlatformSecurityContext context,
final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final TellerRepository tellerRepository, final OfficeRepository officeRepository,
final StaffRepository staffRepository, CashierRepository cashierRepository,
CashierTransactionRepository cashierTxnRepository,
public TellerWritePlatformServiceJpaImpl(final PlatformSecurityContext context,
final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer, final TellerRepository tellerRepository,
final TellerRepositoryWrapper tellerRepositoryWrapper, final OfficeRepository officeRepository,
final StaffRepository staffRepository, CashierRepository cashierRepository, CashierTransactionRepository cashierTxnRepository,
JournalEntryRepository glJournalEntryRepository,
FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper
) {
FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.tellerRepository = tellerRepository;
this.tellerRepositoryWrapper = tellerRepositoryWrapper;
this.officeRepository = officeRepository;
this.staffRepository = staffRepository;
this.cashierRepository = cashierRepository;
this.cashierTxnRepository = cashierTxnRepository;
this.glJournalEntryRepository = glJournalEntryRepository;
this.financialActivityAccountRepositoryWrapper = financialActivityAccountRepositoryWrapper;
this.financialActivityAccountRepositoryWrapper = financialActivityAccountRepositoryWrapper;
}
@Override
@Transactional
public CommandProcessingResult createTeller(JsonCommand command) {
try {
@Override
@Transactional
public CommandProcessingResult createTeller(JsonCommand command) {
try {
this.context.authenticatedUser();
final Long officeId = command.longValueOfParameterNamed("officeId");
this.fromApiJsonDeserializer.validateForCreate(command.json());
// final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);
// final Office parent =
// validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);
final Office tellerOffice = this.officeRepository.findOne(officeId);
if (tellerOffice == null) { throw new OfficeNotFoundException(officeId); }
@@ -109,15 +111,14 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
}
@Override
@Transactional
public CommandProcessingResult modifyTeller(Long tellerId,
JsonCommand command) {
@Override
@Transactional
public CommandProcessingResult modifyTeller(Long tellerId, JsonCommand command) {
try {
final Long officeId = command.longValueOfParameterNamed("officeId");
final Long officeId = command.longValueOfParameterNamed("officeId");
final Office tellerOffice = this.officeRepository.findOne(officeId);
if (tellerOffice == null) { throw new OfficeNotFoundException(officeId); }
@@ -143,9 +144,9 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
/*
}
/*
* used to restrict modifying operations to office that are either the users
* office or lower (child) in the office hierarchy
*/
@@ -166,14 +167,27 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
return tellerToReturn;
}
@Override
@Transactional
public CommandProcessingResult deleteTeller(Long tellerId) {
// TODO Auto-generated method stub
return null;
}
@Override
@Transactional
public CommandProcessingResult deleteTeller(Long tellerId) {
// TODO Auto-generated method stub
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
* is.
@@ -192,27 +206,46 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
"Unknown data integrity issue with resource.");
}
@Override
public CommandProcessingResult allocateCashierToTeller(final Long tellerId, JsonCommand command) {
try {
@Override
public CommandProcessingResult allocateCashierToTeller(final Long tellerId, JsonCommand command) {
try {
this.context.authenticatedUser();
// final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);
Long hourStartTime;
Long minStartTime;
Long hourEndTime;
Long minEndTime;
String startTime = " ";
String endTime = " ";
final Teller teller = this.tellerRepository.findOne(tellerId);
if (teller == null) { throw new TellerNotFoundException(tellerId); }
final Office tellerOffice = teller.getOffice();
final Long staffId = command.longValueOfParameterNamed("staffId");
this.fromApiJsonDeserializer.validateForAllocateCashier(command.json());
final Staff staff = this.staffRepository.findOne(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,
command);
if (minStartTime == 0)
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);
@@ -225,26 +258,25 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty();
}
}
}
@Override
@Transactional
public CommandProcessingResult updateCashierAllocation (Long tellerId, Long cashierId,
JsonCommand command) {
@Override
@Transactional
public CommandProcessingResult updateCashierAllocation(Long tellerId, Long cashierId, JsonCommand command) {
try {
final AppUser currentUser = this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForAllocateCashier(command.json());
final Long staffId = command.longValueOfParameterNamed("staffId");
final Staff staff = this.staffRepository.findOne(staffId);
if (staff == null) { throw new StaffNotFoundException(staffId); }
final Cashier cashier = validateUserPriviledgeOnCashierAndRetrieve(currentUser, tellerId, cashierId);
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);
@@ -262,22 +294,20 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve);
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);
return cashierToReturn;
}
@Override
@Transactional
public CommandProcessingResult deleteCashierAllocation (Long tellerId, Long cashierId,
JsonCommand command) {
@Transactional
public CommandProcessingResult deleteCashierAllocation(Long tellerId, Long cashierId, JsonCommand command) {
try {
final AppUser currentUser = this.context.authenticatedUser();
final Cashier cashier = validateUserPriviledgeOnCashierAndRetrieve(currentUser, tellerId, cashierId);
@@ -288,108 +318,115 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
return CommandProcessingResult.empty();
}
return new CommandProcessingResultBuilder() //
.withEntityId(cashierId) //
.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
return new CommandProcessingResultBuilder() //
.withEntityId(cashierId) //
.build();
}
private CommandProcessingResult doTransactionForCashier(final Long cashierId,
final CashierTxnType txnType, JsonCommand command) {
try {
/*
* @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) {
try {
final AppUser currentUser = this.context.authenticatedUser();
final Cashier cashier = this.cashierRepository.findOne(cashierId);
if (cashier == null) { throw new CashierNotFoundException(cashierId); }
this.fromApiJsonDeserializer.validateForCashTxnForCashier(command.json());
final String entityType = command.stringValueOfParameterNamed("entityType");
final Long entityId = command.longValueOfParameterNamed("entityId");
if (entityType != null) {
if (entityType.equals("loan account")) {
// TODO : Check if loan account exists
// LoanAccount loan = null;
// if (loan == null) { throw new LoanAccountFoundException(entityId); }
} else if (entityType.equals("savings account")) {
// TODO : Check if loan account exists
// SavingsAccount savingsaccount = null;
// if (savingsaccount == null) { throw new SavingsAccountNotFoundException(entityId); }
} if (entityType.equals("client")) {
// TODO: Check if client exists
// Client client = null;
// if (client == null) { throw new ClientNotFoundException(entityId); }
} else {
// TODO : Invalid type handling
}
if (entityType.equals("loan account")) {
// TODO : Check if loan account exists
// LoanAccount loan = null;
// if (loan == null) { throw new
// LoanAccountFoundException(entityId); }
} else if (entityType.equals("savings account")) {
// TODO : Check if loan account exists
// SavingsAccount savingsaccount = null;
// if (savingsaccount == null) { throw new
// SavingsAccountNotFoundException(entityId); }
}
if (entityType.equals("client")) {
// TODO: Check if client exists
// Client client = null;
// if (client == null) { throw new
// ClientNotFoundException(entityId); }
} else {
// TODO : Invalid type handling
}
}
final CashierTransaction cashierTxn = CashierTransaction.fromJson(cashier, command);
cashierTxn.setTxnType(txnType.getId());
this.cashierTxnRepository.save(cashierTxn);
// Pass the journal entries
FinancialActivityAccount mainVaultFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper.
findByFinancialActivityTypeWithNotFoundDetection(
FINANCIAL_ACTIVITY.CASH_AT_MAINVAULT.getValue());
FinancialActivityAccount tellerCashFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper.
findByFinancialActivityTypeWithNotFoundDetection(
FINANCIAL_ACTIVITY.CASH_AT_TELLER.getValue());
FinancialActivityAccount mainVaultFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper
.findByFinancialActivityTypeWithNotFoundDetection(FINANCIAL_ACTIVITY.CASH_AT_MAINVAULT.getValue());
FinancialActivityAccount tellerCashFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper
.findByFinancialActivityTypeWithNotFoundDetection(FINANCIAL_ACTIVITY.CASH_AT_TELLER.getValue());
GLAccount creditAccount = null;
GLAccount debitAccount = null;
if (txnType.equals(CashierTxnType.ALLOCATE) ) {
debitAccount = tellerCashFinancialActivityAccount.getGlAccount();
creditAccount = mainVaultFinancialActivityAccount.getGlAccount();
} else if (txnType.equals(CashierTxnType.SETTLE) ) {
debitAccount = mainVaultFinancialActivityAccount.getGlAccount();
creditAccount = tellerCashFinancialActivityAccount.getGlAccount();
}
if (txnType.equals(CashierTxnType.ALLOCATE)) {
debitAccount = tellerCashFinancialActivityAccount.getGlAccount();
creditAccount = mainVaultFinancialActivityAccount.getGlAccount();
} else if (txnType.equals(CashierTxnType.SETTLE)) {
debitAccount = mainVaultFinancialActivityAccount.getGlAccount();
creditAccount = tellerCashFinancialActivityAccount.getGlAccount();
}
final Office cashierOffice = cashier.getTeller().getOffice();
final Long time = System.currentTimeMillis();
final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId();
final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
final JournalEntry debitJournalEntry = JournalEntry.createNew(
cashierOffice, null, // payment detail
debitAccount, "USD", // FIXME: Take currency code from the transaction
transactionId, false, // manual entry
cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(),
cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number
null, null); // Loan and Savings Txn
final JournalEntry creditJournalEntry = JournalEntry.createNew(
cashierOffice, null, // payment detail
creditAccount, "USD", // FIXME: Take currency code from the transaction
transactionId, false, // manual entry
cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(),
cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number
null, null); // Loan and Savings Txn
this.glJournalEntryRepository.saveAndFlush(debitJournalEntry);
this.glJournalEntryRepository.saveAndFlush(creditJournalEntry);
final Long time = System.currentTimeMillis();
final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId();
final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
final JournalEntry debitJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
// detail
debitAccount, "USD", // FIXME: Take currency code from the
// transaction
transactionId, false, // manual entry
cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number
null, null); // Loan and Savings Txn
final JournalEntry creditJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
// detail
creditAccount, "USD", // FIXME: Take currency code from the
// transaction
transactionId, false, // manual entry
cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number
null, null); // Loan and Savings Txn
this.glJournalEntryRepository.saveAndFlush(debitJournalEntry);
this.glJournalEntryRepository.saveAndFlush(creditJournalEntry);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
@@ -400,7 +437,6 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
handleTellerDataIntegrityIssues(command, dve);
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;