Merge pull request #1611 from nazeer1100126/SharesAndDividends

Shares and dividends
This commit is contained in:
Adi Narayana Raju
2016-01-20 16:01:01 +05:30
46 changed files with 3243 additions and 0 deletions
@@ -2571,4 +2571,36 @@ public class CommandWrapperBuilder {
this.href = "/loans/" + loanId + "/schedule";
return this;
}
public CommandWrapperBuilder createProduct(String productType) {
this.entityName = productType.toUpperCase()+"PRODUCT" ; //To Support different type of products
this.actionName = "CREATE";
this.entityId = null;
this.href = "/products/"+productType;
return this;
}
public CommandWrapperBuilder updateProduct(String productType, final Long productId) {
this.entityName = productType.toUpperCase()+"PRODUCT" ;
this.actionName = "UPDATE";
this.entityId = productId;
this.href = "/products/" + productType+"/"+productId;
return this;
}
public CommandWrapperBuilder createAccount(String accountType) {
this.entityName = accountType.toUpperCase()+"ACCOUNT" ; //To Support different type of Accounts
this.actionName = "CREATE";
this.entityId = null;
this.href = "/accounts/"+accountType;
return this;
}
public CommandWrapperBuilder updateAccount(String accountType, final Long accountId) {
this.entityName = accountType.toUpperCase()+"ACCOUNT" ;
this.actionName = "UPDATE";
this.entityId = accountId;
this.href = "/accounts/" + accountType+"/"+accountId;
return this;
}
}
@@ -0,0 +1,127 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.api;
import java.util.Collection;
import java.util.HashSet;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.accounts.constants.AccountsApiConstants;
import org.mifosplatform.portfolio.accounts.data.AccountData;
import org.mifosplatform.portfolio.accounts.service.AccountReadPlatformService;
import org.mifosplatform.portfolio.accounts.service.AccountsCommandsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/accounts/{type}")
@Component
@Scope("singleton")
public class AccountsApiResource {
private final ApplicationContext applicationContext ;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<AccountData> toApiJsonSerializer;
private final PlatformSecurityContext platformSecurityContext;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
private final DefaultToApiJsonSerializer<Object> toApiObjectJsonSerializer ;
@Autowired
public AccountsApiResource(final ApplicationContext applicationContext,
final ApiRequestParameterHelper apiRequestParameterHelper,
final DefaultToApiJsonSerializer<AccountData> toApiJsonSerializer,
final PlatformSecurityContext platformSecurityContext,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final DefaultToApiJsonSerializer<Object> toApiObjectJsonSerializer) {
this.applicationContext = applicationContext ;
this.apiRequestParameterHelper = apiRequestParameterHelper ;
this.toApiJsonSerializer = toApiJsonSerializer ;
this.platformSecurityContext = platformSecurityContext ;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService ;
this.toApiObjectJsonSerializer = toApiObjectJsonSerializer ;
}
@GET
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAccount(@PathParam("accountId") final Long accountId, @PathParam("type") final String accountType,
@Context final UriInfo uriInfo) {
String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
AccountData data = service.retrieveOne(accountId) ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllAccounts(@PathParam("type") final String accountType, @Context final UriInfo uriInfo) {
String serviceName = accountType+AccountsApiConstants.READPLATFORM_NAME ;
AccountReadPlatformService service = (AccountReadPlatformService) this.applicationContext.getBean(serviceName) ;
Collection<AccountData> data = service.retrieveAll() ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createAccount(@PathParam("type") final String accountType, final String apiRequestBodyAsJson) {
CommandWrapper commandWrapper = null;
this.platformSecurityContext.authenticatedUser();
commandWrapper = new CommandWrapperBuilder().createAccount(accountType).withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult commandProcessingResult = this.commandsSourceWritePlatformService.logCommandSource(commandWrapper);
return this.toApiJsonSerializer.serialize(commandProcessingResult);
}
@POST
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String handleCommands(@PathParam("type") final String accountType, @PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo, final String apiRequestBodyAsJson) {
String serviceName = accountType.toUpperCase()+AccountsApiConstants.ACCOUNT_COMMANDSERVICE ;
AccountsCommandsService service = (AccountsCommandsService) this.applicationContext.getBean(serviceName) ;
final Object obj = service.handleCommand(accountId, commandParam, apiRequestBodyAsJson) ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiObjectJsonSerializer.serialize(settings, obj, new HashSet<String>());
}
@PUT
@Path("{accountId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateAccount(@PathParam("type") final String accountType, @PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) {
this.platformSecurityContext.authenticatedUser();
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateAccount(accountType, accountId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.constants;
public interface AccountsApiConstants {
public final String READPLATFORM_NAME = "AccountReadPlatformService" ;
public final String ACCOUNT_COMMANDSERVICE = "ACCOUNT_COMMANDSERVICE" ;
}
@@ -0,0 +1,64 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.constants;
public interface ShareAccountApiConstants {
//Command Strings
String APPROVE_COMMAND = "approve" ;
String REJECT_COMMAND = "reject" ;
String APPLY_ADDITIONALSHARES_COMMAND = "applyadditionalshares" ;
String APPROVE_ADDITIONSHARES_COMMAND = "approveadditionalshares" ;
String REJECT_ADDITIONSHARES_COMMAND = "rejectadditionalshares" ;
//
String id_paramname = "id" ;
String clientid_paramname = "clientId" ;
String productid_paramname = "productId" ;
String submitteddate_paramname = "submittedDate" ;
String approveddate_paramname = "approvedDate" ;
String fieldofferid_paramname = "fieldOfficerId" ;
String externalid_paramname = "externalId" ;
String currency_paramname = "currencyCode" ;
String digitsafterdecimal_paramname = "digitsAfterDecimal" ;
String inmultiplesof_paramname = "inMultiplesOf" ;
String purchasedshares_paramname = "purchasedShares" ;
String additionalshares_paramname = "additionalShares" ;
String suspenseaccount_paramname = "suspenseAccount" ;
String equityaccount_paramname = "equityAccount" ;
String savingsaccountid_paramname = "savingsAccountId" ;
String lockperiod_paramname = "lockPeriod" ;
String minimumactiveperiodfordividends_paramname = "minimumActivePeriodForDividends" ;
String allowdividendcalculationforinactiveclients_paramname = "allowDividendCalculationForInactiveClients" ;
String charges_paramname = "charges" ;
String purchaseddate_paramname = "purchasedDate" ;
String numberofshares_paramname = "numberOfShares" ;
String purchasedprice_paramname = "purchasedPrice" ;
}
@@ -0,0 +1,11 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.data;
public interface AccountData {
}
@@ -0,0 +1,47 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.data;
import java.math.BigDecimal;
import java.util.Date;
public class PurchasedSharesData {
private final Date purchasedDate ;
private final Long numberOfShares ;
private final BigDecimal purchasedPrice ;
private final String status ;
public PurchasedSharesData(final Date purchasedDate, final Long numberOfShares, final BigDecimal purchasedPrice, final String status) {
this.purchasedDate = purchasedDate ;
this.numberOfShares = numberOfShares ;
this.purchasedPrice = purchasedPrice ;
this.status = status ;
}
public Date getPurchasedDate() {
return this.purchasedDate;
}
public Long getNumberOfShares() {
return this.numberOfShares;
}
public BigDecimal getPurchasedPrice() {
return this.purchasedPrice;
}
public String getStatus() {
return this.status ;
}
}
@@ -0,0 +1,86 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.data;
import java.util.Collection;
import java.util.Date;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
public class ShareAccountData implements AccountData{
private Long id;
private String accountNo;
private String externalId;
private Long productId;
private String productName;
private String loanProductDescription;
private Long fieldOfficerId;
private String fieldOfficerName;
private Long clientId;
private String clientName;
private Long clientOfficeId;
private CurrencyData currency;
private Date submittedDate;
private Date approvedDate;
private Collection<PurchasedSharesData> purchasedShares;
private GLAccountData suspenseAccount;
private GLAccountData equityAccount;
private Long savingsAccountId;
private EnumOptionData lockPeriod;
private EnumOptionData minimumActivePeriodForDividends;
private Boolean allowDividendCalculationForInactiveClients;
private Collection<ShareChargeData> charges ;
private String status ;
public ShareAccountData(final Long id, final String accountNo, final Long clientId, final String clientName, final Long productId, final String productName,
final Long fieldOfficerId, final String externalId, final Date submittedDate, final Collection<PurchasedSharesData> purchasedShares, final GLAccountData suspenseAccount,
final GLAccountData equityAccount, final EnumOptionData lockPeriod, final EnumOptionData minimumActivePeriodForDividends,
final Boolean allowDividendCalculationForInactiveClients, final Collection<ShareChargeData> charges, final String status) {
this.id = id ;
this.accountNo = accountNo ;
this.clientId = clientId ;
this.clientName = clientName ;
this.productId = productId ;
this.productName = productName ;
this.fieldOfficerId = fieldOfficerId ;
this.externalId = externalId ;
this.submittedDate = submittedDate ;
this.purchasedShares = purchasedShares ;
this.suspenseAccount = suspenseAccount ;
this.equityAccount = equityAccount ;
this.lockPeriod = lockPeriod ;
this.minimumActivePeriodForDividends = minimumActivePeriodForDividends ;
this.allowDividendCalculationForInactiveClients = allowDividendCalculationForInactiveClients ;
this.charges = charges ;
this.status = status ;
}
}
@@ -0,0 +1,19 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.data;
public class ShareChargeData {
private Long accountId ;
private Long chargeId ;
public ShareChargeData(final Long accountId, final Long chargeId) {
this.accountId = accountId ;
this.chargeId = chargeId ;
}
}
@@ -0,0 +1,80 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.domain;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.mifosplatform.portfolio.accounts.data.PurchasedSharesData;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_purchasedshares")
public class PurchasedShares extends AbstractPersistable<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "account_id", referencedColumnName = "id", nullable = false)
private ShareAccount shareAccount ;
@Column(name = "purchased_date")
@Temporal(TemporalType.DATE)
private Date purchasedDate ;
@Column(name = "share_count")
private Long totalShares ;
@Column(name = "share_price")
private BigDecimal shareValue ;
@Column(name ="status")
private String status = "Submitted";
protected PurchasedShares() {
}
public void setShareAccount(final ShareAccount shareAccount) {
this.shareAccount = shareAccount ;
}
public PurchasedShares(final Date purchasedDate, final Long totalShares, final BigDecimal shareValue) {
this.purchasedDate = purchasedDate ;
this.totalShares = totalShares ;
this.shareValue = shareValue ;
}
public PurchasedSharesData toData() {
return new PurchasedSharesData(this.purchasedDate, this.totalShares, this.shareValue, this.status) ;
}
public Date getPurchasedDate() {
return this.purchasedDate ;
}
public Long getTotalShares() {
return this.totalShares ;
}
public BigDecimal getPurchasePrice() {
return this.shareValue ;
}
public String getStatus() {
return this.status ;
}
public void setStatus(String status) {
this.status = status ;
}
}
@@ -0,0 +1,320 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
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 org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.joda.time.DateTime;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.accounts.data.PurchasedSharesData;
import org.mifosplatform.portfolio.accounts.data.ShareAccountData;
import org.mifosplatform.portfolio.accounts.data.ShareChargeData;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
import org.mifosplatform.portfolio.shares.domain.ShareProduct;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@Table(name = "m_shareaccounts")
public class ShareAccount extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "client_id", nullable = true)
private Client client ;
@ManyToOne
@JoinColumn(name = "product_id", nullable = true)
private ShareProduct shareProduct ;
@Column(name = "submitted_date")
@Temporal(TemporalType.TIMESTAMP)
private Date submittedDate ;
@Column(name = "approved_date")
@Temporal(TemporalType.TIMESTAMP)
private Date approvedDate ;
@Column(name = "field_officer")
private Long fieldOfficerId ;
@Column(name = "external_id")
private String externalId ;
@Embedded
private MonetaryCurrency currency;
@ManyToOne
@JoinColumn(name = "suspense_account", nullable = true)
private GLAccount suspenseAccount ;
@ManyToOne
@JoinColumn(name = "equity_account", nullable = true)
private GLAccount equityAccount ;
@ManyToOne
@JoinColumn(name = "savings_id", nullable = true)
private SavingsAccount savingsAccount ;
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccount", orphanRemoval = true)
private Set<PurchasedShares> purchasedShares ;
@Column(name = "allow_dividends_inactive_clients")
private Boolean allowDividendCalculationForInactiveClients;
@Enumerated(EnumType.ORDINAL)
@Column(name = "lock_period", nullable = true)
private PeriodFrequencyType lockPeriod;
@Enumerated(EnumType.ORDINAL)
@Column(name = "dividend_active_period", nullable = true)
private PeriodFrequencyType minimumActivePeriodForDividends;
@Column(name = "status")
private String status = "Submitted"; //change it to enum
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccount", orphanRemoval = true)
private Set<ShareAccountCharge> charges ;
protected ShareAccount() {
}
public ShareAccount(final Client client, final ShareProduct shareProduct, final Date submittedDate, final Date approvedDate,
final Long fieldOfficerId , final String externalId, final MonetaryCurrency currency, GLAccount suspenseAccount,
final GLAccount equityAccount, final SavingsAccount savingsAccount, final Set<PurchasedShares> purchasedShares,
final Boolean allowDividendCalculationForInactiveClients, final PeriodFrequencyType lockPeriod,
final PeriodFrequencyType minimumActivePeriodForDividends, Set<ShareAccountCharge> charges,
AppUser createdBy, DateTime createdDate, AppUser lastModifiedBy, DateTime lastModifiedDate) {
this.client = client ;
this.shareProduct = shareProduct ;
this.submittedDate = submittedDate ;
this.approvedDate = approvedDate ;
this.fieldOfficerId = fieldOfficerId ;
this.externalId = externalId ;
this.currency = currency ;
this.suspenseAccount = suspenseAccount ;
this.equityAccount = equityAccount ;
this.savingsAccount = savingsAccount ;
this.purchasedShares = purchasedShares ;
this.allowDividendCalculationForInactiveClients = allowDividendCalculationForInactiveClients ;
this.lockPeriod = lockPeriod ;
this.minimumActivePeriodForDividends = minimumActivePeriodForDividends ;
this.charges = charges ;
setCreatedBy(createdBy) ;
setCreatedDate(createdDate) ;
setLastModifiedBy(lastModifiedBy) ;
setLastModifiedDate(lastModifiedDate) ;
}
public boolean setShareProduct(final ShareProduct shareProduct) {
boolean toReturn = false ;
if(!this.shareProduct.getId().equals(shareProduct.getId())) {
this.shareProduct = shareProduct ;
toReturn = true ;
}
return toReturn ;
}
public ShareProduct getShareProduct() {
return this.shareProduct ;
}
public boolean setSubmittedDate(final Date submittedDate) {
boolean toReturn = false ;
if(!this.submittedDate.equals(submittedDate)) {
this.submittedDate = submittedDate ;
toReturn = true ;
}
return toReturn ;
}
public boolean setApprovedDate(final Date approvedDate) {
boolean toReturn = false ;
if(!this.approvedDate.equals(approvedDate)) {
this.approvedDate = approvedDate ;
toReturn = true ;
}
return toReturn ;
}
public boolean setFieldOfficer(final Long fieldOfficerId) {
boolean toReturn = false ;
if(!this.fieldOfficerId.equals(fieldOfficerId)) {
this.fieldOfficerId = fieldOfficerId ;
toReturn = true ;
}
return toReturn ;
}
public boolean setExternalId(final String externalId) {
boolean toReturn = false ;
if(!this.externalId.equals(externalId)) {
this.externalId = externalId ;
toReturn = true ;
}
return toReturn ;
}
public boolean setSuspenseAccount(GLAccount suspenseAccount) {
boolean returnValue = false;
if (!this.suspenseAccount.getId().equals(suspenseAccount.getId())) {
this.suspenseAccount = suspenseAccount;
returnValue = true;
}
return returnValue;
}
public boolean setEquityAccount(GLAccount equityAccount) {
boolean returnValue = false;
if (!this.equityAccount.getId().equals(equityAccount.getId())) {
this.equityAccount = equityAccount;
returnValue = true;
}
return returnValue;
}
public boolean setSavingsAccount(final SavingsAccount savingsAccount) {
boolean returnValue = false;
if (!this.savingsAccount.getId().equals(savingsAccount.getId())) {
this.savingsAccount = savingsAccount;
returnValue = true;
}
return returnValue;
}
public boolean setPurchasedShares(Set<PurchasedShares> purchasedShares) {
this.purchasedShares = purchasedShares ;
return true ;
}
public boolean setAllowDividendCalculationForInactiveClients(Boolean allowDividendCalculationForInactiveClients) {
boolean returnValue = false;
if (!this.allowDividendCalculationForInactiveClients.equals(allowDividendCalculationForInactiveClients)) {
this.allowDividendCalculationForInactiveClients = allowDividendCalculationForInactiveClients;
returnValue = true;
}
return returnValue;
}
public boolean setLockPeriod(final PeriodFrequencyType lockPeriod) {
boolean returnValue = false;
if (!this.lockPeriod.equals(lockPeriod)) {
this.lockPeriod = lockPeriod;
returnValue = true;
}
return returnValue;
}
public boolean setminimumActivePeriodForDividends(final PeriodFrequencyType minimumActivePeriodForDividends) {
boolean returnValue = false;
if (!this.minimumActivePeriodForDividends.equals(minimumActivePeriodForDividends)) {
this.minimumActivePeriodForDividends = minimumActivePeriodForDividends;
returnValue = true;
}
return returnValue;
}
public boolean setCharges(final Set<ShareAccountCharge> charges) {
this.charges = charges ;
return true ;
}
//FIXME: Remove this
public void setTempId(Long id) {
setId(id) ;
}
public ShareAccountData toData() {
String accountNo = "000025900"+getId() ;
Collection<PurchasedSharesData> purchasedSharesdata = new ArrayList<>();
for(PurchasedShares val: purchasedShares) {
purchasedSharesdata.add(new PurchasedSharesData(val.getPurchasedDate(), val.getTotalShares(), val.getPurchasePrice(), val.getStatus())) ;
}
Collection<ShareChargeData> chargesdata = new ArrayList<>();
for(ShareAccountCharge charge: charges) {
chargesdata.add(new ShareChargeData(charge.getAccountId(), charge.getChargeId())) ;
}
GLAccountData suspenseAccount1 = new GLAccountData(suspenseAccount.getId(), suspenseAccount.getName(), suspenseAccount.getGlCode());
GLAccountData equityAccount1 = new GLAccountData(equityAccount.getId(), equityAccount.getName(), equityAccount.getGlCode());
EnumOptionData lock = new EnumOptionData(this.lockPeriod.getValue().longValue(), this.lockPeriod.getCode(),
this.lockPeriod.toString());
EnumOptionData mini = new EnumOptionData(this.minimumActivePeriodForDividends.getValue().longValue(), this.minimumActivePeriodForDividends.getCode(),
this.minimumActivePeriodForDividends.toString());;
ShareAccountData data = new ShareAccountData(getId(), accountNo, this.client.getId(), this.client.getDisplayName(), this.shareProduct.getId(),
this.shareProduct.getProductName(), fieldOfficerId, externalId,
submittedDate, purchasedSharesdata, suspenseAccount1, equityAccount1, lock, mini,
allowDividendCalculationForInactiveClients, chargesdata, status) ;
return data ;
}
public Long getClientId() {
return this.client.getId() ;
}
public String getClientName() {
return this.client.getDisplayName() ;
}
public Long getTotalShares() {
long value = 0 ;
for(PurchasedShares val: purchasedShares) {
if(val.getStatus().equals("Approved")) {
value += val.getTotalShares().longValue() ;
}
}
return new Long(value) ;
}
public String getShareAccountNo() {
return "000025900"+getId() ;
}
public String getSavingsAccountNo() {
return this.savingsAccount.getAccountNumber() ;
}
public void setStatus(String status) {
this.status = status ;
}
public String getStatus() {
return this.status ;
}
public void addAddtionalShares(Set<PurchasedShares> additionalShares) {
this.purchasedShares.addAll(additionalShares) ;
}
public Set<PurchasedShares> getPurchasedShares() {
return this.purchasedShares ;
}
}
@@ -0,0 +1,52 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.domain;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_shareaccounts_charges")
public class ShareAccountCharge extends AbstractPersistable<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "account_id", referencedColumnName = "id", nullable = false)
private ShareAccount shareAccount;
@ManyToOne(optional = false)
@JoinColumn(name = "charge_id", referencedColumnName = "id", nullable = false)
private Charge charge;
protected ShareAccountCharge() {
}
public ShareAccountCharge(final ShareAccount shareAccount, final Charge charge) {
this.shareAccount = shareAccount;
this.charge = charge;
}
public ShareAccountCharge(final Charge charge) {
this.charge = charge;
}
public void setShareAccount(ShareAccount shareAccount) {
this.shareAccount = shareAccount;
}
public Long getAccountId() {
return this.shareAccount.getId() ;
}
public Long getChargeId() {
return this.charge.getId() ;
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ShareAccountRepository extends JpaRepository<ShareAccount, Long>, JpaSpecificationExecutor<ShareAccount> {
}
@@ -0,0 +1,43 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.domain;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.mifosplatform.portfolio.shares.domain.ShareProductTempRepository;
public class ShareAccountTempRepository {
private final static ShareAccountTempRepository instance = new ShareAccountTempRepository() ;
private Map<Long, ShareAccount> cache = new HashMap<>() ;
private ShareAccountTempRepository() {
}
public static ShareAccountTempRepository getInstance() {
return instance ;
}
public void save(ShareAccount account) {
Long id = new Long(cache.size()+1) ;
account.setTempId(id) ;
cache.put(id, account) ;
ShareProductTempRepository.getInstance().addAccount(account.getShareProduct().getId(), account) ;
}
public ShareAccount findOne(Long id) {
return cache.get(id) ;
}
public Collection<ShareAccount> findAll() {
return cache.values() ;
}
}
@@ -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.portfolio.accounts.exceptions;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class ShareAccountNotFoundException extends AbstractPlatformResourceNotFoundException{
public ShareAccountNotFoundException(final Long id) {
super("error.msg.shareaccount.id.invalid", " Account with identifier " + id + " does not exist" , id);
}
}
@@ -0,0 +1,34 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.handler;
import org.mifosplatform.commands.annotation.CommandType;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.accounts.service.ShareAccountWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "SHAREACCOUNT", action = "CREATE")
public class CreateShareAccountCommandHandler implements NewCommandSourceHandler{
private final ShareAccountWritePlatformService shareAccountWritePlatformService ;
@Autowired
public CreateShareAccountCommandHandler(final ShareAccountWritePlatformService shareAccountWritePlatformService) {
this.shareAccountWritePlatformService = shareAccountWritePlatformService ;
}
@Transactional
@Override
public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
return this.shareAccountWritePlatformService.createShareAccount(jsonCommand);
}
}
@@ -0,0 +1,34 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.handler;
import org.mifosplatform.commands.annotation.CommandType;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.accounts.service.ShareAccountWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "SHAREACCOUNT", action = "UPDATE")
public class UpdateShareAccountCommandHandler implements NewCommandSourceHandler {
private final ShareAccountWritePlatformService shareAccountWritePlatformService ;
@Autowired
public UpdateShareAccountCommandHandler(final ShareAccountWritePlatformService shareAccountWritePlatformService) {
this.shareAccountWritePlatformService = shareAccountWritePlatformService ;
}
@Transactional
@Override
public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
return this.shareAccountWritePlatformService.updateShareAccount(jsonCommand.entityId(), jsonCommand);
}
}
@@ -0,0 +1,320 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.serialization;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepositoryWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.accounts.constants.ShareAccountApiConstants;
import org.mifosplatform.portfolio.accounts.domain.PurchasedShares;
import org.mifosplatform.portfolio.accounts.domain.ShareAccount;
import org.mifosplatform.portfolio.accounts.domain.ShareAccountCharge;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.mifosplatform.portfolio.products.exception.ProductNotFoundException;
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
import org.mifosplatform.portfolio.savings.domain.SavingsAccountRepositoryWrapper;
import org.mifosplatform.portfolio.shares.domain.ShareProduct;
import org.mifosplatform.portfolio.shares.domain.ShareProductTempRepository;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
@Service
public class ShareAccountDataSerializer {
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList(""));
private final PlatformSecurityContext platformSecurityContext;
private final FromJsonHelper fromApiJsonHelper;
private final ChargeRepositoryWrapper chargeRepository;
private final GLAccountRepositoryWrapper glAccountRepository;
private final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper;
private final ClientRepositoryWrapper clientRepositoryWrapper;
@Autowired
public ShareAccountDataSerializer(final PlatformSecurityContext platformSecurityContext, final FromJsonHelper fromApiJsonHelper,
final ChargeRepositoryWrapper chargeRepository, GLAccountRepositoryWrapper glAccountRepository,
final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper, final ClientRepositoryWrapper clientRepositoryWrapper) {
this.platformSecurityContext = platformSecurityContext;
this.fromApiJsonHelper = fromApiJsonHelper;
this.chargeRepository = chargeRepository;
this.glAccountRepository = glAccountRepository;
this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper;
this.clientRepositoryWrapper = clientRepositoryWrapper;
}
public ShareAccount validateAndCreate(JsonCommand jsonCommand) {
if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
//this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
JsonElement element = jsonCommand.parsedJson();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
final Long clientId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.clientid_paramname, element);
final Long productId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.productid_paramname, element);
final Date submittedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.submitteddate_paramname, element)
.toDate();
// On creation submitted date will not be there.
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.fieldofferid_paramname, element);
final String externalId = this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.externalid_paramname, element);
Long suspenseAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.suspenseaccount_paramname, element);
Long equityAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.equityaccount_paramname, element);
Long savingsAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.savingsaccountid_paramname, element);
Set<PurchasedShares> sharesPurchased = asemblePurchasedShares(element);
Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed(
ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element);
PeriodFrequencyType lockPeriod = extractPeriodType(ShareAccountApiConstants.lockperiod_paramname, element);
PeriodFrequencyType minimumActivePeriod = extractPeriodType(ShareAccountApiConstants.minimumactiveperiodfordividends_paramname,
element);
Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
GLAccount suspenseAccount = glAccountRepository.findOneWithNotFoundDetection(suspenseAccountId);
GLAccount equityAccount = glAccountRepository.findOneWithNotFoundDetection(equityAccountId);
SavingsAccount savingsAccount = this.savingsAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsAccountId);
ShareProduct shareProduct = ShareProductTempRepository.getInstance().fineOne(productId);
if(shareProduct == null) {
throw new ProductNotFoundException(productId, "Share") ;
}
final MonetaryCurrency currency = shareProduct.getCurrency() ;
Set<ShareAccountCharge> charges = assembleListOfAccountCharges(element, currency.getCode());
AppUser modifiedBy = null;
DateTime modifiedOn = null;
Date approvedDate = null;
AppUser createdBy = platformSecurityContext.authenticatedUser();
DateTime createdDate = DateUtils.getLocalDateTimeOfTenant().toDateTime();
ShareAccount account = new ShareAccount(client, shareProduct, submittedDate, approvedDate, fieldOfficerId, externalId, currency,
suspenseAccount, equityAccount, savingsAccount, sharesPurchased, allowdividendsForInactiveClients, lockPeriod,
minimumActivePeriod, charges, createdBy, createdDate, modifiedBy, modifiedOn);
for(PurchasedShares pur: sharesPurchased) {
pur.setShareAccount(account) ;
}
for(ShareAccountCharge charge: charges) {
charge.setShareAccount(account) ;
}
return account;
}
public Map<String, Object> validateAndUpdate(JsonCommand jsonCommand, ShareAccount account) {
Map<String, Object> actualChanges = new HashMap<>();
if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
//this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesaccount");
JsonElement element = jsonCommand.parsedJson();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.productid_paramname, element)) {
final Long productId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.productid_paramname, element);
ShareProduct shareProduct = ShareProductTempRepository.getInstance().fineOne(productId);
if(account.setShareProduct(shareProduct)) {
actualChanges.put(ShareAccountApiConstants.productid_paramname, shareProduct) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.submitteddate_paramname, element)) {
final Date submittedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.submitteddate_paramname, element)
.toDate();
if(account.setSubmittedDate(submittedDate)) {
actualChanges.put(ShareAccountApiConstants.submitteddate_paramname, submittedDate) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.fieldofferid_paramname, element)) {
final Long fieldOfficerId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.fieldofferid_paramname, element);
if(account.setFieldOfficer(fieldOfficerId)){
actualChanges.put(ShareAccountApiConstants.fieldofferid_paramname, fieldOfficerId) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.externalid_paramname, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(ShareAccountApiConstants.externalid_paramname, element);
if(account.setExternalId(externalId)) {
actualChanges.put(ShareAccountApiConstants.externalid_paramname, externalId) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.suspenseaccount_paramname, element)) {
Long suspenseAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.suspenseaccount_paramname, element);
GLAccount suspenseAccount = glAccountRepository.findOneWithNotFoundDetection(suspenseAccountId);
if(account.setSuspenseAccount(suspenseAccount)) {
actualChanges.put(ShareAccountApiConstants.suspenseaccount_paramname, suspenseAccount) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.equityaccount_paramname, element)) {
Long equityAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.equityaccount_paramname, element);
GLAccount equityAccount = glAccountRepository.findOneWithNotFoundDetection(equityAccountId);
if(account.setEquityAccount(equityAccount)) {
actualChanges.put(ShareAccountApiConstants.equityaccount_paramname, equityAccount) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.savingsaccountid_paramname, element)) {
Long savingsAccountId = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.savingsaccountid_paramname, element);
SavingsAccount savingsAccount = this.savingsAccountRepositoryWrapper.findOneWithNotFoundDetection(savingsAccountId);
if(account.setSavingsAccount(savingsAccount)) {
actualChanges.put(ShareAccountApiConstants.savingsaccountid_paramname, savingsAccount) ;
}
}
if(this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.purchasedshares_paramname, element)) {
Set<PurchasedShares> sharesPurchased = asemblePurchasedShares(element);
account.setPurchasedShares(sharesPurchased) ;
actualChanges.put(ShareAccountApiConstants.purchasedshares_paramname, sharesPurchased) ;
}
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element)) {
Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed(
ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname, element);
if (account.setAllowDividendCalculationForInactiveClients(allowdividendsForInactiveClients)) {
actualChanges.put(ShareAccountApiConstants.allowdividendcalculationforinactiveclients_paramname,
allowdividendsForInactiveClients);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.lockperiod_paramname, element)) {
PeriodFrequencyType lockPeriod = extractPeriodType(ShareAccountApiConstants.lockperiod_paramname, element);
if (account.setLockPeriod(lockPeriod)) {
actualChanges.put(ShareAccountApiConstants.lockperiod_paramname, lockPeriod);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.minimumactiveperiodfordividends_paramname, element)) {
PeriodFrequencyType minimumActivePeriod = extractPeriodType(ShareAccountApiConstants.minimumactiveperiodfordividends_paramname,
element);
if (account.setminimumActivePeriodForDividends(minimumActivePeriod)) {
actualChanges.put(ShareAccountApiConstants.minimumactiveperiodfordividends_paramname, minimumActivePeriod);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
ShareProduct shareProduct = account.getShareProduct() ;
Set<ShareAccountCharge> charges = assembleListOfAccountCharges(element, shareProduct.getCurrency().getCode());
if(account.setCharges(charges)) {
actualChanges.put(ShareAccountApiConstants.charges_paramname, charges);
}
}
AppUser modifiedBy = platformSecurityContext.authenticatedUser();
DateTime modifiedOn = DateUtils.getLocalDateTimeOfTenant().toDateTime();
return actualChanges;
}
private Set<ShareAccountCharge> assembleListOfAccountCharges(final JsonElement element, final String currencyCode) {
final Set<ShareAccountCharge> charges = new HashSet<>();
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.charges_paramname, element)) {
JsonArray chargesArray = this.fromApiJsonHelper.extractJsonArrayNamed(ShareAccountApiConstants.charges_paramname, element);
if (chargesArray != null) {
for (int i = 0; i < chargesArray.size(); i++) {
final JsonObject jsonObject = chargesArray.get(i).getAsJsonObject();
if (jsonObject.has("id")) {
final Long id = jsonObject.get("id").getAsLong();
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(id);
if (!currencyCode.equals(charge.getCurrencyCode())) {
final String errorMessage = "Charge and Share Account must have the same currency.";
throw new InvalidCurrencyException("charge", "attach.to.share.account", errorMessage);
}
ShareAccountCharge accountCharge = new ShareAccountCharge(charge);
charges.add(accountCharge);
}
}
}
}
return charges;
}
private PeriodFrequencyType extractPeriodType(String paramName, final JsonElement element) {
PeriodFrequencyType frequencyType = PeriodFrequencyType.INVALID;
frequencyType = PeriodFrequencyType.fromInt(this.fromApiJsonHelper.extractIntegerWithLocaleNamed(paramName, element));
return frequencyType;
}
private Set<PurchasedShares> asemblePurchasedShares(final JsonElement element) {
Set<PurchasedShares> set = null;
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.purchasedshares_paramname, element)) {
set = new HashSet<>();
JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareAccountApiConstants.purchasedshares_paramname, element);
for (JsonElement arrayElement : array) {
LocalDate localDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.purchaseddate_paramname,
arrayElement);
final Long shares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.numberofshares_paramname, arrayElement);
final BigDecimal shareValue = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
ShareAccountApiConstants.purchasedprice_paramname, arrayElement);
PurchasedShares obj = new PurchasedShares(localDate.toDate(), shares, shareValue);
set.add(obj);
}
}
return set;
}
public Set<PurchasedShares> asembleAdditionalShares(final JsonElement element) {
Set<PurchasedShares> set = null;
if (this.fromApiJsonHelper.parameterExists(ShareAccountApiConstants.additionalshares_paramname, element)) {
set = new HashSet<>();
JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareAccountApiConstants.additionalshares_paramname, element);
for (JsonElement arrayElement : array) {
LocalDate localDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.purchaseddate_paramname,
arrayElement);
final Long shares = this.fromApiJsonHelper.extractLongNamed(ShareAccountApiConstants.numberofshares_paramname, arrayElement);
final BigDecimal shareValue = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
ShareAccountApiConstants.purchasedprice_paramname, arrayElement);
PurchasedShares obj = new PurchasedShares(localDate.toDate(), shares, shareValue);
set.add(obj);
}
}
return set;
}
}
@@ -0,0 +1,21 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.service;
import java.util.Collection;
import java.util.Set;
import org.mifosplatform.portfolio.accounts.data.AccountData;
public interface AccountReadPlatformService {
public AccountData retrieveOne(Long id) ;
public Collection<AccountData> retrieveAll() ;
public Set<String> getResponseDataParams();
}
@@ -0,0 +1,12 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.service;
public interface AccountsCommandsService {
public Object handleCommand(final Long accountId, final String command, final String jsonBody) ;
}
@@ -0,0 +1,123 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.service;
import java.util.Set;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.accounts.constants.ShareAccountApiConstants;
import org.mifosplatform.portfolio.accounts.domain.PurchasedShares;
import org.mifosplatform.portfolio.accounts.domain.ShareAccount;
import org.mifosplatform.portfolio.accounts.domain.ShareAccountTempRepository;
import org.mifosplatform.portfolio.accounts.serialization.ShareAccountDataSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service(value = "SHAREACCOUNT_COMMANDSERVICE")
public class ShareAccountCommandsServiceImpl implements AccountsCommandsService {
private final FromJsonHelper fromApiJsonHelper;
private final ShareAccountDataSerializer shareAccountDataSerializer ;
@Autowired
public ShareAccountCommandsServiceImpl(final FromJsonHelper fromApiJsonHelper,
final ShareAccountDataSerializer shareAccountDataSerializer) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.shareAccountDataSerializer = shareAccountDataSerializer ;
}
@Override
public Object handleCommand(Long accountId, String command, String jsonBody) {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonBody);
final JsonCommand jsonCommand = JsonCommand.from(jsonBody, parsedCommand, this.fromApiJsonHelper, null, null, null, null, null,
null, null, null, null, null);
if(ShareAccountApiConstants.APPROVE_COMMAND.equals(command)){
return approveShareAccount(accountId, jsonCommand) ;
}if(ShareAccountApiConstants.REJECT_COMMAND.equals(command)){
return rejectShareAccount(accountId, jsonCommand) ;
}else if(ShareAccountApiConstants.APPLY_ADDITIONALSHARES_COMMAND.equals(command)) {
return applyAdditionalShares(accountId, jsonCommand) ;
}else if(ShareAccountApiConstants.APPROVE_ADDITIONSHARES_COMMAND.equals(command)) {
return approveAdditionalShares(accountId, jsonCommand) ;
}else if(ShareAccountApiConstants.REJECT_ADDITIONSHARES_COMMAND.equals(command)) {
return rejectAdditionalShares(accountId, jsonCommand) ;
}
return CommandProcessingResult.empty();
}
public Object approveShareAccount(Long accountId, JsonCommand jsonCommand) {
//We need to add approval date also
ShareAccount account = ShareAccountTempRepository.getInstance().findOne(accountId);
account.setStatus("Approved");
Set<PurchasedShares> purchasedShares = account.getPurchasedShares() ;
for(PurchasedShares pur: purchasedShares) {
pur.setStatus("Approved") ;
}
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
.build();
}
public Object rejectShareAccount(Long accountId, JsonCommand jsonCommand) {
ShareAccount account = ShareAccountTempRepository.getInstance().findOne(accountId);
account.setStatus("Rejected");
//rejection date we need to capture
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
.build();
}
public Object applyAdditionalShares(Long accountId, JsonCommand jsonCommand) {
ShareAccount account = ShareAccountTempRepository.getInstance().findOne(accountId);
Set<PurchasedShares> additionalShares = this.shareAccountDataSerializer.asembleAdditionalShares(jsonCommand.parsedJson()) ;
account.addAddtionalShares(additionalShares) ;
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
.build();
}
public Object approveAdditionalShares(Long accountId, JsonCommand jsonCommand) {
//user might have requested for different dates.
//we need to capture either purchase date or ids []
ShareAccount account = ShareAccountTempRepository.getInstance().findOne(accountId);
Set<PurchasedShares> purchasedShares = account.getPurchasedShares() ;
for(PurchasedShares pur: purchasedShares) {
if(pur.getStatus().equals("Submitted") && !pur.getStatus().equals("Rejected")) {
pur.setStatus("Approved") ;
}
}
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
.build();
}
public Object rejectAdditionalShares(Long accountId, JsonCommand jsonCommand) {
//user might have requested for different dates.
//we need to capture either purchase date or ids []
ShareAccount account = ShareAccountTempRepository.getInstance().findOne(accountId);
Set<PurchasedShares> purchasedShares = account.getPurchasedShares() ;
for(PurchasedShares pur: purchasedShares) {
if(pur.getStatus().equals("Submitted")) {
pur.setStatus("Rejected") ;
}
}
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
.build();
}
}
@@ -0,0 +1,40 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.service;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.mifosplatform.portfolio.accounts.constants.AccountsApiConstants;
import org.mifosplatform.portfolio.accounts.data.AccountData;
import org.mifosplatform.portfolio.accounts.domain.ShareAccount;
import org.mifosplatform.portfolio.accounts.domain.ShareAccountTempRepository;
import org.springframework.stereotype.Service;
@Service(value = "share"+AccountsApiConstants.READPLATFORM_NAME)
public class ShareAccountReadPlatformServiceImpl implements AccountReadPlatformService{
@Override
public AccountData retrieveOne(Long id) {
return ShareAccountTempRepository.getInstance().findOne(id).toData();
}
@Override
public Collection<AccountData> retrieveAll() {
Collection<ShareAccount> collection = ShareAccountTempRepository.getInstance().findAll() ;
Set<AccountData> set = new HashSet<>() ;
for(ShareAccount data: collection) {
set.add(data.toData()) ;
}
return set;
}
@Override
public Set<String> getResponseDataParams() {
return null;
}
}
@@ -0,0 +1,17 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.service;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
public interface ShareAccountWritePlatformService {
public CommandProcessingResult createShareAccount(JsonCommand jsonCommand) ;
public CommandProcessingResult updateShareAccount(Long accountId, JsonCommand jsonCommand) ;
}
@@ -0,0 +1,72 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.accounts.service;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.portfolio.accounts.domain.ShareAccount;
import org.mifosplatform.portfolio.accounts.domain.ShareAccountTempRepository;
import org.mifosplatform.portfolio.accounts.exceptions.ShareAccountNotFoundException;
import org.mifosplatform.portfolio.accounts.serialization.ShareAccountDataSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
@Service
public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareAccountWritePlatformService {
private final ShareAccountDataSerializer accountDataSerializer;
@Autowired
public ShareAccountWritePlatformServiceJpaRepositoryImpl(final ShareAccountDataSerializer accountDataSerializer) {
this.accountDataSerializer = accountDataSerializer;
}
@Override
public CommandProcessingResult createShareAccount(JsonCommand jsonCommand) {
try {
ShareAccount account = this.accountDataSerializer.validateAndCreate(jsonCommand);
ShareAccountTempRepository.getInstance().save(account);
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(account.getId()) //
.build();
} catch (final DataIntegrityViolationException dve) {
handleDataIntegrityIssues(jsonCommand, dve);
return CommandProcessingResult.empty();
}
}
@Override
public CommandProcessingResult updateShareAccount(Long accountId, JsonCommand jsonCommand) {
try {
ShareAccount account = ShareAccountTempRepository.getInstance().findOne(accountId);
if (account == null) {
throw new ShareAccountNotFoundException(accountId) ;
}
Map<String, Object> changes = this.accountDataSerializer.validateAndUpdate(jsonCommand, account);
if (!changes.isEmpty()) {
// Save the data here
}
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(accountId) //
.with(changes) //
.build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(jsonCommand, dve);
return CommandProcessingResult.empty();
}
}
private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
}
}
@@ -0,0 +1,144 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.products.api;
import java.util.Collection;
import java.util.HashSet;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.products.constants.ProductsApiConstants;
import org.mifosplatform.portfolio.products.data.ProductData;
import org.mifosplatform.portfolio.products.service.ProductCommandsService;
import org.mifosplatform.portfolio.products.service.ProductReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/products/{type}")
@Component
@Scope("singleton")
public class ProductsApiResource {
private final ApplicationContext applicationContext ;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<ProductData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<Object> toApiObjectJsonSerializer ;
private final PlatformSecurityContext platformSecurityContext;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public ProductsApiResource(final ApplicationContext applicationContext,
final ApiRequestParameterHelper apiRequestParameterHelper,
final DefaultToApiJsonSerializer<ProductData> toApiJsonSerializer,
final PlatformSecurityContext platformSecurityContext,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final DefaultToApiJsonSerializer<Object> toApiDividendsJsonSerializer) {
this.applicationContext = applicationContext ;
this.apiRequestParameterHelper = apiRequestParameterHelper ;
this.toApiJsonSerializer = toApiJsonSerializer ;
this.platformSecurityContext = platformSecurityContext ;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService ;
this.toApiObjectJsonSerializer = toApiDividendsJsonSerializer ;
}
@GET
@Path("template")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@PathParam("type") final String productType, @Context final UriInfo uriInfo) {
String serviceName = productType+ProductsApiConstants.READPLATFORM_NAME ;
ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName) ;
ProductData data = service.retrieveTemplate() ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
}
@GET
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveProduct(@PathParam("productId") final Long productId, @PathParam("type") final String productType,
@Context final UriInfo uriInfo) {
String serviceName = productType+ProductsApiConstants.READPLATFORM_NAME ;
ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName) ;
ProductData data = service.retrieveOne(productId) ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
}
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllProducts(@PathParam("type") final String productType, @Context final UriInfo uriInfo) {
String serviceName = productType+ProductsApiConstants.READPLATFORM_NAME ;
ProductReadPlatformService service = (ProductReadPlatformService) this.applicationContext.getBean(serviceName) ;
Collection<ProductData> data = service.retrieveAllProducts() ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, data, service.getResponseDataParams());
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createProduct(@PathParam("type") final String productType, final String apiRequestBodyAsJson) {
CommandWrapper commandWrapper = null;
this.platformSecurityContext.authenticatedUser();
commandWrapper = new CommandWrapperBuilder().createProduct(productType).withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult commandProcessingResult = this.commandsSourceWritePlatformService.logCommandSource(commandWrapper);
return this.toApiJsonSerializer.serialize(commandProcessingResult);
}
@POST
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String handleCommands(@PathParam("type") final String productType, @PathParam("productId") final Long productId, @QueryParam("command") final String commandParam,
@Context final UriInfo uriInfo, final String apiRequestBodyAsJson) {
String serviceName = productType.toUpperCase()+ProductsApiConstants.PRODUCT_COMMANDSERVICE ;
ProductCommandsService service = (ProductCommandsService) this.applicationContext.getBean(serviceName) ;
final Object obj = service.handleCommand(productId, commandParam, apiRequestBodyAsJson) ;
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiObjectJsonSerializer.serialize(settings, obj, new HashSet<String>());
}
@PUT
@Path("{productId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateProduct(@PathParam("type") final String productType, @PathParam("productId") final Long productId, final String apiRequestBodyAsJson) {
this.platformSecurityContext.authenticatedUser();
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateProduct(productType, productId)
.withJson(apiRequestBodyAsJson).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
private boolean is(final String commandParam, final String commandValue) {
return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue);
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.products.constants;
public interface ProductsApiConstants {
public final String READPLATFORM_NAME = "ReadPlatformService" ;
public final String PRODUCT_COMMANDSERVICE = "PRODUCT_COMMANDSERVICE" ;
}
@@ -0,0 +1,11 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.products.data;
public interface ProductData {
}
@@ -0,0 +1,18 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.products.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
/**
* A {@link RuntimeException} thrown when loan product resources are not found.
*/
public class ProductNotFoundException extends AbstractPlatformResourceNotFoundException {
public ProductNotFoundException(final Long id, String type) {
super("error.msg.product.id.invalid", type + " product with identifier " + id + " does not exist" , id);
}
}
@@ -0,0 +1,13 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.products.service;
public interface ProductCommandsService {
public Object handleCommand(final Long productId, final String command, final String jsonBody) ;
}
@@ -0,0 +1,22 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.products.service;
import java.util.Collection;
import java.util.Set;
import org.mifosplatform.portfolio.products.data.ProductData;
public interface ProductReadPlatformService {
public Collection<ProductData> retrieveAllProducts();
public ProductData retrieveOne(final Long productId);
public ProductData retrieveTemplate();
public Set<String> getResponseDataParams();
}
@@ -0,0 +1,39 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.constants;
public interface ShareProductApiConstants {
//Command Strings
public final String PREIEW_DIVIDENDS_COMMAND_STRING = "previewdividends" ;
public final String POST_DIVIDENdS_COMMAND_STRING = "postdividends" ;
String id_paramname = "id";
String name_paramname = "name";
String shortname_paramname = "shortName";
String description_paramname = "description";
String externalid_paramname = "externalId";
String totalshares_paramname = "totalShares";
String currency_paramname = "currencyCode";
String digitsafterdecimal_paramname = "digitsAfterDecimal";
String inmultiplesof_paramname = "inMultiplesOf";
String totalsharesissued_paramname = "totalSharesIssued";
String unitprice_paramname = "unitPrice";
String sharecapital_paramname = "shareCapital";
String suspenseaccount_paramname = "suspenseAccount";
String equityaccount_paramname = "equityAccount";
String minimumshares_paramname = "minimumShares";
String nominaltshares_paramname = "nominaltShares";
String maximumshares_paramname = "maximumShares";
String marketprice_paramname = "marketPrice";
String charges_paramname = "charges";
String allowdividendcalculationforinactiveclients_paramname = "allowDividendCalculationForInactiveClients";
String lockperiod_paramname = "lockPeriod";
String minimumactiveperiodfordividends_paramname = "minimumActivePeriodForDividends";
String startdate_paramname = "startDate";
String sharevalue_paramname = "shareValue";
}
@@ -0,0 +1,36 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.data;
import java.math.BigDecimal;
import java.util.Date;
public class DividendsData {
private Long clientId;
private String clientName;
private String shareAccountNo;
private String savingsAccountNo;
private Long numberOfShares;
private BigDecimal dividendAmount;
private Date dividendIssuedDate;
public DividendsData(final Long clientId, final String clientName, final String savingsAccountNo, final Long numberOfShares,
final BigDecimal dividendAmount, final Date dividendIssuedDate) {
this.clientId = clientId;
this.clientName = clientName;
this.savingsAccountNo = savingsAccountNo;
this.numberOfShares = numberOfShares;
this.dividendAmount = dividendAmount;
this.dividendIssuedDate = dividendIssuedDate;
}
}
@@ -0,0 +1,52 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
public class ProductDividendsData {
private Long id ;
private Long productId ;
private String productName ;
private Date dividendsIssuedDate ;
private BigDecimal dividendAmount ;
private CurrencyData currency ;
Collection<DividendsData> dividendsData ;
public ProductDividendsData(final Long productId, final String productName, final Date dividendsIssuedDate,
final BigDecimal dividendAmount, final CurrencyData currency, final Collection<DividendsData> dividendsData) {
this.productId = productId ;
this.productName = productName ;
this.dividendsIssuedDate = dividendsIssuedDate ;
this.dividendAmount = dividendAmount ;
this.dividendsData = dividendsData ;
this.currency = currency ;
}
public void setId(Long id) {
this.id = id ;
}
public Long getId() {
return this.id ;
}
public Long getProductId() {
return productId ;
}
}
@@ -0,0 +1,29 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.data;
import java.math.BigDecimal;
import java.util.Date;
public class ShareMarketPriceData {
private final Date startDate;
private final BigDecimal shareValue;
public ShareMarketPriceData(final Date startDate, final BigDecimal shareValue) {
this.startDate = startDate ;
this.shareValue = shareValue ;
}
public Date getStartDate() {
return this.startDate;
}
public BigDecimal getShareValue() {
return this.shareValue;
}
}
@@ -0,0 +1,147 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.data;
import java.math.BigDecimal;
import java.util.List;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.products.data.ProductData;
public class ShareProductData implements ProductData{
private final Long id;
private final String name;
private final String shortName;
private final String description;
private final String externalId;
private final CurrencyData currency;
private final Long totalShares;
private final Long totalSharesIssued;
private final BigDecimal unitPrice;
private final BigDecimal shareCapital;
private final GLAccountData suspenseAccount;
private final GLAccountData equityAccount;
private final Long minimumShares;
private final Long nominaltShares;
private final Long maximumShares;
private final List<ShareMarketPriceData> marketPrice;
private final List<ChargeData> charges;
private Boolean allowDividendCalculationForInactiveClients;
private final EnumOptionData lockPeriod;
private final EnumOptionData minimumActivePeriodForDividends;
public ShareProductData(final Long id, final String name, final String shortName, final String description, final String externalId,
final CurrencyData currency, final Long totalShares, final Long totalSharesIssued, final BigDecimal unitPrice,
final BigDecimal shareCapital, final GLAccountData suspenseAccount, final GLAccountData equityAccount,
final Long minimumShares, final Long nominaltShares, final Long maximumShares, List<ShareMarketPriceData> marketPrice,
final List<ChargeData> charges, final Boolean allowDividendCalculationForInactiveClients, final EnumOptionData lockPeriod,
final EnumOptionData minimumActivePeriodForDividends) {
this.id = id;
this.name = name;
this.shortName = shortName;
this.description = description;
this.externalId = externalId;
this.currency = currency;
this.totalShares = totalShares;
this.totalSharesIssued = totalSharesIssued;
this.unitPrice = unitPrice;
this.shareCapital = shareCapital;
this.suspenseAccount = suspenseAccount;
this.equityAccount = equityAccount;
this.minimumShares = minimumShares;
this.nominaltShares = nominaltShares;
this.maximumShares = maximumShares;
this.marketPrice = marketPrice;
this.charges = charges;
this.allowDividendCalculationForInactiveClients = allowDividendCalculationForInactiveClients;
this.lockPeriod = lockPeriod;
this.minimumActivePeriodForDividends = minimumActivePeriodForDividends;
}
public Long getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getShortName() {
return this.shortName;
}
public String getDescription() {
return this.description;
}
public String getExternalId() {
return this.externalId;
}
public CurrencyData getCurrency() {
return this.currency;
}
public Long getTotalShares() {
return this.totalShares;
}
public Long getTotalSharesIssued() {
return this.totalSharesIssued;
}
public BigDecimal getUnitPrice() {
return this.unitPrice;
}
public BigDecimal getShareCapital() {
return this.shareCapital;
}
public GLAccountData getSuspenseAccount() {
return this.suspenseAccount;
}
public GLAccountData getEquityAccount() {
return this.equityAccount;
}
public Long getMinimumShares() {
return this.minimumShares;
}
public Long getNominaltShares() {
return this.nominaltShares;
}
public Long getMaximumShares() {
return this.maximumShares;
}
public List<ShareMarketPriceData> getMarketPrice() {
return this.marketPrice;
}
public List<ChargeData> getCharges() {
return this.charges;
}
public Boolean getAllowDividendCalculationForInactiveClients() {
return this.allowDividendCalculationForInactiveClients;
}
public EnumOptionData getLockPeriod() {
return this.lockPeriod;
}
public EnumOptionData getMinimumActivePeriodForDividends() {
return this.minimumActivePeriodForDividends;
}
}
@@ -0,0 +1,52 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.domain;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@Table(name = "m_share_marketprice")
public class ShareMarketPrice extends AbstractPersistable<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "product_id", referencedColumnName = "id", nullable = false)
private ShareProduct product;
@Column(name = "start_date")
@Temporal(TemporalType.DATE)
private Date startDate;
@Column(name = "share_value", nullable = false)
private BigDecimal shareValue ;
public ShareMarketPrice(final Date startDate, final BigDecimal shareValue) {
this.startDate = startDate ;
this.shareValue = shareValue ;
}
public void setShareProduct(final ShareProduct product) {
this.product = product ;
}
public Date getStartDate() {
return this.startDate ;
}
public BigDecimal getPrice() {
return this.shareValue ;
}
}
@@ -0,0 +1,350 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.domain;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.joda.time.DateTime;
import org.mifosplatform.accounting.glaccount.data.GLAccountData;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.shares.data.ShareMarketPriceData;
import org.mifosplatform.portfolio.shares.data.ShareProductData;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@Table(name = "m_shareproducts")
public class ShareProduct extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "name", nullable = false, unique = true)
private String name;
@Column(name = "short_name", nullable = false, unique = true)
private String shortName;
@Column(name = "description")
private String description;
@Column(name = "start_date")
@Temporal(TemporalType.DATE)
private Date startDate;
@Column(name = "end_date")
@Temporal(TemporalType.DATE)
private Date endDate;
@Column(name = "external_id", length = 100, nullable = true, unique = true)
private String externalId;
@Embedded
private MonetaryCurrency currency;
@Column(name = "total_shares", nullable = false)
private Long totalShares;
@Column(name = "total_shares_issued", nullable = false)
private Long totalSharesIssued;
@Column(name = "unit_price", nullable = false)
private BigDecimal unitPrice;
@Column(name = "share_capital", nullable = false)
private BigDecimal shareCapital;
@ManyToOne
@JoinColumn(name = "suspence_account", nullable = false)
private GLAccount suspenseAccount;
@ManyToOne
@JoinColumn(name = "equity_account", nullable = false)
private GLAccount equityAccount;
@Column(name = "minimum_client_shares")
private Long minimumShares;
@Column(name = "default_client_shares", nullable = false)
private Long nominalShares;
@Column(name = "maximum_client_shares")
private Long maximumShares;
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "product", orphanRemoval = true)
Set<ShareMarketPrice> marketPrice = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "m_product_charges", joinColumns = @JoinColumn(name = "product_id"), inverseJoinColumns = @JoinColumn(name = "charge_id"))
private Set<Charge> charges;
@Column(name = "allow_dividends_inactive_clients")
private Boolean allowDividendCalculationForInactiveClients;
@Enumerated(EnumType.ORDINAL)
@Column(name = "lock_period", nullable = true)
private PeriodFrequencyType lockPeriod;
@Enumerated(EnumType.ORDINAL)
@Column(name = "dividend_active_period", nullable = true)
private PeriodFrequencyType minimumActivePeriodForDividends;
protected ShareProduct() {
}
// FIXME Remove this method
public void setTempId(Long id) {
super.setId(id);
}
public ShareProduct(final String name, final String shortName, final String description, final String externalId,
final MonetaryCurrency currency, final Long totalShares, final Long totalSharesIssued, final BigDecimal unitPrice,
final BigDecimal shareCapital, final GLAccount suspenseAccount, final GLAccount equityAccount, final Long minimumShares,
final Long nominalShares, final Long maximumShares, Set<ShareMarketPrice> marketPrice, Set<Charge> charges,
final Boolean allowDividendCalculationForInactiveClients, final PeriodFrequencyType lockPeriod,
final PeriodFrequencyType minimumActivePeriodForDividends,
AppUser createdBy, DateTime createdDate, AppUser lastModifiedBy, DateTime lastModifiedDate) {
this.name = name;
this.shortName = shortName;
this.description = description;
this.externalId = externalId;
this.currency = currency;
this.totalShares = totalShares;
this.totalSharesIssued = totalSharesIssued;
this.unitPrice = unitPrice;
this.shareCapital = shareCapital;
this.suspenseAccount = suspenseAccount;
this.equityAccount = equityAccount;
this.minimumShares = minimumShares;
this.nominalShares = nominalShares;
this.maximumShares = maximumShares;
this.marketPrice = marketPrice;
this.charges = charges;
this.allowDividendCalculationForInactiveClients = allowDividendCalculationForInactiveClients;
this.lockPeriod = lockPeriod;
this.minimumActivePeriodForDividends = minimumActivePeriodForDividends;
setCreatedBy(createdBy) ;
setCreatedDate(createdDate) ;
setLastModifiedBy(lastModifiedBy) ;
setLastModifiedDate(lastModifiedDate) ;
}
public ShareProductData toData() {
GLAccountData suspenseAccount1 = new GLAccountData(suspenseAccount.getId(), suspenseAccount.getName(), suspenseAccount.getGlCode());
GLAccountData equityAccount1 = new GLAccountData(equityAccount.getId(), equityAccount.getName(), equityAccount.getGlCode());
List<ChargeData> chargeData = new ArrayList<>();
for(Charge charge: this.charges) {
chargeData.add(ChargeData.lookup(charge.getId(), charge.getName(), charge.isPenalty())) ;
}
List<ShareMarketPriceData> marketData = new ArrayList<>() ;
for(ShareMarketPrice pri: marketPrice) {
marketData.add(new ShareMarketPriceData(pri.getStartDate(), pri.getPrice())) ;
}
EnumOptionData lock = new EnumOptionData(this.lockPeriod.getValue().longValue(), this.lockPeriod.getCode(),
this.lockPeriod.toString());
EnumOptionData mini = new EnumOptionData(this.minimumActivePeriodForDividends.getValue().longValue(), this.minimumActivePeriodForDividends.getCode(),
this.minimumActivePeriodForDividends.toString());;
CurrencyData curr = new CurrencyData(currency.getCode(), "", currency.getDigitsAfterDecimal(), currency.getCurrencyInMultiplesOf(),
"", "");
return new ShareProductData(getId(), name, shortName, description, externalId, curr, totalShares, totalSharesIssued, unitPrice,
shareCapital, suspenseAccount1, equityAccount1, minimumShares, nominalShares, maximumShares, marketData, chargeData,
allowDividendCalculationForInactiveClients, lock, mini);
}
public boolean setProductName(String productName) {
boolean returnValue = false;
if (!this.name.equals(productName)) {
this.name = productName;
returnValue = true;
}
return returnValue;
}
public String getProductName() {
return this.name ;
}
public boolean setShortName(String shortName) {
boolean returnValue = false;
if (!this.shortName.equals(shortName)) {
this.shortName = shortName;
returnValue = true;
}
return returnValue;
}
public boolean setDescription(String description) {
boolean returnValue = false;
if (!this.description.equals(description)) {
this.description = description;
returnValue = true;
}
return returnValue;
}
public boolean setExternalId(String externalId) {
boolean returnValue = false;
if (!this.externalId.equals(externalId)) {
this.externalId = externalId;
returnValue = true;
}
return returnValue;
}
public boolean setTotalShares(Long totalShares) {
boolean returnValue = false;
if (!this.totalShares.equals(totalShares)) {
this.totalShares = totalShares;
returnValue = true;
}
return returnValue;
}
public Long getTotalShares() {
return this.totalShares ;
}
public boolean setTotalIssuedShares(Long totalSharesIssued) {
boolean returnValue = false;
if (!this.totalSharesIssued.equals(totalSharesIssued)) {
this.totalSharesIssued = totalSharesIssued;
returnValue = true;
}
return returnValue;
}
public boolean setMonetaryCurrency(MonetaryCurrency currency) {
boolean returnValue = false;
if (!this.currency.equals(currency)) {
this.currency = currency;
returnValue = true;
}
return returnValue;
}
public MonetaryCurrency getCurrency() {
return this.currency ;
}
public boolean setUnitPrice(BigDecimal unitPrice) {
boolean returnValue = false;
if (!this.unitPrice.equals(unitPrice)) {
this.unitPrice = unitPrice;
returnValue = true;
}
return returnValue;
}
public boolean setSuspenseAccount(GLAccount suspenseAccount) {
boolean returnValue = false;
if (!this.suspenseAccount.getId().equals(suspenseAccount.getId())) {
this.suspenseAccount = suspenseAccount;
returnValue = true;
}
return returnValue;
}
public boolean setEquityAccount(GLAccount equityAccount) {
boolean returnValue = false;
if (!this.equityAccount.getId().equals(equityAccount.getId())) {
this.equityAccount = equityAccount;
returnValue = true;
}
return returnValue;
}
public boolean setMinimumShares(final Long minimumShares) {
boolean returnValue = false;
if (!this.minimumShares.equals(minimumShares)) {
this.minimumShares = minimumShares;
returnValue = true;
}
return returnValue;
}
public boolean setNominalShares(final Long nominalShares) {
boolean returnValue = false;
if (!this.nominalShares.equals(nominalShares)) {
this.nominalShares = nominalShares;
returnValue = true;
}
return returnValue;
}
public boolean setMaximumShares(final Long maximumShares) {
boolean returnValue = false;
if (!this.maximumShares.equals(maximumShares)) {
this.maximumShares = maximumShares;
returnValue = true;
}
return returnValue;
}
public boolean setMarketPrice(Set<ShareMarketPrice> marketPrice) {
this.marketPrice = marketPrice;
return true;
}
public boolean setCharges(Set<Charge> charges) {
this.charges = charges;
return true;
}
public boolean setAllowDividendCalculationForInactiveClients(Boolean allowDividendCalculationForInactiveClients) {
boolean returnValue = false;
if (!this.allowDividendCalculationForInactiveClients.equals(allowDividendCalculationForInactiveClients)) {
this.allowDividendCalculationForInactiveClients = allowDividendCalculationForInactiveClients;
returnValue = true;
}
return returnValue;
}
public boolean setLockPeriod(final PeriodFrequencyType lockPeriod) {
boolean returnValue = false;
if (!this.lockPeriod.equals(lockPeriod)) {
this.lockPeriod = lockPeriod;
returnValue = true;
}
return returnValue;
}
public boolean setminimumActivePeriodForDividends(final PeriodFrequencyType minimumActivePeriodForDividends) {
boolean returnValue = false;
if (!this.minimumActivePeriodForDividends.equals(minimumActivePeriodForDividends)) {
this.minimumActivePeriodForDividends = minimumActivePeriodForDividends;
returnValue = true;
}
return returnValue;
}
}
@@ -0,0 +1,14 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ShareProductRepository extends JpaRepository<ShareProduct, Long>, JpaSpecificationExecutor<ShareProduct> {
}
@@ -0,0 +1,66 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.mifosplatform.portfolio.accounts.domain.ShareAccount;
import org.mifosplatform.portfolio.shares.data.ProductDividendsData;
public class ShareProductTempRepository {
Map<Long, ShareProduct> cache = new HashMap<>() ;
Map<Long, ArrayList<ShareAccount>> accountsCache = new HashMap<>() ;
Map<Long, ProductDividendsData> dividendsCahe = new HashMap<>() ;
private final static ShareProductTempRepository instance = new ShareProductTempRepository() ;
private ShareProductTempRepository() {
}
public final static ShareProductTempRepository getInstance() {
return instance ;
}
public ShareProduct fineOne(Long productId) {
return this.cache.get(productId) ;
}
public Collection<ShareProduct> findAll() {
return this.cache.values() ;
}
public void save(ShareProduct product) {
Long id = new Long(cache.size() + 1) ;
product.setTempId(id) ;
this.cache.put(id, product) ;
}
public void addAccount(Long productId, ShareAccount account) {
if(accountsCache.containsKey(productId)) {
ArrayList<ShareAccount> list = accountsCache.get(productId) ;
list.add(account) ;
}else {
ArrayList<ShareAccount> list = new ArrayList<>() ;
list.add(account) ;
accountsCache.put(productId, list) ;
}
}
public ArrayList<ShareAccount> getAllAccounts(Long productId) {
return accountsCache.get(productId) ;
}
public void saveDividends(ProductDividendsData data) {
Long id = new Long(dividendsCahe.size()+1) ;
data.setId(id) ;
dividendsCahe.put(data.getProductId(), data) ;
}
}
@@ -0,0 +1,34 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.handler;
import org.mifosplatform.commands.annotation.CommandType;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.shares.service.ShareProductWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "SHAREPRODUCT", action = "CREATE")
public class CreateShareProductCommandHandler implements NewCommandSourceHandler {
private final ShareProductWritePlatformService shareProductWritePlatformService ;
@Autowired
public CreateShareProductCommandHandler(final ShareProductWritePlatformService shareProductWritePlatformService) {
this.shareProductWritePlatformService = shareProductWritePlatformService ;
}
@Transactional
@Override
public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
return this.shareProductWritePlatformService.createShareProduct(jsonCommand);
}
}
@@ -0,0 +1,34 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.handler;
import org.mifosplatform.commands.annotation.CommandType;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.shares.service.ShareProductWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@CommandType(entity = "SHAREPRODUCT", action = "UPDATE")
public class UpdateShareProductCommandHandler implements NewCommandSourceHandler {
private final ShareProductWritePlatformService shareProductWritePlatformService ;
@Autowired
public UpdateShareProductCommandHandler(final ShareProductWritePlatformService shareProductWritePlatformService) {
this.shareProductWritePlatformService = shareProductWritePlatformService ;
}
@Transactional
@Override
public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
return this.shareProductWritePlatformService.updateProduct(jsonCommand.entityId(), jsonCommand);
}
}
@@ -0,0 +1,328 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.serialization;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.mifosplatform.accounting.glaccount.domain.GLAccount;
import org.mifosplatform.accounting.glaccount.domain.GLAccountRepositoryWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper;
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.mifosplatform.portfolio.shares.constants.ShareProductApiConstants;
import org.mifosplatform.portfolio.shares.domain.ShareMarketPrice;
import org.mifosplatform.portfolio.shares.domain.ShareProduct;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
//This class responsibility is to validate data and serialize to entity and return object to the caller
@Service
public class ShareProductDataSerializer {
private final Set<String> supportedParameters = new HashSet<>(Arrays.asList(""));
private final FromJsonHelper fromApiJsonHelper;
private final ChargeRepositoryWrapper chargeRepository;
private final GLAccountRepositoryWrapper glAccountRepository;
private final PlatformSecurityContext platformSecurityContext ;
@Autowired
public ShareProductDataSerializer(final FromJsonHelper fromApiJsonHelper, final ChargeRepositoryWrapper chargeRepository,
final GLAccountRepositoryWrapper glAccountRepository,
final PlatformSecurityContext platformSecurityContext) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.chargeRepository = chargeRepository;
this.glAccountRepository = glAccountRepository;
this.platformSecurityContext = platformSecurityContext ;
}
public ShareProduct validateAndCreate(JsonCommand jsonCommand) {
if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
//this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesproduct");
JsonElement element = jsonCommand.parsedJson();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
final String productName = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.name_paramname, element);
baseDataValidator.reset().parameter(ShareProductApiConstants.name_paramname).value(productName).notBlank()
.notExceedingLengthOf(200);
final String shortName = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.shortname_paramname, element);
baseDataValidator.reset().parameter(ShareProductApiConstants.shortname_paramname).value(shortName).notBlank()
.notExceedingLengthOf(10);
String description = null;
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.description_paramname, element)) {
description = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.description_paramname, element);
}
String externalId = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.externalid_paramname, element);
Long totalNumberOfShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.totalshares_paramname, element);
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.currency_paramname, element);
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
ShareProductApiConstants.digitsafterdecimal_paramname, element);
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
ShareProductApiConstants.inmultiplesof_paramname, element);
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
final Long sharesIssued = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.totalsharesissued_paramname, element);
final BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareProductApiConstants.unitprice_paramname, element,
locale);
final BigDecimal shareCapitalValue = null;
Long suspenseAccountId = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.suspenseaccount_paramname, element);
Long equityAccountId = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.equityaccount_paramname, element);
Long minimumClientShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.minimumshares_paramname, element);
Long nominalClientShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.nominaltshares_paramname, element);
Long maximumClientShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.maximumshares_paramname, element);
Set<ShareMarketPrice> marketPriceSet = asembleShareMarketPrice(element);
Set<Charge> charges = assembleListOfProductCharges(element, currencyCode);
Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed(
ShareProductApiConstants.allowdividendcalculationforinactiveclients_paramname, element);
PeriodFrequencyType lockPeriod = extractPeriodType(ShareProductApiConstants.lockperiod_paramname, element);
PeriodFrequencyType minimumActivePeriod = extractPeriodType(ShareProductApiConstants.minimumactiveperiodfordividends_paramname,
element);
GLAccount suspenseAccount = glAccountRepository.findOneWithNotFoundDetection(suspenseAccountId);
GLAccount equityAccount = glAccountRepository.findOneWithNotFoundDetection(equityAccountId);
AppUser modifiedBy = null;
DateTime modifiedOn = null;
AppUser createdBy = platformSecurityContext.authenticatedUser() ;
DateTime createdDate = DateUtils.getLocalDateTimeOfTenant().toDateTime() ;
ShareProduct product = new ShareProduct(productName, shortName, description, externalId, currency, totalNumberOfShares,
sharesIssued, unitPrice, shareCapitalValue, suspenseAccount, equityAccount, minimumClientShares, nominalClientShares,
maximumClientShares, marketPriceSet, charges, allowdividendsForInactiveClients, lockPeriod, minimumActivePeriod,
createdBy, createdDate, modifiedBy, modifiedOn);
return product;
}
private PeriodFrequencyType extractPeriodType(String paramName, final JsonElement element) {
PeriodFrequencyType frequencyType = PeriodFrequencyType.INVALID;
frequencyType = PeriodFrequencyType.fromInt(this.fromApiJsonHelper.extractIntegerWithLocaleNamed(paramName, element));
return frequencyType;
}
private Set<ShareMarketPrice> asembleShareMarketPrice(final JsonElement element) {
Set<ShareMarketPrice> set = null;
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.marketprice_paramname, element)) {
set = new HashSet<>();
JsonArray array = this.fromApiJsonHelper.extractJsonArrayNamed(ShareProductApiConstants.marketprice_paramname, element);
for (JsonElement arrayElement : array) {
LocalDate localDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareProductApiConstants.startdate_paramname,
arrayElement);
final BigDecimal shareValue = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(
ShareProductApiConstants.sharevalue_paramname, arrayElement);
ShareMarketPrice obj = new ShareMarketPrice(localDate.toDate(), shareValue);
set.add(obj);
}
}
return set;
}
private Set<Charge> assembleListOfProductCharges(final JsonElement element, final String currencyCode) {
final Set<Charge> charges = new HashSet<>();
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.charges_paramname, element)) {
JsonArray chargesArray = this.fromApiJsonHelper.extractJsonArrayNamed(ShareProductApiConstants.charges_paramname, element);
if (chargesArray != null) {
for (int i = 0; i < chargesArray.size(); i++) {
final JsonObject jsonObject = chargesArray.get(i).getAsJsonObject();
if (jsonObject.has("id")) {
final Long id = jsonObject.get("id").getAsLong();
final Charge charge = this.chargeRepository.findOneWithNotFoundDetection(id);
if (!currencyCode.equals(charge.getCurrencyCode())) {
final String errorMessage = "Charge and Loan Product must have the same currency.";
throw new InvalidCurrencyException("charge", "attach.to.loan.product", errorMessage);
}
charges.add(charge);
}
}
}
}
return charges;
}
public Map<String, Object> validateAndUpdate(JsonCommand jsonCommand, ShareProduct product) {
Map<String, Object> actualChanges = new HashMap<>();
if (StringUtils.isBlank(jsonCommand.json())) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
//this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, jsonCommand.json(), supportedParameters);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("sharesproduct");
JsonElement element = jsonCommand.parsedJson();
final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(element.getAsJsonObject());
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.name_paramname, element)) {
final String productName = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.name_paramname, element);
if (product.setProductName(productName)) {
actualChanges.put(ShareProductApiConstants.name_paramname, productName);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.shortname_paramname, element)) {
final String shortName = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.shortname_paramname, element);
if (product.setShortName(shortName)) {
actualChanges.put(ShareProductApiConstants.shortname_paramname, shortName);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.description_paramname, element)) {
String description = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.description_paramname, element);
if (product.setDescription(description)) {
actualChanges.put(ShareProductApiConstants.description_paramname, description);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.externalid_paramname, element)) {
String externalId = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.externalid_paramname, element);
if (product.setExternalId(externalId)) {
actualChanges.put(ShareProductApiConstants.externalid_paramname, externalId);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.totalshares_paramname, element)) {
Long totalShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.totalshares_paramname, element);
if (product.setTotalShares(totalShares)) {
actualChanges.put(ShareProductApiConstants.totalshares_paramname, totalShares);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.totalsharesissued_paramname, element)) {
final Long sharesIssued = this.fromApiJsonHelper
.extractLongNamed(ShareProductApiConstants.totalsharesissued_paramname, element);
if (product.setTotalIssuedShares(sharesIssued)) {
actualChanges.put(ShareProductApiConstants.totalsharesissued_paramname, sharesIssued);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.currency_paramname, element)
&& this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.digitsafterdecimal_paramname, element)
&& this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.inmultiplesof_paramname, element)) {
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.currency_paramname, element);
final Integer digitsAfterDecimal = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
ShareProductApiConstants.digitsafterdecimal_paramname, element);
final Integer inMultiplesOf = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(
ShareProductApiConstants.inmultiplesof_paramname, element);
final MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal, inMultiplesOf);
if (product.setMonetaryCurrency(currency)) {
actualChanges.put(ShareProductApiConstants.currency_paramname, currency);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.unitprice_paramname, element)) {
final BigDecimal unitPrice = this.fromApiJsonHelper.extractBigDecimalNamed(ShareProductApiConstants.unitprice_paramname,
element, locale);
if (product.setUnitPrice(unitPrice)) {
actualChanges.put(ShareProductApiConstants.unitprice_paramname, unitPrice);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.suspenseaccount_paramname, element)) {
Long suspenseAccountId = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.suspenseaccount_paramname, element);
GLAccount suspenseAccount = glAccountRepository.findOneWithNotFoundDetection(suspenseAccountId);
if (product.setSuspenseAccount(suspenseAccount)) {
actualChanges.put(ShareProductApiConstants.suspenseaccount_paramname, suspenseAccount);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.equityaccount_paramname, element)) {
Long equityAccountId = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.equityaccount_paramname, element);
GLAccount equityAccount = glAccountRepository.findOneWithNotFoundDetection(equityAccountId);
if (product.setEquityAccount(equityAccount)) {
actualChanges.put(ShareProductApiConstants.equityaccount_paramname, equityAccount);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.minimumshares_paramname, element)) {
Long minimumClientShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.minimumshares_paramname, element);
if (product.setMinimumShares(minimumClientShares)) {
actualChanges.put(ShareProductApiConstants.minimumshares_paramname, minimumClientShares);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.nominaltshares_paramname, element)) {
Long nominalClientShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.nominaltshares_paramname, element);
if (product.setNominalShares(nominalClientShares)) {
actualChanges.put(ShareProductApiConstants.nominaltshares_paramname, nominalClientShares);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.maximumshares_paramname, element)) {
Long maximumClientShares = this.fromApiJsonHelper.extractLongNamed(ShareProductApiConstants.maximumshares_paramname, element);
if (product.setMaximumShares(maximumClientShares)) {
actualChanges.put(ShareProductApiConstants.maximumshares_paramname, maximumClientShares);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.marketprice_paramname, element)) {
Set<ShareMarketPrice> marketPrice = asembleShareMarketPrice(element);
if (product.setMarketPrice(marketPrice)) {
actualChanges.put(ShareProductApiConstants.marketprice_paramname, marketPrice);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.charges_paramname, element)) {
final String currencyCode = this.fromApiJsonHelper.extractStringNamed(ShareProductApiConstants.currency_paramname, element);
Set<Charge> charges = assembleListOfProductCharges(element, currencyCode);
if (product.setCharges(charges)) {
actualChanges.put(ShareProductApiConstants.charges_paramname, charges);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.allowdividendcalculationforinactiveclients_paramname, element)) {
Boolean allowdividendsForInactiveClients = this.fromApiJsonHelper.extractBooleanNamed(
ShareProductApiConstants.allowdividendcalculationforinactiveclients_paramname, element);
if (product.setAllowDividendCalculationForInactiveClients(allowdividendsForInactiveClients)) {
actualChanges.put(ShareProductApiConstants.allowdividendcalculationforinactiveclients_paramname,
allowdividendsForInactiveClients);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.lockperiod_paramname, element)) {
PeriodFrequencyType lockPeriod = extractPeriodType(ShareProductApiConstants.lockperiod_paramname, element);
if (product.setLockPeriod(lockPeriod)) {
actualChanges.put(ShareProductApiConstants.lockperiod_paramname, lockPeriod);
}
}
if (this.fromApiJsonHelper.parameterExists(ShareProductApiConstants.minimumactiveperiodfordividends_paramname, element)) {
PeriodFrequencyType minimumActivePeriod = extractPeriodType(ShareProductApiConstants.minimumactiveperiodfordividends_paramname,
element);
if (product.setminimumActivePeriodForDividends(minimumActivePeriod)) {
actualChanges.put(ShareProductApiConstants.minimumactiveperiodfordividends_paramname, minimumActivePeriod);
}
}
return actualChanges;
}
}
@@ -0,0 +1,92 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.portfolio.accounts.domain.ShareAccount;
import org.mifosplatform.portfolio.products.service.ProductCommandsService;
import org.mifosplatform.portfolio.shares.constants.ShareProductApiConstants;
import org.mifosplatform.portfolio.shares.data.DividendsData;
import org.mifosplatform.portfolio.shares.data.ProductDividendsData;
import org.mifosplatform.portfolio.shares.domain.ShareProduct;
import org.mifosplatform.portfolio.shares.domain.ShareProductTempRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service(value = "SHAREPRODUCT_COMMANDSERVICE")
public class ShareProductCommandsServiceImpl implements ProductCommandsService {
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public ShareProductCommandsServiceImpl(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public ProductDividendsData previewDividends(Long productId, JsonCommand jsonCommand) {
ArrayList<ShareAccount> accounts = ShareProductTempRepository.getInstance().getAllAccounts(productId);
ShareProduct product = ShareProductTempRepository.getInstance().fineOne(productId);
Long total = product.getTotalShares();
JsonElement element = jsonCommand.parsedJson();
final BigDecimal totalDividendAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("dividendAmount", element);
BigDecimal perShareValue = totalDividendAmount.divide(new BigDecimal(total));
Date date = new Date();
ArrayList<DividendsData> dividends = new ArrayList<>();
for (ShareAccount account : accounts) {
if(account.getStatus().equals("Approved")) {
BigDecimal val = perShareValue.multiply(new BigDecimal(account.getTotalShares()));
DividendsData data = new DividendsData(account.getClientId(), account.getClientName(), account.getSavingsAccountNo(),
account.getTotalShares(), val, date);
dividends.add(data);
}
}
MonetaryCurrency currency = product.getCurrency() ;
CurrencyData cur = new CurrencyData(currency.getCode(), "", currency.getDigitsAfterDecimal(), currency.getCurrencyInMultiplesOf(),
"", "");
ProductDividendsData toReturn = new ProductDividendsData(productId, product.getProductName(), date, totalDividendAmount, cur, dividends);
return toReturn;
}
public CommandProcessingResult postDividends(Long productId, JsonCommand jsonCommand) {
try {
ProductDividendsData data = previewDividends(productId, jsonCommand);
ShareProductTempRepository.getInstance().saveDividends(data);
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(data.getId()) //
.build();
} catch (final DataIntegrityViolationException dve) {
return CommandProcessingResult.empty();
}
}
@Override
public Object handleCommand(Long productId, String command, String jsonBody) {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonBody);
final JsonCommand jsonCommand = JsonCommand.from(jsonBody, parsedCommand, this.fromApiJsonHelper, null, null, null, null, null,
null, null, null, null, null);
if (ShareProductApiConstants.PREIEW_DIVIDENDS_COMMAND_STRING.equals(command)) {
return previewDividends(productId, jsonCommand);
} else if (ShareProductApiConstants.POST_DIVIDENdS_COMMAND_STRING.equals(command)) { return postDividends(productId,
jsonCommand); }
// throw unknow commandexception
return CommandProcessingResult.empty();
}
}
@@ -0,0 +1,51 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.mifosplatform.portfolio.products.data.ProductData;
import org.mifosplatform.portfolio.products.service.ProductReadPlatformService;
import org.mifosplatform.portfolio.shares.domain.ShareProduct;
import org.mifosplatform.portfolio.shares.domain.ShareProductTempRepository;
import org.springframework.stereotype.Service;
@Service(value = "shareReadPlatformService")
public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformService{
ShareProductTempRepository repo = ShareProductTempRepository.getInstance() ;
@Override
public Collection<ProductData> retrieveAllProducts() {
Collection<ShareProduct> entities = repo.findAll() ;
List<ProductData> toReturn = new ArrayList<>() ;
for(ShareProduct entity: entities) {
toReturn.add(entity.toData()) ;
}
return toReturn;
}
@Override
public ProductData retrieveOne(Long productId) {
ShareProduct product = repo.fineOne(productId) ;
return product.toData() ;
}
@Override
public ProductData retrieveTemplate() {
return null;
}
@Override
public Set<String> getResponseDataParams() {
return null;
}
}
@@ -0,0 +1,17 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.service;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
public interface ShareProductWritePlatformService {
CommandProcessingResult createShareProduct(JsonCommand jsonCommand) ;
CommandProcessingResult updateProduct(Long productId, JsonCommand command);
}
@@ -0,0 +1,77 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.shares.service;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.portfolio.products.exception.ProductNotFoundException;
import org.mifosplatform.portfolio.shares.domain.ShareProduct;
import org.mifosplatform.portfolio.shares.domain.ShareProductRepository;
import org.mifosplatform.portfolio.shares.domain.ShareProductTempRepository;
import org.mifosplatform.portfolio.shares.serialization.ShareProductDataSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
@Service
public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareProductWritePlatformService {
private final ShareProductRepository repository;
private final ShareProductDataSerializer serializer;
@Autowired
public ShareProductWritePlatformServiceJpaRepositoryImpl(final ShareProductRepository repository,
final ShareProductDataSerializer serializer) {
this.repository = repository;
this.serializer = serializer;
}
@Override
public CommandProcessingResult createShareProduct(JsonCommand jsonCommand) {
try {
ShareProduct product = this.serializer.validateAndCreate(jsonCommand);
//this.repository.save(product);
ShareProductTempRepository.getInstance().save(product) ;
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(product.getId()) //
.build();
} catch (final DataIntegrityViolationException dve) {
handleDataIntegrityIssues(jsonCommand, dve);
return CommandProcessingResult.empty();
}
}
@Override
public CommandProcessingResult updateProduct(Long productId, JsonCommand jsonCommand) {
try {
//ShareProduct product = this.repository.findOne(productId);
ShareProduct product = ShareProductTempRepository.getInstance().fineOne(productId) ;
if (product == null) { throw new ProductNotFoundException(productId, "share"); }
final Map<String, Object> changes = this.serializer.validateAndUpdate(jsonCommand, product);
if(!changes.isEmpty()) {
//this.repository.saveAndFlush(product) ;
}
return new CommandProcessingResultBuilder() //
.withCommandId(jsonCommand.commandId()) //
.withEntityId(productId) //
.with(changes) //
.build();
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(jsonCommand, dve);
return CommandProcessingResult.empty();
}
}
private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
}
}
@@ -0,0 +1,5 @@
INSERT INTO `m_permission`(`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES
('SHAREPRODUCT', 'CREATE_SHAREPRODUCT', 'SHAREPRODUCT', 'CREATE', 0),
('SHAREPRODUCT', 'UPDATE_SHAREPRODUCT', 'SHAREPRODUCT', 'CREATE', 0),
('SHAREACCOUNT', 'CREATE_SHAREACCOUNT', 'SHAREACCOUNT', 'CREATE', 0),
('SHAREACCOUNT', 'UPDATE_SHAREACCOUNT', 'SHAREACCOUNT', 'CREATE', 0);