Merge branch 'PULLREQUEST68' into develop

This commit is contained in:
Nazeer Hussain Shaik
2016-04-26 11:34:44 +05:30
17 changed files with 270 additions and 18 deletions
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract;
import org.apache.fineract.infrastructure.core.boot.AbstractApplicationConfiguration;
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract;
import java.awt.Desktop;
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot;
import java.io.File;
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.db;
import org.springframework.context.annotation.Bean;
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.db;
import javax.annotation.PostConstruct;
@@ -24,6 +24,7 @@ import java.util.List;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.portfolio.client.domain.ClientIdentifierStatus;
/**
* Immutable command for creating or updating details of a client identifier.
@@ -33,10 +34,12 @@ public class ClientIdentifierCommand {
private final Long documentTypeId;
private final String documentKey;
private final String description;
private final String status;
public ClientIdentifierCommand(final Long documentTypeId, final String documentKey, final String description) {
public ClientIdentifierCommand(final Long documentTypeId, final String documentKey, final String statusString, final String description) {
this.documentTypeId = documentTypeId;
this.documentKey = documentKey;
this.status = statusString;
this.description = description;
}
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.client.data;
import java.util.Collection;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
/**
* Immutable data object represent client identity data.
@@ -32,29 +33,32 @@ public class ClientIdentifierData {
private final CodeValueData documentType;
private final String documentKey;
private final String description;
private final String status;
@SuppressWarnings("unused")
private final Collection<CodeValueData> allowedDocumentTypes;
public static ClientIdentifierData singleItem(final Long id, final Long clientId, final CodeValueData documentType,
final String documentKey, final String description) {
return new ClientIdentifierData(id, clientId, documentType, documentKey, description, null);
final String documentKey, final String status, final String description) {
return new ClientIdentifierData(id, clientId, documentType, documentKey, description, status, null);
}
public static ClientIdentifierData template(final Collection<CodeValueData> codeValues) {
return new ClientIdentifierData(null, null, null, null, null, codeValues);
return new ClientIdentifierData(null, null, null, null, null, null, codeValues);
}
public static ClientIdentifierData template(final ClientIdentifierData data, final Collection<CodeValueData> codeValues) {
return new ClientIdentifierData(data.id, data.clientId, data.documentType, data.documentKey, data.description, codeValues);
return new ClientIdentifierData(data.id, data.clientId, data.documentType, data.documentKey, data.description, data.status, codeValues);
}
public ClientIdentifierData(final Long id, final Long clientId, final CodeValueData documentType, final String documentKey,
final String description, final Collection<CodeValueData> allowedDocumentTypes) {
final String description, final String status, final Collection<CodeValueData> allowedDocumentTypes) {
this.id = id;
this.clientId = clientId;
this.documentType = documentType;
this.documentKey = documentKey;
this.description = description;
this.allowedDocumentTypes = allowedDocumentTypes;
this.status = status;
}
}
@@ -37,7 +37,7 @@ import org.apache.fineract.useradministration.domain.AppUser;
@Entity
@Table(name = "m_client_identifier", uniqueConstraints = {
@UniqueConstraint(columnNames = { "document_type_id", "document_key" }, name = "unique_identifier_key"),
@UniqueConstraint(columnNames = { "client_id", "document_type_id" }, name = "unique_client_identifier") })
@UniqueConstraint(columnNames = { "client_id", "document_key", "active" }, name = "unique_active_client_identifier")})
public class ClientIdentifier extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@@ -50,25 +50,38 @@ public class ClientIdentifier extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "document_key", length = 1000)
private String documentKey;
@Column(name = "status", nullable = false)
private Integer status;
@Column(name = "description", length = 1000)
private String description;
@Column(name = "active")
private Integer active;
public static ClientIdentifier fromJson(final Client client, final CodeValue documentType, final JsonCommand command) {
final String documentKey = command.stringValueOfParameterNamed("documentKey");
final String description = command.stringValueOfParameterNamed("description");
return new ClientIdentifier(client, documentType, documentKey, description);
final String status = command.stringValueOfParameterNamed("status");
return new ClientIdentifier(client, documentType, documentKey, status, description);
}
protected ClientIdentifier() {
//
}
private ClientIdentifier(final Client client, final CodeValue documentType, final String documentKey, final String description) {
private ClientIdentifier(final Client client, final CodeValue documentType, final String documentKey, final String statusName, String description) {
this.client = client;
this.documentType = documentType;
this.documentKey = StringUtils.defaultIfEmpty(documentKey, null);
this.description = StringUtils.defaultIfEmpty(description, null);
ClientIdentifierStatus statusEnum = ClientIdentifierStatus.valueOf(statusName.toUpperCase());
this.active = null;
if(statusEnum.isActive()){
this.active = statusEnum.getValue();
}
this.status = statusEnum.getValue();
}
public void update(final CodeValue documentType) {
@@ -98,6 +111,13 @@ public class ClientIdentifier extends AbstractAuditableCustom<AppUser, Long> {
actualChanges.put(descriptionParamName, newValue);
this.description = StringUtils.defaultIfEmpty(newValue, null);
}
final String statusParamName = "status";
if(command.isChangeInStringParameterNamed(statusParamName, ClientIdentifierStatus.fromInt(this.status).getCode())){
final String newValue = command.stringValueOfParameterNamed(descriptionParamName);
actualChanges.put(descriptionParamName, ClientIdentifierStatus.valueOf(newValue));
this.status = ClientIdentifierStatus.valueOf(newValue).getValue();
}
return actualChanges;
}
@@ -0,0 +1,72 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.client.domain;
/**
* Enum representation of client identifier status states.
*/
public enum ClientIdentifierStatus {
INACTIVE(100, "clientIdentifierStatusType.inactive"), //
ACTIVE(200, "clientIdentifierStatusType.active"), //
INVALID(0,"clientIdentifierStatusType.invalid");
private final Integer value;
private final String code;
public static ClientIdentifierStatus fromInt(final Integer statusValue) {
ClientIdentifierStatus enumeration = ClientIdentifierStatus.INVALID;
switch (statusValue) {
case 100:
enumeration = ClientIdentifierStatus.INACTIVE;
break;
case 200:
enumeration = ClientIdentifierStatus.ACTIVE;
break;
}
return enumeration;
}
private ClientIdentifierStatus(final Integer value, final String code) {
this.value = value;
this.code = code;
}
// public boolean hasStateOf(final ClientIdentifierStatus state) {
// return this.value.equals(state.getValue());
// }
public Integer getValue() {
return this.value;
}
public String getCode() {
return this.code;
}
public boolean isInactive() {
return this.value.equals(ClientIdentifierStatus.INACTIVE.getValue());
}
public boolean isActive() {
return this.value.equals(ClientIdentifierStatus.ACTIVE.getValue());
}
}
@@ -31,7 +31,7 @@ public class DuplicateClientIdentifierException extends AbstractPlatformDomainRu
private final String identifierType;
public DuplicateClientIdentifierException(final String identifierType) {
super("error.msg.clientIdentifier.type.duplicate", "Client identifier of type " + identifierType
super("error.msg.clientIdentifier.type.duplicate", "Active Client identifier of type " + identifierType
+ " is already present for this client", identifierType);
this.identifierType = identifierType;
}
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.core.serialization.AbstractFromApiJson
import org.apache.fineract.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.portfolio.client.command.ClientIdentifierCommand;
import org.apache.fineract.portfolio.client.domain.ClientIdentifierStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -46,7 +47,7 @@ public final class ClientIdentifierCommandFromApiJsonDeserializer extends Abstra
/**
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList("documentTypeId", "documentKey", "description"));
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList("documentTypeId", "documentKey","status", "description"));
private final FromJsonHelper fromApiJsonHelper;
@@ -67,7 +68,7 @@ public final class ClientIdentifierCommandFromApiJsonDeserializer extends Abstra
final Long documentTypeId = this.fromApiJsonHelper.extractLongNamed("documentTypeId", element);
final String documentKey = this.fromApiJsonHelper.extractStringNamed("documentKey", element);
final String documentDescription = this.fromApiJsonHelper.extractStringNamed("documentDescription", element);
return new ClientIdentifierCommand(documentTypeId, documentKey, documentDescription);
final String statusString = this.fromApiJsonHelper.extractStringNamed("status", element);
return new ClientIdentifierCommand(documentTypeId, documentKey, statusString, documentDescription);
}
}
@@ -23,10 +23,12 @@ import java.sql.SQLException;
import java.util.Collection;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.client.data.ClientIdentifierData;
import org.apache.fineract.portfolio.client.domain.ClientIdentifierStatus;
import org.apache.fineract.portfolio.client.exception.ClientIdentifierNotFoundException;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
@@ -91,7 +93,7 @@ public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifier
public ClientIdentityMapper() {}
public String schema() {
return "ci.id as id, ci.client_id as clientId, ci.document_type_id as documentTypeId, ci.document_key as documentKey,"
return "ci.id as id, ci.client_id as clientId, ci.document_type_id as documentTypeId, ci.status as status, ci.document_key as documentKey,"
+ " ci.description as description, cv.code_value as documentType "
+ " from m_client_identifier ci, m_client c, m_office o, m_code_value cv"
+ " where ci.client_id=c.id and c.office_id=o.id" + " and ci.document_type_id=cv.id"
@@ -107,10 +109,9 @@ public class ClientIdentifierReadPlatformServiceImpl implements ClientIdentifier
final String documentKey = rs.getString("documentKey");
final String description = rs.getString("description");
final String documentTypeName = rs.getString("documentType");
final CodeValueData documentType = CodeValueData.instance(documentTypeId, documentTypeName);
return ClientIdentifierData.singleItem(id, clientId, documentType, documentKey, description);
final String status = ClientIdentifierStatus.fromInt(rs.getInt("status")).getCode();
return ClientIdentifierData.singleItem(id, clientId, documentType, documentKey, status, description);
}
}
@@ -98,6 +98,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
.build();
} catch (final DataIntegrityViolationException dve) {
handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve);
return CommandProcessingResult.empty();
}
}
@@ -181,7 +182,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId,
final String documentKey, final DataIntegrityViolationException dve) {
if (dve.getMostSpecificCause().getMessage().contains("unique_client_identifier")) {
if (dve.getMostSpecificCause().getMessage().contains("unique_active_client_identifier")) {
throw new DuplicateClientIdentifierException(documentTypeLabel);
} else if (dve.getMostSpecificCause().getMessage().contains("unique_identifier_key")) { throw new DuplicateClientIdentifierException(
documentTypeId, documentTypeLabel, documentKey); }
@@ -0,0 +1,6 @@
ALTER TABLE `m_client_identifier`
ADD COLUMN `status` INT(5) NOT NULL DEFAULT 300 AFTER `document_key`,
DROP INDEX `unique_client_identifier`,
ADD COLUMN `active` INT(5) NULL DEFAULT NULL AFTER `status`,
ADD UNIQUE INDEX `unique_active_client_identifier` (`client_id`, `document_type_id`, `active` );
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.tests;
import org.apache.fineract.ServerWithMariaDB4jApplication;
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.tests;
import static org.junit.Assert.assertTrue;
@@ -1,3 +1,21 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.tests;
import static org.hamcrest.Matchers.is;