remove organisation and anything org_id related

This commit is contained in:
Keith Woodlock
2012-07-14 23:38:51 +01:00
parent 883d1b88ff
commit 8feb9980f3
44 changed files with 497 additions and 937 deletions
@@ -0,0 +1,43 @@
/* remove column org_id */
ALTER TABLE `org_office` DROP FOREIGN KEY `FK2291C47754DF2770`;
ALTER TABLE `org_office` DROP COLUMN `org_id`,
DROP INDEX `name_org`,
ADD UNIQUE INDEX `name_org` (`name` ASC),
DROP INDEX `externalid_org`,
ADD UNIQUE INDEX `externalid_org` (`external_id` ASC),
DROP INDEX `FK2291C47754DF2770`;
ALTER TABLE `org_fund` DROP FOREIGN KEY `FK4E56DB4054DF2770` ;
ALTER TABLE `org_fund` DROP COLUMN `org_id` , DROP INDEX `fund_name_org` , ADD UNIQUE INDEX `fund_name_org` (`name` ASC) , DROP INDEX `fund_externalid_org` , ADD UNIQUE INDEX `fund_externalid_org` (`external_id` ASC) , DROP INDEX `FK4E56DB4054DF2770` ;
ALTER TABLE `org_organisation_currency` DROP FOREIGN KEY `FK308062BB54DF2770` ;ALTER TABLE `org_organisation_currency` DROP COLUMN `org_id` , DROP INDEX `FK308062BB54DF2770` ;
ALTER TABLE `admin_appuser` DROP FOREIGN KEY `FKB3D587C54DF2770` ;ALTER TABLE `admin_appuser` DROP COLUMN `org_id` , DROP INDEX `username_org` , ADD UNIQUE INDEX `username_org` (`username` ASC) , DROP INDEX `FKB3D587C54DF2770` ;
ALTER TABLE `admin_permission` DROP FOREIGN KEY `FK18040BF54DF2770` ;ALTER TABLE `admin_permission` DROP COLUMN `org_id` , DROP INDEX `FK18040BF54DF2770` ;
ALTER TABLE `admin_role` DROP FOREIGN KEY `FK2902EF6654DF2770` ;ALTER TABLE `admin_role` DROP COLUMN `org_id` , DROP INDEX `FK2902EF6654DF2770`;
ALTER TABLE `portfolio_loan` DROP FOREIGN KEY `FKB6F935D854DF2770` ;ALTER TABLE `portfolio_loan` DROP COLUMN `org_id` , DROP INDEX `org_id` , ADD UNIQUE INDEX `org_id` (`external_id` ASC) , DROP INDEX `FKB6F935D854DF2770` ;
ALTER TABLE `portfolio_loan_repayment_schedule` DROP COLUMN `org_id`;
ALTER TABLE `portfolio_loan_transaction` DROP COLUMN `org_id`;
ALTER TABLE `portfolio_note` DROP FOREIGN KEY `FK7C9708954DF2770` ;ALTER TABLE `portfolio_note` DROP COLUMN `org_id` , DROP INDEX `FK7C9708954DF2770`;
ALTER TABLE `portfolio_product_loan` DROP FOREIGN KEY `FK1BD0772854DF2770` ;ALTER TABLE `portfolio_product_loan` DROP COLUMN `org_id` , DROP INDEX `FK1BD0772854DF2770`;
drop table `admin_oauth_consumer_application`;
drop table `org_organisation`;
@@ -6,121 +6,17 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.Note;
import org.mifosng.platform.fund.domain.Fund;
import org.mifosng.platform.loan.domain.Loan; import org.mifosng.platform.loan.domain.Loan;
import org.mifosng.platform.loan.domain.LoanProduct;
import org.mifosng.platform.loan.domain.LoanTransaction;
import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.Role;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
public final class Specifications { public final class Specifications {
public static Specification<AppUser> usersThatMatch(final Organisation organisation, final Long id) { public static Specification<Loan> loansThatMatch(final Client client) {
return new Specification<AppUser>() {
@Override
public Predicate toPredicate(final Root<AppUser> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<AppUser> usersThatMatch(final Organisation organisation, final String username) {
return new Specification<AppUser>() {
@Override
public Predicate toPredicate(final Root<AppUser> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("username"), username));
}
};
}
public static Specification<Role> rolesThatMatch(final Organisation organisation, final Long id) {
return new Specification<Role>() {
@Override
public Predicate toPredicate(final Root<Role> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<LoanTransaction> loanTransactionsThatMatch(final Organisation organisation, final Long id) {
return new Specification<LoanTransaction>() {
@Override
public Predicate toPredicate(final Root<LoanTransaction> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<Loan> loansThatMatch(final Organisation organisation, final Long id) {
return new Specification<Loan>() {
@Override
public Predicate toPredicate(final Root<Loan> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<Loan> loansThatMatch(final Organisation organisation, final Client client) {
return new Specification<Loan>() { return new Specification<Loan>() {
@Override @Override
public Predicate toPredicate(final Root<Loan> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) { public Predicate toPredicate(final Root<Loan> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("client"), client)); return cb.equal(root.get("client"), client);
}
};
}
public static Specification<LoanProduct> productThatMatches(final Organisation organisation, final Long id) {
return new Specification<LoanProduct>() {
@Override
public Predicate toPredicate(final Root<LoanProduct> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<Office> officesThatMatch(final Organisation organisation, final Long id) {
return new Specification<Office>() {
@Override
public Predicate toPredicate(final Root<Office> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<Fund> fundsThatMatch(final Organisation organisation, final Long id) {
return new Specification<Fund>() {
@Override
public Predicate toPredicate(final Root<Fund> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
@Deprecated
public static Specification<Client> clientsThatMatch(final Organisation organisation, final Long id) {
return new Specification<Client>() {
@Override
public Predicate toPredicate(final Root<Client> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
}
};
}
public static Specification<Note> notesThatMatch(final Organisation organisation, final Long id) {
return new Specification<Note>() {
@Override
public Predicate toPredicate(final Root<Note> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.and(cb.equal(root.get("organisation"), organisation), cb.equal(root.get("id"), id));
} }
}; };
} }
@@ -16,9 +16,7 @@ import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService; import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJSONFormattingService;
import org.mifosng.platform.exceptions.UnrecognizedQueryParamException; import org.mifosng.platform.exceptions.UnrecognizedQueryParamException;
import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
import org.mifosng.platform.organisation.service.OfficeWritePlatformService; import org.mifosng.platform.organisation.service.OfficeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@@ -29,22 +27,12 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class OfficeTransactionsApiResource { public class OfficeTransactionsApiResource {
private String defaultFieldList = "openingDate";
private String allowedFieldList = "allowedParents";
private String filterName = "myFilter";
@Autowired
private OfficeReadPlatformService readPlatformService;
@Autowired @Autowired
private OfficeWritePlatformService writePlatformService; private OfficeWritePlatformService writePlatformService;
@Autowired @Autowired
private ApiDataConversionService apiDataConversionService; private ApiDataConversionService apiDataConversionService;
@Autowired
private ApiJSONFormattingService jsonFormattingService;
@POST @POST
@Consumes({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
@@ -11,7 +11,6 @@ import org.codehaus.jackson.map.annotate.JsonFilter;
public class AppUserData { public class AppUserData {
private Long id; private Long id;
private Long orgId;
private Long officeId; private Long officeId;
private String officeName; private String officeName;
private String username; private String username;
@@ -29,12 +28,11 @@ public class AppUserData {
} }
public AppUserData(final Long id, final String username, public AppUserData(final Long id, final String username,
final String email, final Long orgId, final Long officeId, final String email, final Long officeId,
final String officeName) { final String officeName) {
this.id = id; this.id = id;
this.username = username; this.username = username;
this.email = email; this.email = email;
this.orgId = orgId;
this.officeId = officeId; this.officeId = officeId;
this.officeName = officeName; this.officeName = officeName;
} }
@@ -51,10 +49,6 @@ public class AppUserData {
return this.email; return this.email;
} }
public Long getOrgId() {
return this.orgId;
}
public Long getOfficeId() { public Long getOfficeId() {
return this.officeId; return this.officeId;
} }
@@ -75,10 +69,6 @@ public class AppUserData {
this.email = email; this.email = email;
} }
public void setOrgId(final Long orgId) {
this.orgId = orgId;
}
public void setOfficeId(final Long officeId) { public void setOfficeId(final Long officeId) {
this.officeId = officeId; this.officeId = officeId;
} }
@@ -10,7 +10,6 @@ import org.codehaus.jackson.map.annotate.JsonFilter;
public class PermissionData implements Serializable { public class PermissionData implements Serializable {
private Long id; private Long id;
private Long orgId;
private String name; private String name;
private String description; private String description;
private String code; private String code;
@@ -20,10 +19,8 @@ public class PermissionData implements Serializable {
// //
} }
public PermissionData(final Long id, final Long orgId, final String name, public PermissionData(final Long id, final String name, final String description, final String code, int groupType) {
final String description, final String code, int groupType) {
this.id = id; this.id = id;
this.orgId = orgId;
this.name = name; this.name = name;
this.description = description; this.description = description;
this.code = code; this.code = code;
@@ -45,10 +42,6 @@ public class PermissionData implements Serializable {
return this.id; return this.id;
} }
public Long getOrgId() {
return this.orgId;
}
public String getName() { public String getName() {
return this.name; return this.name;
} }
@@ -65,10 +58,6 @@ public class PermissionData implements Serializable {
this.id = id; this.id = id;
} }
public void setOrgId(final Long orgId) {
this.orgId = orgId;
}
public void setName(final String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
@@ -11,7 +11,6 @@ import org.codehaus.jackson.map.annotate.JsonFilter;
public class RoleData { public class RoleData {
private Long id; private Long id;
private Long orgId;
private String name; private String name;
private String description; private String description;
@@ -22,10 +21,8 @@ public class RoleData {
// //
} }
public RoleData(final Long id, final Long orgId, final String name, public RoleData(final Long id, final String name, final String description) {
final String description) {
this.id = id; this.id = id;
this.orgId = orgId;
this.name = name; this.name = name;
this.description = description; this.description = description;
} }
@@ -45,10 +42,6 @@ public class RoleData {
return this.id; return this.id;
} }
public Long getOrgId() {
return this.orgId;
}
public String getName() { public String getName() {
return this.name; return this.name;
} }
@@ -61,10 +54,6 @@ public class RoleData {
this.id = id; this.id = id;
} }
public void setOrgId(final Long orgId) {
this.orgId = orgId;
}
public void setName(final String name) { public void setName(final String name) {
this.name = name; this.name = name;
} }
@@ -9,18 +9,12 @@ import javax.persistence.Table;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.loan.domain.Loan; import org.mifosng.platform.loan.domain.Loan;
import org.mifosng.platform.loan.domain.LoanTransaction; import org.mifosng.platform.loan.domain.LoanTransaction;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
@Entity @Entity
@Table(name = "portfolio_note") @Table(name = "portfolio_note")
public class Note extends AbstractAuditableCustom<AppUser, Long> { public class Note extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
@ManyToOne @ManyToOne
@JoinColumn(name = "client_id", nullable = false) @JoinColumn(name = "client_id", nullable = false)
private final Client client; private final Client client;
@@ -69,35 +63,32 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
} }
} }
public static Note clientNote(Organisation organisation, Client client, String note) { public static Note clientNote(Client client, String note) {
return new Note(organisation, client, note); return new Note(client, note);
} }
public static Note loanNote(Organisation organisation, Loan loan, String note) { public static Note loanNote(Loan loan, String note) {
return new Note(organisation, loan, note); return new Note(loan, note);
} }
public static Note loanTransactionNote(Organisation organisation, Loan loan, LoanTransaction loanTransaction, String note) { public static Note loanTransactionNote(Loan loan, LoanTransaction loanTransaction, String note) {
return new Note(organisation, loan, loanTransaction, note); return new Note(loan, loanTransaction, note);
} }
private Note(Organisation organisation, Client client, String note) { private Note(Client client, String note) {
this.organisation = organisation;
this.client = client; this.client = client;
this.note = note; this.note = note;
this.noteTypeId = NoteType.CLIENT.getValue(); this.noteTypeId = NoteType.CLIENT.getValue();
} }
private Note(Organisation organisation, Loan loan, String note) { private Note(Loan loan, String note) {
this.organisation = organisation;
this.loan = loan; this.loan = loan;
this.client = loan.getClient(); this.client = loan.getClient();
this.note = note; this.note = note;
this.noteTypeId = NoteType.LOAN.getValue(); this.noteTypeId = NoteType.LOAN.getValue();
} }
private Note(Organisation organisation, Loan loan, LoanTransaction loanTransaction, String note) { private Note(Loan loan, LoanTransaction loanTransaction, String note) {
this.organisation = organisation;
this.loan = loan; this.loan = loan;
this.loanTransaction = loanTransaction; this.loanTransaction = loanTransaction;
this.client = loan.getClient(); this.client = loan.getClient();
@@ -106,7 +97,6 @@ public class Note extends AbstractAuditableCustom<AppUser, Long> {
} }
protected Note() { protected Note() {
this.organisation = null;
this.client = null; this.client = null;
this.loan = null; this.loan = null;
this.loanTransaction = null; this.loanTransaction = null;
@@ -68,16 +68,14 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public Collection<ClientData> retrieveAllIndividualClients( public Collection<ClientData> retrieveAllIndividualClients(
String extraCriteria) { String extraCriteria) {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
List<OfficeData> offices = new ArrayList<OfficeData>( List<OfficeData> offices = new ArrayList<OfficeData>(officeReadPlatformService.retrieveAllOffices());
officeReadPlatformService.retrieveAllOffices());
String officeIdsList = generateOfficeIdInClause(offices); String officeIdsList = generateOfficeIdInClause(offices);
ClientMapper rm = new ClientMapper(offices); ClientMapper rm = new ClientMapper(offices);
String sql = "select " + rm.clientSchema() + " where c.office_id in (" String sql = "select " + rm.clientSchema() + " where c.office_id in (" + officeIdsList + ") ";
+ officeIdsList + ") ";
if (StringUtils.isNotBlank(extraCriteria)) if (StringUtils.isNotBlank(extraCriteria))
sql += " and " + extraCriteria; sql += " and " + extraCriteria;
@@ -91,18 +89,16 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public ClientData retrieveIndividualClient(final Long clientId) { public ClientData retrieveIndividualClient(final Long clientId) {
try { try {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
// TODO - JW include office name in query rather than get the lot // TODO - JW include office name in query rather than get the lot
// for office name // for office name
List<OfficeData> offices = new ArrayList<OfficeData>( List<OfficeData> offices = new ArrayList<OfficeData>(
officeReadPlatformService.retrieveAllOffices()); officeReadPlatformService.retrieveAllOffices());
ClientMapper rm = new ClientMapper(offices); ClientMapper rm = new ClientMapper(offices);
String sql = "select " + rm.clientSchema() String sql = "select " + rm.clientSchema() + " where c.id = ? ";
+ " where c.id = ? ";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {clientId});
clientId });
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
throw new ClientNotFoundException(clientId); throw new ClientNotFoundException(clientId);
} }
@@ -134,7 +130,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
} }
public String clientSchema() { public String clientSchema() {
return "c.office_id as officeId, c.id as id, c.firstname as firstname, c.lastname as lastname, c.external_id as externalId, c.joining_date as joinedDate from portfolio_client c"; return "c.office_id as officeId, c.id as id, c.firstname as firstname, c.lastname as lastname, c.external_id as externalId, " +
"c.joining_date as joinedDate from portfolio_client c";
} }
@Override @Override
@@ -171,11 +168,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
} }
@Override @Override
public ClientLoanAccountSummaryCollectionData retrieveClientAccountDetails( public ClientLoanAccountSummaryCollectionData retrieveClientAccountDetails(final Long clientId) {
final Long clientId) {
try { try {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
List<ClientLoanAccountSummaryData> pendingApprovalLoans = new ArrayList<ClientLoanAccountSummaryData>(); List<ClientLoanAccountSummaryData> pendingApprovalLoans = new ArrayList<ClientLoanAccountSummaryData>();
List<ClientLoanAccountSummaryData> awaitingDisbursalLoans = new ArrayList<ClientLoanAccountSummaryData>(); List<ClientLoanAccountSummaryData> awaitingDisbursalLoans = new ArrayList<ClientLoanAccountSummaryData>();
@@ -185,11 +181,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
ClientLoanAccountSummaryDataMapper rm = new ClientLoanAccountSummaryDataMapper(); ClientLoanAccountSummaryDataMapper rm = new ClientLoanAccountSummaryDataMapper();
String sql = "select " + rm.loanAccountSummarySchema() String sql = "select " + rm.loanAccountSummarySchema()
+ " where l.client_id = ? and l.org_id = ?"; + " where l.client_id = ?";
List<ClientLoanAccountSummaryData> results = this.jdbcTemplate List<ClientLoanAccountSummaryData> results = this.jdbcTemplate.query(sql, rm, new Object[] {clientId});
.query(sql, rm, new Object[] { clientId,
currentUser.getOrganisation().getId() });
if (results != null) { if (results != null) {
for (ClientLoanAccountSummaryData row : results) { for (ClientLoanAccountSummaryData row : results) {
@@ -243,18 +237,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
Long productId = JdbcSupport.getLong(rs, "productId"); Long productId = JdbcSupport.getLong(rs, "productId");
String loanProductName = rs.getString("productName"); String loanProductName = rs.getString("productName");
Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId"); Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId");
// String lifeCycleStatusText = rs.getString("statusName");
//
// LoanStatusMapper statusMapper = new
// LoanStatusMapper(loanStatusId);
//
// boolean pendingApproval = statusMapper.isPendingApproval();
// boolean waitingForDisbursal = statusMapper.isAwaitingDisbursal();
// boolean open = statusMapper.isOpen();
// boolean closed = statusMapper.isClosed();
return new ClientLoanAccountSummaryData(id, externalId, productId, return new ClientLoanAccountSummaryData(id, externalId, productId, loanProductName, loanStatusId);
loanProductName, loanStatusId);
} }
} }
@@ -262,7 +246,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public NoteData retrieveClientNote(Long clientId, Long noteId) { public NoteData retrieveClientNote(Long clientId, Long noteId) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
// FIXME - use join on sql query to fetch user information for note // FIXME - use join on sql query to fetch user information for note
// rather than fetching users? // rather than fetching users?
@@ -272,11 +256,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
NoteMapper noteMapper = new NoteMapper(allUsers); NoteMapper noteMapper = new NoteMapper(allUsers);
String sql = "select " + noteMapper.schema() String sql = "select " + noteMapper.schema()
+ " where n.org_id = ? and n.client_id = ? and n.id = ?"; + " where n.client_id = ? and n.id = ?";
return this.jdbcTemplate.queryForObject(sql, noteMapper, return this.jdbcTemplate.queryForObject(sql, noteMapper, new Object[] {clientId, noteId});
new Object[] { currentUser.getOrganisation().getId(),
clientId, noteId });
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
throw new NoteNotFoundException(clientId); throw new NoteNotFoundException(clientId);
} }
@@ -285,7 +267,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
@Override @Override
public Collection<NoteData> retrieveAllClientNotes(Long clientId) { public Collection<NoteData> retrieveAllClientNotes(Long clientId) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
// FIXME - use join on sql query to fetch user information for note // FIXME - use join on sql query to fetch user information for note
// rather than fetching users? // rather than fetching users?
@@ -296,10 +278,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
String sql = "select " String sql = "select "
+ noteMapper.schema() + noteMapper.schema()
+ " where n.org_id = ? and n.client_id = ? order by n.created_date DESC"; + " where n.client_id = ? order by n.created_date DESC";
return this.jdbcTemplate.query(sql, noteMapper, new Object[] { return this.jdbcTemplate.query(sql, noteMapper, new Object[] {clientId});
currentUser.getOrganisation().getId(), clientId });
} }
private static final class NoteMapper implements RowMapper<NoteData> { private static final class NoteMapper implements RowMapper<NoteData> {
@@ -342,8 +323,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
lastModifiedDate, lastModifiedById, updatedByUsername); lastModifiedDate, lastModifiedById, updatedByUsername);
} }
private String findUserById(Long createdById, private String findUserById(Long createdById, Collection<AppUserData> allUsers) {
Collection<AppUserData> allUsers) {
String username = ""; String username = "";
for (AppUserData appUserData : allUsers) { for (AppUserData appUserData : allUsers) {
if (appUserData.getId().equals(createdById)) { if (appUserData.getId().equals(createdById)) {
@@ -1,8 +1,5 @@
package org.mifosng.platform.client.service; package org.mifosng.platform.client.service;
import static org.mifosng.platform.Specifications.notesThatMatch;
import static org.mifosng.platform.Specifications.officesThatMatch;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.ClientCommand; import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.commands.NoteCommand; import org.mifosng.platform.api.commands.NoteCommand;
@@ -17,7 +14,6 @@ import org.mifosng.platform.exceptions.OfficeNotFoundException;
import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.OfficeRepository; import org.mifosng.platform.organisation.domain.OfficeRepository;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -43,12 +39,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Override @Override
public Long enrollClient(final ClientCommand command) { public Long enrollClient(final ClientCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
ClientCommandValidator validator = new ClientCommandValidator(command); ClientCommandValidator validator = new ClientCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
Office clientOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getOfficeId())); Office clientOffice = this.officeRepository.findOne(command.getOfficeId());
if (clientOffice == null) { if (clientOffice == null) {
throw new OfficeNotFoundException(command.getOfficeId()); throw new OfficeNotFoundException(command.getOfficeId());
} }
@@ -69,9 +65,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public EntityIdentifier updateClientDetails(ClientCommand command) { public EntityIdentifier updateClientDetails(final ClientCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
ClientCommandValidator validator = new ClientCommandValidator(command); ClientCommandValidator validator = new ClientCommandValidator(command);
validator.validateForUpdate(); validator.validateForUpdate();
@@ -79,7 +75,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
Office clientOffice = null; Office clientOffice = null;
Long officeId = command.getOfficeId(); Long officeId = command.getOfficeId();
if (officeId != null) { if (officeId != null) {
clientOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), officeId)); clientOffice = this.officeRepository.findOne(officeId);
if (clientOffice == null) { if (clientOffice == null) {
throw new OfficeNotFoundException(command.getOfficeId()); throw new OfficeNotFoundException(command.getOfficeId());
} }
@@ -106,17 +102,16 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public EntityIdentifier addClientNote(NoteCommand command) { public EntityIdentifier addClientNote(final NoteCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
// Client clientForUpdate = this.clientRepository.findOne(clientsThatMatch(currentUser.getOrganisation(), command.getClientId()));
Client clientForUpdate = this.clientRepository.findOne(command.getClientId()); Client clientForUpdate = this.clientRepository.findOne(command.getClientId());
if (clientForUpdate == null) { if (clientForUpdate == null) {
throw new ClientNotFoundException(command.getClientId()); throw new ClientNotFoundException(command.getClientId());
} }
Note note = Note.clientNote(currentUser.getOrganisation(), clientForUpdate, command.getNote()); Note note = Note.clientNote(clientForUpdate, command.getNote());
this.noteRepository.save(note); this.noteRepository.save(note);
@@ -125,11 +120,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public EntityIdentifier updateNote(NoteCommand command) { public EntityIdentifier updateNote(final NoteCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Note noteForUpdate = this.noteRepository.findOne(notesThatMatch(currentUser.getOrganisation(), command.getId())); Note noteForUpdate = this.noteRepository.findOne(command.getId());
if (noteForUpdate == null || noteForUpdate.isNotAgainstClientWithIdOf(command.getClientId())) { if (noteForUpdate == null || noteForUpdate.isNotAgainstClientWithIdOf(command.getClientId())) {
throw new NoteNotFoundException(command.getId(), command.getClientId(), "client"); throw new NoteNotFoundException(command.getId(), command.getClientId(), "client");
} }
@@ -11,11 +11,8 @@ import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.currency.domain.ApplicationCurrency;
import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository; import org.mifosng.platform.currency.domain.ApplicationCurrencyRepository;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException; import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.organisation.domain.OrganisationCurrency; import org.mifosng.platform.organisation.domain.OrganisationCurrency;
import org.mifosng.platform.organisation.domain.OrganisationRepository;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -24,14 +21,12 @@ import org.springframework.transaction.annotation.Transactional;
public class ConfigurationWritePlatformServiceJpaRepositoryImpl implements ConfigurationWritePlatformService { public class ConfigurationWritePlatformServiceJpaRepositoryImpl implements ConfigurationWritePlatformService {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final OrganisationRepository organisationRepository;
private final ApplicationCurrencyRepository applicationCurrencyRepository; private final ApplicationCurrencyRepository applicationCurrencyRepository;
@Autowired @Autowired
public ConfigurationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final OrganisationRepository organisationRepository, public ConfigurationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final ApplicationCurrencyRepository applicationCurrencyRepository) { final ApplicationCurrencyRepository applicationCurrencyRepository) {
this.context = context; this.context = context;
this.organisationRepository = organisationRepository;
this.applicationCurrencyRepository = applicationCurrencyRepository; this.applicationCurrencyRepository = applicationCurrencyRepository;
} }
@@ -39,7 +34,7 @@ public class ConfigurationWritePlatformServiceJpaRepositoryImpl implements Confi
@Override @Override
public void updateOrganisationCurrencies(final OrganisationCurrencyCommand command) { public void updateOrganisationCurrencies(final OrganisationCurrencyCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("configuration"); DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("configuration");
@@ -69,9 +64,5 @@ public class ConfigurationWritePlatformServiceJpaRepositoryImpl implements Confi
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
} }
Organisation org = currentUser.getOrganisation();
org.setAllowedCurrencies(allowedCurrencies);
this.organisationRepository.save(org);
} }
} }
@@ -8,7 +8,6 @@ import org.mifosng.platform.api.data.CurrencyData;
import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
@@ -29,14 +28,13 @@ public class CurrencyReadPlatformServiceImpl implements CurrencyReadPlatformServ
@Override @Override
public List<CurrencyData> retrieveAllowedCurrencies() { public List<CurrencyData> retrieveAllowedCurrencies() {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
String sql = "select c.code as code, c.name as name, c.decimal_places as decimalPlaces, c.display_symbol as displaySymbol, c.internationalized_name_code as nameCode from org_organisation_currency c where c.org_id = ?"; String sql = "select c.code as code, c.name as name, c.decimal_places as decimalPlaces, c.display_symbol as displaySymbol, c.internationalized_name_code as nameCode from org_organisation_currency c";
RowMapper<CurrencyData> rm = new CurrencyMapper(); RowMapper<CurrencyData> rm = new CurrencyMapper();
return this.jdbcTemplate.query(sql, rm, new Object[] { currentUser return this.jdbcTemplate.query(sql, rm, new Object[] {});
.getOrganisation().getId() });
} }
@Override @Override
@@ -2,43 +2,36 @@ package org.mifosng.platform.fund.domain;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
@Entity @Entity
@Table(name = "org_fund", uniqueConstraints={ @Table(name = "org_fund", uniqueConstraints={
@UniqueConstraint(columnNames = {"org_id", "name"}, name="fund_name_org"), @UniqueConstraint(columnNames = {"name"}, name="fund_name_org"),
@UniqueConstraint(columnNames = {"org_id", "external_id"}, name="fund_externalid_org") @UniqueConstraint(columnNames = {"external_id"}, name="fund_externalid_org")
}) })
public class Fund extends AbstractAuditableCustom<AppUser, Long> { public class Fund extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne @SuppressWarnings("unused")
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
@Column(name = "name") @Column(name = "name")
private String name; private String name;
@SuppressWarnings("unused")
@Column(name = "external_id", length=100) @Column(name = "external_id", length=100)
private String externalId; private String externalId;
public static Fund createNew(final Organisation organisation, final String fundName) { public static Fund createNew(final String fundName) {
return new Fund(organisation, fundName); return new Fund(fundName);
} }
protected Fund() { protected Fund() {
this.organisation = null;
} }
private Fund(final Organisation organisation, final String fundName) { private Fund(final String fundName) {
this.organisation = organisation;
this.name = fundName; this.name = fundName;
} }
@@ -8,7 +8,6 @@ import org.mifosng.platform.api.data.FundData;
import org.mifosng.platform.exceptions.FundNotFoundException; import org.mifosng.platform.exceptions.FundNotFoundException;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@@ -30,7 +29,7 @@ public class FundReadPlatformServiceImpl implements FundReadPlatformService {
private static final class FundMapper implements RowMapper<FundData> { private static final class FundMapper implements RowMapper<FundData> {
public String officeSchema() { public String schema() {
return " f.id as id, f.name as name, f.external_id as externalId from org_fund f "; return " f.id as id, f.name as name, f.external_id as externalId from org_fund f ";
} }
@@ -49,28 +48,26 @@ public class FundReadPlatformServiceImpl implements FundReadPlatformService {
@Override @Override
public Collection<FundData> retrieveAllFunds() { public Collection<FundData> retrieveAllFunds() {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
FundMapper rm = new FundMapper(); FundMapper rm = new FundMapper();
String sql = "select " String sql = "select "
+ rm.officeSchema() + rm.schema()
+ " where f.org_id = ? order by f.name"; + " order by f.name";
return this.jdbcTemplate.query(sql, rm, new Object[] {currentUser.getOrganisation().getId()}); return this.jdbcTemplate.query(sql, rm, new Object[] {});
} }
@Override @Override
public FundData retrieveFund(final Long fundId) { public FundData retrieveFund(final Long fundId) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
FundMapper rm = new FundMapper(); FundMapper rm = new FundMapper();
String sql = "select " + rm.officeSchema() String sql = "select " + rm.schema() + " where f.id = ?";
+ " where f.org_id = ? and f.id = ?";
FundData selectedFund = this.jdbcTemplate.queryForObject(sql, FundData selectedFund = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {fundId});
rm, new Object[] { currentUser.getOrganisation().getId(), fundId});
return selectedFund; return selectedFund;
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
@@ -1,14 +1,11 @@
package org.mifosng.platform.fund.service; package org.mifosng.platform.fund.service;
import static org.mifosng.platform.Specifications.fundsThatMatch;
import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.FundCommand;
import org.mifosng.platform.exceptions.FundNotFoundException; import org.mifosng.platform.exceptions.FundNotFoundException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.fund.domain.Fund; import org.mifosng.platform.fund.domain.Fund;
import org.mifosng.platform.fund.domain.FundRepository; import org.mifosng.platform.fund.domain.FundRepository;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -35,12 +32,12 @@ public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatf
public Long createFund(final FundCommand command) { public Long createFund(final FundCommand command) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
FundCommandValidator validator = new FundCommandValidator(command); FundCommandValidator validator = new FundCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
Fund fund = Fund.createNew(currentUser.getOrganisation(), command.getName()); Fund fund = Fund.createNew(command.getName());
this.fundRepository.saveAndFlush(fund); this.fundRepository.saveAndFlush(fund);
@@ -56,13 +53,13 @@ public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatf
public Long updateFund(final FundCommand command) { public Long updateFund(final FundCommand command) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
FundCommandValidator validator = new FundCommandValidator(command); FundCommandValidator validator = new FundCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
final Long fundId = command.getId(); final Long fundId = command.getId();
Fund fund = this.fundRepository.findOne(fundsThatMatch(currentUser.getOrganisation(), fundId)); Fund fund = this.fundRepository.findOne(fundId);
if (fund == null) { if (fund == null) {
throw new FundNotFoundException(fundId); throw new FundNotFoundException(fundId);
} }
@@ -44,17 +44,12 @@ import org.mifosng.platform.exceptions.InvalidLoanTransactionTypeException;
import org.mifosng.platform.fund.domain.Fund; import org.mifosng.platform.fund.domain.Fund;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.loanproduct.service.LoanEnumerations; import org.mifosng.platform.loanproduct.service.LoanEnumerations;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
@Entity @Entity
@Table(name = "portfolio_loan", uniqueConstraints = @UniqueConstraint(columnNames = {"org_id", "external_id" })) @Table(name = "portfolio_loan", uniqueConstraints = @UniqueConstraint(columnNames = {"external_id" }))
public class Loan extends AbstractAuditableCustom<AppUser, Long> { public class Loan extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
@ManyToOne @ManyToOne
@JoinColumn(name = "client_id", nullable = false) @JoinColumn(name = "client_id", nullable = false)
private final Client client; private final Client client;
@@ -149,24 +144,20 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
@Transient @Transient
private final InterestRebateCalculatorFactory interestRebateCalculatorFactory = new DailyEquivalentInterestRebateCalculatorFactory(); private final InterestRebateCalculatorFactory interestRebateCalculatorFactory = new DailyEquivalentInterestRebateCalculatorFactory();
public static Loan createNew(Organisation organisation, public static Loan createNew(final Fund fund, final LoanProduct loanProduct, final Client client, final LoanProductRelatedDetail loanRepaymentScheduleDetail) {
Fund fund, LoanProduct loanProduct, Client client, return new Loan(client, fund, loanProduct, loanRepaymentScheduleDetail, null);
LoanProductRelatedDetail loanRepaymentScheduleDetail) {
return new Loan(organisation, client, fund, loanProduct, loanRepaymentScheduleDetail, null);
} }
public Loan() { public Loan() {
this.organisation = null;
this.client = null; this.client = null;
this.loanProduct = null; this.loanProduct = null;
this.loanRepaymentScheduleDetail = null; this.loanRepaymentScheduleDetail = null;
} }
public Loan(final Organisation organisation, final Client client, public Loan(final Client client,
Fund fund, final LoanProduct loanProduct, Fund fund, final LoanProduct loanProduct,
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanProductRelatedDetail loanRepaymentScheduleDetail,
final LoanStatus loanStatus) { final LoanStatus loanStatus) {
this.organisation = organisation;
this.client = client; this.client = client;
if (fund != null) { if (fund != null) {
this.fund = fund; this.fund = fund;
@@ -179,10 +170,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
this.interestRebateOwed = BigDecimal.ZERO; this.interestRebateOwed = BigDecimal.ZERO;
} }
public Organisation getOrganisation() {
return this.organisation;
}
public Client getClient() { public Client getClient() {
return this.client; return this.client;
} }
@@ -292,7 +279,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
final List<LoanRepaymentScheduleInstallment> modifiedLoanRepaymentSchedule, LoanLifecycleStateMachine loanLifecycleStateMachine) { final List<LoanRepaymentScheduleInstallment> modifiedLoanRepaymentSchedule, LoanLifecycleStateMachine loanLifecycleStateMachine) {
this.repaymentScheduleInstallments.clear(); this.repaymentScheduleInstallments.clear();
for (LoanRepaymentScheduleInstallment modifiedInstallment : modifiedLoanRepaymentSchedule) { for (LoanRepaymentScheduleInstallment modifiedInstallment : modifiedLoanRepaymentSchedule) {
modifiedInstallment.updateOrgnaisation(this.organisation);
modifiedInstallment.updateLoan(this); modifiedInstallment.updateLoan(this);
this.repaymentScheduleInstallments.add(modifiedInstallment); this.repaymentScheduleInstallments.add(modifiedInstallment);
} }
@@ -309,7 +295,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
LoanTransaction loanTransaction = LoanTransaction.disbursement( LoanTransaction loanTransaction = LoanTransaction.disbursement(
this.loanRepaymentScheduleDetail.getPrincipal(), disbursedOn); this.loanRepaymentScheduleDetail.getPrincipal(), disbursedOn);
loanTransaction.updateLoan(this); loanTransaction.updateLoan(this);
loanTransaction.updateOrganisation(organisation);
this.loanTransactions.add(loanTransaction); this.loanTransactions.add(loanTransaction);
if (disbursedOn.isBefore(getApprovedOnDate())) { if (disbursedOn.isBefore(getApprovedOnDate())) {
@@ -338,7 +323,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
public void waive(LoanTransaction loanTransaction, LoanLifecycleStateMachine loanLifecycleStateMachine) { public void waive(LoanTransaction loanTransaction, LoanLifecycleStateMachine loanLifecycleStateMachine) {
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, this.loanStatus); this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, this.loanStatus);
loanTransaction.updateLoan(this); loanTransaction.updateLoan(this);
loanTransaction.updateOrganisation(organisation);
this.loanTransactions.add(loanTransaction); this.loanTransactions.add(loanTransaction);
LocalDate loanTransactionDate = loanTransaction.getTransactionDate(); LocalDate loanTransactionDate = loanTransaction.getTransactionDate();
@@ -382,7 +366,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
public void makeRepayment(final LoanTransaction loanTransaction, LoanLifecycleStateMachine loanLifecycleStateMachine) { public void makeRepayment(final LoanTransaction loanTransaction, LoanLifecycleStateMachine loanLifecycleStateMachine) {
this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, this.loanStatus); this.loanStatus = loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT, this.loanStatus);
loanTransaction.updateLoan(this); loanTransaction.updateLoan(this);
loanTransaction.updateOrganisation(organisation);
this.loanTransactions.add(loanTransaction); this.loanTransactions.add(loanTransaction);
deriveLoanRepaymentScheduleCompletedData(); deriveLoanRepaymentScheduleCompletedData();
@@ -804,7 +787,6 @@ public class Loan extends AbstractAuditableCustom<AppUser, Long> {
} }
public void addRepaymentScheduleInstallment(final LoanRepaymentScheduleInstallment installment) { public void addRepaymentScheduleInstallment(final LoanRepaymentScheduleInstallment installment) {
installment.updateOrgnaisation(this.organisation);
installment.updateLoan(this); installment.updateLoan(this);
this.repaymentScheduleInstallments.add(installment); this.repaymentScheduleInstallments.add(installment);
} }
@@ -15,7 +15,6 @@ import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.fund.domain.Fund; import org.mifosng.platform.fund.domain.Fund;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
/** /**
@@ -30,10 +29,6 @@ import org.mifosng.platform.user.domain.AppUser;
@Table(name = "portfolio_product_loan") @Table(name = "portfolio_product_loan")
public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> { public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
@ManyToOne @ManyToOne
@JoinColumn(name = "fund_id", nullable = true) @JoinColumn(name = "fund_id", nullable = true)
private Fund fund; private Fund fund;
@@ -48,19 +43,17 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
private final LoanProductRelatedDetail loanProductRelatedDetail; private final LoanProductRelatedDetail loanProductRelatedDetail;
public LoanProduct() { public LoanProduct() {
this.organisation = null;
this.fund = null; this.fund = null;
this.name = null; this.name = null;
this.description = null; this.description = null;
this.loanProductRelatedDetail = null; this.loanProductRelatedDetail = null;
} }
public LoanProduct(final Organisation organisation, Fund fund, final String name, final String description, final MonetaryCurrency currency, final BigDecimal defaultPrincipal, public LoanProduct(final Fund fund, final String name, final String description, final MonetaryCurrency currency, final BigDecimal defaultPrincipal,
final BigDecimal defaultNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType, final BigDecimal defaultAnnualNominalInterestRate, final BigDecimal defaultNominalInterestRatePerPeriod, final PeriodFrequencyType interestPeriodFrequencyType, final BigDecimal defaultAnnualNominalInterestRate,
final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod, final InterestMethod interestMethod, final InterestCalculationPeriodMethod interestCalculationPeriodMethod,
final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments, final AmortizationMethod amortizationMethod, final Integer repayEvery, final PeriodFrequencyType repaymentFrequencyType, final Integer defaultNumberOfInstallments, final AmortizationMethod amortizationMethod,
final BigDecimal inArrearsTolerance) { final BigDecimal inArrearsTolerance) {
this.organisation = organisation;
this.fund = fund; this.fund = fund;
this.name = name.trim(); this.name = name.trim();
if (StringUtils.isNotBlank(description)) { if (StringUtils.isNotBlank(description)) {
@@ -75,10 +68,6 @@ public class LoanProduct extends AbstractAuditableCustom<AppUser, Long> {
repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance); repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, amortizationMethod, inArrearsTolerance);
} }
public Organisation getOrganisation() {
return this.organisation;
}
public MonetaryCurrency getCurrency() { public MonetaryCurrency getCurrency() {
return this.loanProductRelatedDetail.getCurrency(); return this.loanProductRelatedDetail.getCurrency();
} }
@@ -15,18 +15,12 @@ import org.joda.time.LocalDate;
import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
@Entity @Entity
@Table(name = "portfolio_loan_repayment_schedule") @Table(name = "portfolio_loan_repayment_schedule")
public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<AppUser, Long> { public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private Organisation organisation;
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = "loan_id") @JoinColumn(name = "loan_id")
private Loan loan; private Loan loan;
@@ -54,7 +48,6 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<Ap
private final Date dueDate; private final Date dueDate;
protected LoanRepaymentScheduleInstallment() { protected LoanRepaymentScheduleInstallment() {
this.organisation = null;
this.loan = null; this.loan = null;
this.installmentNumber = null; this.installmentNumber = null;
this.dueDate = null; this.dueDate = null;
@@ -109,7 +102,6 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<Ap
} }
remaining = remaining.minus(this.interestCompleted); remaining = remaining.minus(this.interestCompleted);
// pay off principal // pay off principal
if (remaining.isGreaterThanOrEqualTo(principal)) { if (remaining.isGreaterThanOrEqualTo(principal)) {
this.principalCompleted = principal.getAmount(); this.principalCompleted = principal.getAmount();
@@ -144,10 +136,6 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom<Ap
return getPrincipal(currency).plus(getInterest(currency)); return getPrincipal(currency).plus(getInterest(currency));
} }
public void updateOrgnaisation(Organisation organisation) {
this.organisation = organisation;
}
public void updateLoan(final Loan loan) { public void updateLoan(final Loan loan) {
this.loan = loan; this.loan = loan;
} }
@@ -19,7 +19,6 @@ import org.joda.time.LocalDate;
import org.mifosng.platform.currency.domain.MonetaryCurrency; import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money; import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
@@ -31,10 +30,6 @@ import org.springframework.format.annotation.DateTimeFormat;
@Table(name = "portfolio_loan_transaction") @Table(name = "portfolio_loan_transaction")
public class LoanTransaction extends AbstractAuditableCustom<AppUser, Long> { public class LoanTransaction extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private Organisation organisation;
@ManyToOne(optional = false) @ManyToOne(optional = false)
@JoinColumn(name = "loan_id", nullable=false) @JoinColumn(name = "loan_id", nullable=false)
private Loan loan; private Loan loan;
@@ -55,7 +50,6 @@ public class LoanTransaction extends AbstractAuditableCustom<AppUser, Long> {
private LoanTransaction contra; private LoanTransaction contra;
protected LoanTransaction() { protected LoanTransaction() {
this.organisation = null;
this.loan = null; this.loan = null;
this.amount = null; this.amount = null;
this.dateOf = null; this.dateOf = null;
@@ -152,11 +146,6 @@ public class LoanTransaction extends AbstractAuditableCustom<AppUser, Long> {
public void contra() { public void contra() {
this.contra = LoanTransaction.contra(this); this.contra = LoanTransaction.contra(this);
contra.updateLoan(this.loan); contra.updateLoan(this.loan);
contra.updateOrganisation(this.organisation);
}
public void updateOrganisation(Organisation organisation) {
this.organisation = organisation;
} }
public void updateLoan(final Loan loan) { public void updateLoan(final Loan loan) {
@@ -1,7 +1,5 @@
package org.mifosng.platform.loan.service; package org.mifosng.platform.loan.service;
import static org.mifosng.platform.Specifications.productThatMatches;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
@@ -30,7 +28,6 @@ import org.mifosng.platform.loanschedule.domain.DefaultLoanScheduleGeneratorFact
import org.mifosng.platform.loanschedule.domain.LoanScheduleGenerator; import org.mifosng.platform.loanschedule.domain.LoanScheduleGenerator;
import org.mifosng.platform.loanschedule.domain.LoanScheduleGeneratorFactory; import org.mifosng.platform.loanschedule.domain.LoanScheduleGeneratorFactory;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -60,7 +57,7 @@ public class CalculationPlatformServiceImpl implements
@Override @Override
public LoanSchedule calculateLoanSchedule(final CalculateLoanScheduleCommand command) { public LoanSchedule calculateLoanSchedule(final CalculateLoanScheduleCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(command); CalculateLoanScheduleCommandValidator validator = new CalculateLoanScheduleCommandValidator(command);
validator.validate(); validator.validate();
@@ -77,7 +74,7 @@ public class CalculationPlatformServiceImpl implements
final BigDecimal defaultAnnualNominalInterestRate = this.aprCalculator.calculateFrom(interestPeriodFrequencyType, defaultNominalInterestRatePerPeriod); final BigDecimal defaultAnnualNominalInterestRate = this.aprCalculator.calculateFrom(interestPeriodFrequencyType, defaultNominalInterestRatePerPeriod);
LoanProduct loanProduct = this.loanProductRepository.findOne(productThatMatches(currentUser.getOrganisation(), command.getProductId())); LoanProduct loanProduct = this.loanProductRepository.findOne(command.getProductId());
if (loanProduct == null) { if (loanProduct == null) {
throw new LoanProductNotFoundException(command.getProductId()); throw new LoanProductNotFoundException(command.getProductId());
} }
@@ -1,8 +1,5 @@
package org.mifosng.platform.loan.service; package org.mifosng.platform.loan.service;
import static org.mifosng.platform.Specifications.fundsThatMatch;
import static org.mifosng.platform.Specifications.productThatMatches;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
@@ -32,7 +29,6 @@ import org.mifosng.platform.loan.domain.LoanStatus;
import org.mifosng.platform.loan.domain.LoanStatusRepository; import org.mifosng.platform.loan.domain.LoanStatusRepository;
import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.loanschedule.domain.AprCalculator; import org.mifosng.platform.loanschedule.domain.AprCalculator;
import org.mifosng.platform.organisation.domain.Organisation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -55,12 +51,13 @@ public class LoanAssembler {
this.fundRepository = fundRepository; this.fundRepository = fundRepository;
} }
public Loan assembleFrom(SubmitLoanApplicationCommand command, Organisation organisation) { public Loan assembleFrom(SubmitLoanApplicationCommand command) {
LoanProduct loanProduct = this.loanProductRepository.findOne(productThatMatches(organisation, command.getProductId()));
LoanProduct loanProduct = this.loanProductRepository.findOne(command.getProductId());
if (loanProduct == null) { if (loanProduct == null) {
throw new LoanProductNotFoundException(command.getProductId()); throw new LoanProductNotFoundException(command.getProductId());
} }
// Client client = this.clientRepository.findOne(clientsThatMatch(organisation, command.getClientId()));
Client client = this.clientRepository.findOne(command.getClientId()); Client client = this.clientRepository.findOne(command.getClientId());
if (client == null) { if (client == null) {
throw new ClientNotFoundException(command.getClientId()); throw new ClientNotFoundException(command.getClientId());
@@ -89,9 +86,9 @@ public class LoanAssembler {
List<ScheduledLoanInstallment> loanRepaymentSchedule = loanSchedule.getScheduledLoanInstallments(); List<ScheduledLoanInstallment> loanRepaymentSchedule = loanSchedule.getScheduledLoanInstallments();
// associating fund with loan product at creation is optional for now. // associating fund with loan product at creation is optional for now.
Fund fund = findFundByIdIfProvided(organisation, command.getFundId()); Fund fund = findFundByIdIfProvided(command.getFundId());
Loan loan = Loan.createNew(organisation, fund, loanProduct, client, loanRepaymentScheduleDetail); Loan loan = Loan.createNew(fund, loanProduct, client, loanRepaymentScheduleDetail);
loan.setExternalId(command.getExternalId()); loan.setExternalId(command.getExternalId());
for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) { for (ScheduledLoanInstallment scheduledLoanInstallment : loanRepaymentSchedule) {
@@ -117,10 +114,10 @@ public class LoanAssembler {
return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses); return new DefaultLoanLifecycleStateMachine(allowedLoanStatuses);
} }
private Fund findFundByIdIfProvided(final Organisation organisation, final Long fundId) { private Fund findFundByIdIfProvided(final Long fundId) {
Fund fund = null; Fund fund = null;
if (fundId != null) { if (fundId != null) {
fund = this.fundRepository.findOne(fundsThatMatch(organisation, fundId)); fund = this.fundRepository.findOne(fundId);
if (fund == null) { if (fund == null) {
throw new FundNotFoundException(fundId); throw new FundNotFoundException(fundId);
} }
@@ -1,8 +1,5 @@
package org.mifosng.platform.loan.service; package org.mifosng.platform.loan.service;
import static org.mifosng.platform.Specifications.loanTransactionsThatMatch;
import static org.mifosng.platform.Specifications.loansThatMatch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -33,7 +30,6 @@ import org.mifosng.platform.loan.domain.LoanTransactionType;
import org.mifosng.platform.loanproduct.service.LoanEnumerations; import org.mifosng.platform.loanproduct.service.LoanEnumerations;
import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService; import org.mifosng.platform.loanproduct.service.LoanProductReadPlatformService;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -67,13 +63,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
} }
@Override @Override
public LoanAccountData retrieveLoanAccountDetails(Long loanId) { public LoanAccountData retrieveLoanAccountDetails(final Long loanId) {
// TODO - OPTIMISE - prefer jdbc sql approach to return only what we // TODO - OPTIMISE - prefer jdbc sql approach to return only what we
// need of loan information. // need of loan information.
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), loanId)); Loan loan = this.loanRepository.findOne(loanId);
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(loanId); throw new LoanNotFoundException(loanId);
} }
@@ -149,14 +145,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
} }
@Override @Override
public LoanTransactionData retrieveNewLoanRepaymentDetails(Long loanId) { public LoanTransactionData retrieveNewLoanRepaymentDetails(final Long loanId) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
// TODO - OPTIMIZE - write simple sql query to fetch back date of // TODO - OPTIMIZE - write simple sql query to fetch back date of
// possible next transaction date. // possible next transaction date.
Loan loan = this.loanRepository.findOne(loansThatMatch( Loan loan = this.loanRepository.findOne(loanId);
currentUser.getOrganisation(), loanId));
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(loanId); throw new LoanNotFoundException(loanId);
} }
@@ -188,14 +183,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
} }
@Override @Override
public LoanTransactionData retrieveNewLoanWaiverDetails(Long loanId) { public LoanTransactionData retrieveNewLoanWaiverDetails(final Long loanId) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
// TODO - OPTIMIZE - write simple sql query to fetch back date of // TODO - OPTIMIZE - write simple sql query to fetch back date of
// possible next transaction date. // possible next transaction date.
Loan loan = this.loanRepository.findOne(loansThatMatch( Loan loan = this.loanRepository.findOne(loanId);
currentUser.getOrganisation(), loanId));
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(loanId); throw new LoanNotFoundException(loanId);
} }
@@ -225,13 +219,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
} }
@Override @Override
public LoanTransactionData retrieveLoanTransactionDetails(Long loanId, public LoanTransactionData retrieveLoanTransactionDetails(final Long loanId, final Long transactionId) {
Long transactionId) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Loan loan = this.loanRepository.findOne(loansThatMatch( Loan loan = this.loanRepository.findOne(loanId);
currentUser.getOrganisation(), loanId));
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(loanId); throw new LoanNotFoundException(loanId);
} }
@@ -244,9 +236,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
throw new CurrencyNotFoundException(currencyCode); throw new CurrencyNotFoundException(currencyCode);
} }
LoanTransaction transaction = this.loanTransactionRepository LoanTransaction transaction = this.loanTransactionRepository.findOne(transactionId);
.findOne(loanTransactionsThatMatch(
currentUser.getOrganisation(), transactionId));
if (transaction == null) { if (transaction == null) {
throw new LoanTransactionNotFoundException(transactionId); throw new LoanTransactionNotFoundException(transactionId);
} }
@@ -1,7 +1,5 @@
package org.mifosng.platform.loan.service; package org.mifosng.platform.loan.service;
import static org.mifosng.platform.Specifications.loansThatMatch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -89,12 +87,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
throw new NoAuthorizationException("Cannot add backdated loan."); throw new NoAuthorizationException("Cannot add backdated loan.");
} }
Loan loan = loanAssembler.assembleFrom(command, currentUser.getOrganisation()); Loan loan = loanAssembler.assembleFrom(command);
this.loanRepository.save(loan); this.loanRepository.save(loan);
if (StringUtils.isNotBlank(command.getSubmittedOnNote())) { if (StringUtils.isNotBlank(command.getSubmittedOnNote())) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, command.getSubmittedOnNote()); Note note = Note.loanNote(loan, command.getSubmittedOnNote());
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -103,11 +101,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Transactional @Transactional
@Override @Override
public EntityIdentifier deleteLoan(Long loanId) { public EntityIdentifier deleteLoan(final Long loanId) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), loanId)); Loan loan = this.loanRepository.findOne(loanId);
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(loanId); throw new LoanNotFoundException(loanId);
} }
@@ -133,7 +131,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command); LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -148,7 +146,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, noteText); Note note = Note.loanNote(loan, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -159,9 +157,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Override @Override
public EntityIdentifier undoLoanApproval(final UndoStateTransitionCommand command) { public EntityIdentifier undoLoanApproval(final UndoStateTransitionCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -171,7 +169,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, noteText); Note note = Note.loanNote(loan, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -187,7 +185,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command); LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -202,7 +200,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, noteText); Note note = Note.loanNote(loan, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -218,7 +216,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command); LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -233,7 +231,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, noteText); Note note = Note.loanNote(loan, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -249,7 +247,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command); LoanStateTransitionCommandValidator validator = new LoanStateTransitionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -322,7 +320,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanRepository.save(loan); this.loanRepository.save(loan);
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, noteText); Note note = Note.loanNote(loan, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -333,9 +331,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Override @Override
public EntityIdentifier undoLoanDisbursal(final UndoStateTransitionCommand command) { public EntityIdentifier undoLoanDisbursal(final UndoStateTransitionCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -350,7 +348,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanNote(currentUser.getOrganisation(), loan, noteText); Note note = Note.loanNote(loan, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -366,7 +364,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command); LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -387,7 +385,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanTransactionNote(currentUser.getOrganisation(), loan, loanRepayment, noteText); Note note = Note.loanTransactionNote(loan, loanRepayment, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -396,14 +394,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Transactional @Transactional
@Override @Override
public EntityIdentifier adjustLoanTransaction(AdjustLoanTransactionCommand command) { public EntityIdentifier adjustLoanTransaction(final AdjustLoanTransactionCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
AdjustLoanTransactionCommandValidator validator = new AdjustLoanTransactionCommandValidator(command); AdjustLoanTransactionCommandValidator validator = new AdjustLoanTransactionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -432,8 +430,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanTransactionNote(currentUser.getOrganisation(), Note note = Note.loanTransactionNote(loan, newTransactionDetail, noteText);
loan, newTransactionDetail, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -444,12 +441,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Override @Override
public EntityIdentifier waiveLoanAmount(LoanTransactionCommand command) { public EntityIdentifier waiveLoanAmount(LoanTransactionCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command); LoanTransactionCommandValidator validator = new LoanTransactionCommandValidator(command);
validator.validate(); validator.validate();
Loan loan = this.loanRepository.findOne(loansThatMatch(currentUser.getOrganisation(), command.getLoanId())); Loan loan = this.loanRepository.findOne(command.getLoanId());
if (loan == null) { if (loan == null) {
throw new LoanNotFoundException(command.getLoanId()); throw new LoanNotFoundException(command.getLoanId());
} }
@@ -468,7 +465,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
String noteText = command.getNote(); String noteText = command.getNote();
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
Note note = Note.loanTransactionNote(currentUser.getOrganisation(), loan, waiver, noteText); Note note = Note.loanTransactionNote(loan, waiver, noteText);
this.noteRepository.save(note); this.noteRepository.save(note);
} }
@@ -23,7 +23,6 @@ import org.mifosng.platform.loan.domain.InterestCalculationPeriodMethod;
import org.mifosng.platform.loan.domain.InterestMethod; import org.mifosng.platform.loan.domain.InterestMethod;
import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@@ -76,29 +75,25 @@ public class LoanProductReadPlatformServiceImpl implements
@Override @Override
public Collection<LoanProductData> retrieveAllLoanProducts() { public Collection<LoanProductData> retrieveAllLoanProducts() {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
LoanProductMapper rm = new LoanProductMapper(); LoanProductMapper rm = new LoanProductMapper();
String sql = "select " + rm.loanProductSchema() String sql = "select " + rm.loanProductSchema();
+ " where lp.org_id = ?";
return this.jdbcTemplate.query(sql, rm, new Object[] { currentUser return this.jdbcTemplate.query(sql, rm, new Object[] {});
.getOrganisation().getId() });
} }
@Override @Override
public Collection<LoanProductLookup> retrieveAllLoanProductsForLookup() { public Collection<LoanProductLookup> retrieveAllLoanProductsForLookup() {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
LoanProductLookupMapper rm = new LoanProductLookupMapper(); LoanProductLookupMapper rm = new LoanProductLookupMapper();
String sql = "select " + rm.loanProductLookupSchema() String sql = "select " + rm.loanProductLookupSchema();
+ " where lp.org_id = ?";
return this.jdbcTemplate.query(sql, rm, new Object[] { currentUser return this.jdbcTemplate.query(sql, rm, new Object[] {});
.getOrganisation().getId() });
} }
@Override @Override
@@ -1,7 +1,5 @@
package org.mifosng.platform.loanproduct.service; package org.mifosng.platform.loanproduct.service;
import static org.mifosng.platform.Specifications.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.mifosng.platform.api.commands.LoanProductCommand; import org.mifosng.platform.api.commands.LoanProductCommand;
@@ -18,9 +16,7 @@ import org.mifosng.platform.loan.domain.LoanProduct;
import org.mifosng.platform.loan.domain.LoanProductRepository; import org.mifosng.platform.loan.domain.LoanProductRepository;
import org.mifosng.platform.loan.domain.PeriodFrequencyType; import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.loanschedule.domain.AprCalculator; import org.mifosng.platform.loanschedule.domain.AprCalculator;
import org.mifosng.platform.organisation.domain.Organisation;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -46,7 +42,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
@Override @Override
public EntityIdentifier createLoanProduct(final LoanProductCommand command) { public EntityIdentifier createLoanProduct(final LoanProductCommand command) {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
LoanProductCommandValidator validator = new LoanProductCommandValidator(command); LoanProductCommandValidator validator = new LoanProductCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
@@ -68,9 +64,9 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
BigDecimal annualInterestRate = this.aprCalculator.calculateFrom(interestFrequencyType, command.getInterestRatePerPeriodValue()); BigDecimal annualInterestRate = this.aprCalculator.calculateFrom(interestFrequencyType, command.getInterestRatePerPeriodValue());
// associating fund with loan product at creation is optional for now. // associating fund with loan product at creation is optional for now.
Fund fund = findFundByIdIfProvided(currentUser.getOrganisation(), command.getFundId()); Fund fund = findFundByIdIfProvided(command.getFundId());
LoanProduct loanproduct = new LoanProduct(currentUser.getOrganisation(), fund, command.getName(), command.getDescription(), LoanProduct loanproduct = new LoanProduct(fund, command.getName(), command.getDescription(),
currency, command.getPrincipalValue(), currency, command.getPrincipalValue(),
command.getInterestRatePerPeriodValue(), interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod, command.getInterestRatePerPeriodValue(), interestFrequencyType, annualInterestRate, interestMethod, interestCalculationPeriodMethod,
command.getRepaymentEveryValue(), repaymentFrequencyType, command.getNumberOfRepaymentsValue(), command.getRepaymentEveryValue(), repaymentFrequencyType, command.getNumberOfRepaymentsValue(),
@@ -81,10 +77,10 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
return new EntityIdentifier(loanproduct.getId()); return new EntityIdentifier(loanproduct.getId());
} }
private Fund findFundByIdIfProvided(final Organisation organisation, final Long fundId) { private Fund findFundByIdIfProvided(final Long fundId) {
Fund fund = null; Fund fund = null;
if (fundId != null) { if (fundId != null) {
fund = this.fundRepository.findOne(fundsThatMatch(organisation, fundId)); fund = this.fundRepository.findOne(fundId);
if (fund == null) { if (fund == null) {
throw new FundNotFoundException(fundId); throw new FundNotFoundException(fundId);
} }
@@ -96,18 +92,18 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
@Override @Override
public EntityIdentifier updateLoanProduct(LoanProductCommand command) { public EntityIdentifier updateLoanProduct(LoanProductCommand command) {
AppUser currentUser = this.context.authenticatedUser(); this.context.authenticatedUser();
LoanProductCommandValidator validator = new LoanProductCommandValidator(command); LoanProductCommandValidator validator = new LoanProductCommandValidator(command);
validator.validateForUpdate(); validator.validateForUpdate();
LoanProduct product = this.loanProductRepository.findOne(productThatMatches(currentUser.getOrganisation(), command.getId())); LoanProduct product = this.loanProductRepository.findOne(command.getId());
if (product == null) { if (product == null) {
throw new LoanProductNotFoundException(command.getId()); throw new LoanProductNotFoundException(command.getId());
} }
// associating fund with loan product at creation is optional for now. // associating fund with loan product at creation is optional for now.
Fund fund = findFundByIdIfProvided(currentUser.getOrganisation(), command.getFundId()); Fund fund = findFundByIdIfProvided(command.getFundId());
product.update(command, fund); product.update(command, fund);
@@ -25,16 +25,11 @@ import org.mifosng.platform.user.domain.AppUser;
@Entity @Entity
@Table(name = "org_office", uniqueConstraints={ @Table(name = "org_office", uniqueConstraints={
@UniqueConstraint(columnNames = {"org_id", "name"}, name="name_org"), @UniqueConstraint(columnNames = {"name"}, name="name_org"),
@UniqueConstraint(columnNames = {"org_id", "external_id"}, name="externalid_org") @UniqueConstraint(columnNames = {"external_id"}, name="externalid_org")
}) })
public class Office extends AbstractAuditableCustom<AppUser, Long> { public class Office extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
@OneToMany(fetch = FetchType.EAGER) @OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "parent_id") @JoinColumn(name = "parent_id")
private final List<Office> children = new LinkedList<Office>(); private final List<Office> children = new LinkedList<Office>();
@@ -57,24 +52,22 @@ public class Office extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "external_id", length=100) @Column(name = "external_id", length=100)
private String externalId; private String externalId;
public static Office headOffice(final Organisation org, final String name, final LocalDate openingDate, final String externalId) { public static Office headOffice(final String name, final LocalDate openingDate, final String externalId) {
return new Office(org, null, name, openingDate, externalId); return new Office(null, name, openingDate, externalId);
} }
public static Office createNew(Organisation organisation, Office parent, String name, LocalDate openingDate, String externalId) { public static Office createNew(final Office parent, final String name, final LocalDate openingDate, final String externalId) {
return new Office(organisation, parent, name, openingDate, externalId); return new Office(parent, name, openingDate, externalId);
} }
protected Office() { protected Office() {
this.organisation = null;
this.openingDate = null; this.openingDate = null;
this.parent = null; this.parent = null;
this.name = null; this.name = null;
this.externalId = null; this.externalId = null;
} }
public Office(final Organisation organisation, final Office parent, final String name, final LocalDate openingDate, final String externalId) { public Office(final Office parent, final String name, final LocalDate openingDate, final String externalId) {
this.organisation = organisation;
this.parent = parent; this.parent = parent;
this.openingDate = openingDate.toDateMidnight().toDate(); this.openingDate = openingDate.toDateMidnight().toDate();
if (parent != null) { if (parent != null) {
@@ -23,24 +23,30 @@ import org.mifosng.platform.user.domain.AppUser;
@Table(name = "portfolio_office_transaction") @Table(name = "portfolio_office_transaction")
public class OfficeTransaction extends AbstractAuditableCustom<AppUser, Long> { public class OfficeTransaction extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_office_id") @JoinColumn(name = "from_office_id")
private Office from; private Office from;
@SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_office_id") @JoinColumn(name = "to_office_id")
private Office to; private Office to;
@SuppressWarnings("unused")
@Column(name = "transaction_date", nullable = false) @Column(name = "transaction_date", nullable = false)
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date transactionDate; private Date transactionDate;
@SuppressWarnings("unused")
@Embedded @Embedded
private MonetaryCurrency currency; private MonetaryCurrency currency;
@SuppressWarnings("unused")
@Column(name = "transaction_amount", scale = 6, precision = 19, nullable = false) @Column(name = "transaction_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal transactionAmount; private BigDecimal transactionAmount;
@SuppressWarnings("unused")
@Column(name = "description", nullable=true, length=100) @Column(name = "description", nullable=true, length=100)
private String description; private String description;
@@ -1,93 +0,0 @@
package org.mifosng.platform.organisation.domain;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.joda.time.LocalDate;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.user.domain.AppUser;
@Entity
@Table(name = "org_organisation")
public class Organisation extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "name", nullable = false, unique=true, length=100)
private final String name;
@Column(name = "opening_date", nullable = false)
@Temporal(TemporalType.DATE)
private final Date openingDate;
@Column(name = "contact_email", nullable = false, length=100)
private final String contactEmail;
@Column(name = "contact_name", nullable = false, length=100)
private final String contactName;
@OneToMany(mappedBy = "organisation", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<OrganisationCurrency> allowedCurrencies;
protected Organisation() {
this.name = null;
this.openingDate = null;
this.contactEmail = null;
this.contactName = null;
this.allowedCurrencies = null;
}
public Organisation(final String name, final LocalDate openingDate,
final String contactEmail, final String contactName,
final List<OrganisationCurrency> currencies
) {
this.name = name.trim();
this.contactEmail = contactEmail.trim();
this.contactName = contactName.trim();
this.openingDate = openingDate.toDateMidnight().toDate();
this.setAllowedCurrencies(new LinkedHashSet<OrganisationCurrency>(
currencies));
}
public String defaultHeadOfficeName() {
return this.name + " Head Office";
}
public LocalDate openingDate() {
return new LocalDate(this.openingDate);
}
public String getContactEmail() {
return this.contactEmail;
}
public String getContactName() {
return this.contactName;
}
public String getName() {
return this.name;
}
public void addAllowedCurrency(final OrganisationCurrency currency) {
currency.updateOrganisation(this);
this.allowedCurrencies.add(currency);
}
public void setAllowedCurrencies(
final Set<OrganisationCurrency> allowedCurrencies) {
this.allowedCurrencies = allowedCurrencies;
for (OrganisationCurrency currency : allowedCurrencies) {
currency.updateOrganisation(this);
}
}
}
@@ -2,8 +2,6 @@ package org.mifosng.platform.organisation.domain;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
@@ -13,11 +11,6 @@ import org.mifosng.platform.user.domain.AppUser;
@Table(name = "org_organisation_currency") @Table(name = "org_organisation_currency")
public class OrganisationCurrency extends AbstractAuditableCustom<AppUser, Long> { public class OrganisationCurrency extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private Organisation organisation;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Column(name = "code", nullable = false, length=3) @Column(name = "code", nullable = false, length=3)
private final String code; private final String code;
@@ -53,8 +46,4 @@ public class OrganisationCurrency extends AbstractAuditableCustom<AppUser, Long>
this.nameCode = nameCode; this.nameCode = nameCode;
this.displaySymbol = displaySymbol; this.displaySymbol = displaySymbol;
} }
public void updateOrganisation(final Organisation organisation) {
this.organisation = organisation;
}
} }
@@ -1,7 +0,0 @@
package org.mifosng.platform.organisation.domain;
import org.springframework.data.jpa.repository.JpaRepository;
public interface OrganisationRepository extends JpaRepository<Organisation, Long> {
// no added behaviour
}
@@ -91,10 +91,9 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
OfficeMapper rm = new OfficeMapper(); OfficeMapper rm = new OfficeMapper();
String sql = "select " String sql = "select "
+ rm.officeSchema() + rm.officeSchema()
+ "where o.org_id = ? and o.hierarchy like ? order by o.hierarchy"; + "where o.hierarchy like ? order by o.hierarchy";
return this.jdbcTemplate.query(sql, rm, new Object[] { return this.jdbcTemplate.query(sql, rm, new Object[] {hierarchySearchString});
currentUser.getOrganisation().getId(), hierarchySearchString });
} }
@Override @Override
@@ -107,25 +106,21 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
OfficeLookupMapper rm = new OfficeLookupMapper(); OfficeLookupMapper rm = new OfficeLookupMapper();
String sql = "select " String sql = "select "
+ rm.officeLookupSchema() + rm.officeLookupSchema()
+ "where o.org_id = ? and o.hierarchy like ? order by o.hierarchy"; + "where o.hierarchy like ? order by o.hierarchy";
return this.jdbcTemplate.query(sql, rm, new Object[] { return this.jdbcTemplate.query(sql, rm, new Object[] {hierarchySearchString});
currentUser.getOrganisation().getId(), hierarchySearchString });
} }
@Override @Override
public OfficeData retrieveOffice(final Long officeId) { public OfficeData retrieveOffice(final Long officeId) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
OfficeMapper rm = new OfficeMapper(); OfficeMapper rm = new OfficeMapper();
String sql = "select " + rm.officeSchema() String sql = "select " + rm.officeSchema() + " where o.id = ?";
+ " where o.org_id = ? and o.id = ?";
OfficeData selectedOffice = this.jdbcTemplate.queryForObject(sql, OfficeData selectedOffice = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {officeId});
rm, new Object[] { currentUser.getOrganisation().getId(),
officeId });
return selectedOffice; return selectedOffice;
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
@@ -1,7 +1,5 @@
package org.mifosng.platform.organisation.service; package org.mifosng.platform.organisation.service;
import static org.mifosng.platform.Specifications.officesThatMatch;
import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand;
import org.mifosng.platform.api.commands.OfficeCommand; import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.currency.domain.ApplicationCurrency; import org.mifosng.platform.currency.domain.ApplicationCurrency;
@@ -13,9 +11,9 @@ import org.mifosng.platform.exceptions.NoAuthorizationException;
import org.mifosng.platform.exceptions.OfficeNotFoundException; import org.mifosng.platform.exceptions.OfficeNotFoundException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.OfficeRepository;
import org.mifosng.platform.organisation.domain.OfficeTransaction; import org.mifosng.platform.organisation.domain.OfficeTransaction;
import org.mifosng.platform.organisation.domain.OfficeTransactionRepository; import org.mifosng.platform.organisation.domain.OfficeTransactionRepository;
import org.mifosng.platform.organisation.domain.OfficeRepository;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -58,7 +56,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId());
Office office = Office.createNew(currentUser.getOrganisation(), parent, command.getName(), command.getOpeningLocalDate(), command.getExternalId()); Office office = Office.createNew(parent, command.getName(), command.getOpeningLocalDate(), command.getExternalId());
// pre save to generate id for use in office hierarchy // pre save to generate id for use in office hierarchy
this.officeRepository.save(office); this.officeRepository.save(office);
@@ -106,17 +104,17 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
@Override @Override
public Long interBranchMoneyTransfer(final BranchMoneyTransferCommand command) { public Long interBranchMoneyTransfer(final BranchMoneyTransferCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
BranchMoneyTransferCommandValidator validator = new BranchMoneyTransferCommandValidator(command); BranchMoneyTransferCommandValidator validator = new BranchMoneyTransferCommandValidator(command);
validator.validateInterBranchTransfer(); validator.validateInterBranchTransfer();
Office fromOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getFromOfficeId())); Office fromOffice = this.officeRepository.findOne(command.getFromOfficeId());
if (fromOffice == null) { if (fromOffice == null) {
throw new OfficeNotFoundException(command.getFromOfficeId()); throw new OfficeNotFoundException(command.getFromOfficeId());
} }
Office toOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getToOfficeId())); Office toOffice = this.officeRepository.findOne(command.getToOfficeId());
if (toOffice == null) { if (toOffice == null) {
throw new OfficeNotFoundException(command.getToOfficeId()); throw new OfficeNotFoundException(command.getToOfficeId());
} }
@@ -141,13 +139,13 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
@Override @Override
public Long externalBranchMoneyTransfer(BranchMoneyTransferCommand command) { public Long externalBranchMoneyTransfer(BranchMoneyTransferCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
BranchMoneyTransferCommandValidator validator = new BranchMoneyTransferCommandValidator(command); BranchMoneyTransferCommandValidator validator = new BranchMoneyTransferCommandValidator(command);
validator.validateExternalBranchTransfer(); validator.validateExternalBranchTransfer();
Office fromOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getFromOfficeId())); Office fromOffice = this.officeRepository.findOne(command.getFromOfficeId());
Office toOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), command.getToOfficeId())); Office toOffice = this.officeRepository.findOne(command.getToOfficeId());
if (fromOffice == null && toOffice == null) { if (fromOffice == null && toOffice == null) {
throw new OfficeNotFoundException(command.getToOfficeId()); throw new OfficeNotFoundException(command.getToOfficeId());
} }
@@ -189,7 +187,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
*/ */
private Office validateUserPriviledgeOnOfficeAndRetrieve(AppUser currentUser, Long officeId) { private Office validateUserPriviledgeOnOfficeAndRetrieve(AppUser currentUser, Long officeId) {
Office userOffice = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), currentUser.getOffice().getId())); Office userOffice = this.officeRepository.findOne(currentUser.getOffice().getId());
if (userOffice == null) { if (userOffice == null) {
throw new OfficeNotFoundException(currentUser.getOffice().getId()); throw new OfficeNotFoundException(currentUser.getOffice().getId());
} }
@@ -200,7 +198,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
Office officeToReturn = userOffice; Office officeToReturn = userOffice;
if (!userOffice.identifiedBy(officeId)) { if (!userOffice.identifiedBy(officeId)) {
officeToReturn = this.officeRepository.findOne(officesThatMatch(currentUser.getOrganisation(), officeId)); officeToReturn = this.officeRepository.findOne(officeId);
if (officeToReturn == null) { if (officeToReturn == null) {
throw new OfficeNotFoundException(officeId); throw new OfficeNotFoundException(officeId);
} }
@@ -19,13 +19,12 @@ import javax.persistence.UniqueConstraint;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.infrastructure.PlatformUser; import org.mifosng.platform.infrastructure.PlatformUser;
import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.Organisation;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
@Entity @Entity
@Table(name = "admin_appuser", uniqueConstraints=@UniqueConstraint(columnNames = {"org_id", "username"}, name="username_org")) @Table(name = "admin_appuser", uniqueConstraints=@UniqueConstraint(columnNames = {"username"}, name="username_org"))
public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements PlatformUser { public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements PlatformUser {
@Column(name = "email", nullable=false, length=100) @Column(name = "email", nullable=false, length=100)
@@ -58,10 +57,6 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
@Column(name = "firsttime_login_remaining", nullable=false) @Column(name = "firsttime_login_remaining", nullable=false)
private boolean firstTimeLoginRemaining; private boolean firstTimeLoginRemaining;
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
@ManyToOne @ManyToOne
@JoinColumn(name = "office_id") @JoinColumn(name = "office_id")
private Office office; private Office office;
@@ -71,9 +66,9 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
private Set<Role> roles; private Set<Role> roles;
public static AppUser createNew(Organisation organisation, Office office, public static AppUser createNew(final Office office,
Set<Role> allRoles, String username, String email, final Set<Role> allRoles, final String username, final String email,
String firstname, String lastname, String password) { final String firstname, final String lastname, final String password) {
boolean userEnabled = true; boolean userEnabled = true;
boolean userAccountNonExpired = true; boolean userAccountNonExpired = true;
@@ -84,11 +79,10 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION")); authorities.add(new SimpleGrantedAuthority("DUMMY_ROLE_NOT_USED_OR_PERSISTED_TO_AVOID_EXCEPTION"));
User user = new User(username, password, userEnabled, userAccountNonExpired, userCredentialsNonExpired, userAccountNonLocked, authorities); User user = new User(username, password, userEnabled, userAccountNonExpired, userCredentialsNonExpired, userAccountNonLocked, authorities);
return new AppUser(organisation, office, user, allRoles, email, firstname, lastname); return new AppUser(office, user, allRoles, email, firstname, lastname);
} }
protected AppUser() { protected AppUser() {
this.organisation = null;
this.office = null; this.office = null;
this.email = null; this.email = null;
this.username = null; this.username = null;
@@ -101,8 +95,7 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
this.firstTimeLoginRemaining = true; this.firstTimeLoginRemaining = true;
} }
public AppUser(final Organisation organisation, final Office office, final User user, final Set<Role> roles, final String email, final String firstname, final String lastname) { public AppUser(final Office office, final User user, final Set<Role> roles, final String email, final String firstname, final String lastname) {
this.organisation = organisation;
this.office = office; this.office = office;
this.email = email.trim(); this.email = email.trim();
this.username = user.getUsername().trim(); this.username = user.getUsername().trim();
@@ -214,10 +207,6 @@ public class AppUser extends AbstractAuditableCustom<AppUser, Long> implements P
this.setId(id); this.setId(id);
} }
public Organisation getOrganisation() {
return this.organisation;
}
public Office getOffice() { public Office getOffice() {
return this.office; return this.office;
} }
@@ -4,19 +4,12 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.mifosng.platform.infrastructure.EmailDetail; import org.mifosng.platform.infrastructure.EmailDetail;
import org.mifosng.platform.infrastructure.PlatformEmailService; import org.mifosng.platform.infrastructure.PlatformEmailService;
import org.mifosng.platform.infrastructure.PlatformPasswordEncoder; import org.mifosng.platform.infrastructure.PlatformPasswordEncoder;
import org.mifosng.platform.infrastructure.RandomPasswordGenerator; import org.mifosng.platform.infrastructure.RandomPasswordGenerator;
import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.Organisation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -38,29 +31,19 @@ public class JpaUserDomainService implements UserDomainService {
@Autowired @Autowired
private PlatformEmailService emailService; private PlatformEmailService emailService;
public static Specification<Role> thatMatch(final Organisation organisation) {
return new Specification<Role>() {
@Override
public Predicate toPredicate(final Root<Role> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
return cb.equal(root.get("organisation"), organisation);
}
};
}
@Transactional @Transactional
@Override @Override
public void createDefaultAdminUser(final Organisation organisation, final Office office) { public void createDefaultAdminUser(final Office office) {
this.userPriviledgeDomainService.createAllOrganisationRolesAndPermissions(organisation); this.userPriviledgeDomainService.createAllOrganisationRolesAndPermissions();
List<Role> organisationalRoles = this.roleRepository.findAll(thatMatch(organisation)); List<Role> organisationalRoles = this.roleRepository.findAll();
Set<Role> allRoles = new HashSet<Role>(organisationalRoles); Set<Role> allRoles = new HashSet<Role>(organisationalRoles);
String username = "admin" + organisation.getId(); String username = "admin";
String password = ""; String password = "";
AppUser defaultAdministrator = AppUser.createNew(organisation, office, allRoles, username, organisation.getContactEmail(), "Organisation", "Administrator", password); AppUser defaultAdministrator = AppUser.createNew(office, allRoles, username, "email?", "Organisation", "Administrator", password);
this.create(defaultAdministrator); this.create(defaultAdministrator);
} }
@@ -81,7 +64,7 @@ public class JpaUserDomainService implements UserDomainService {
this.userRepository.save(appUser); this.userRepository.save(appUser);
EmailDetail emailDetail = new EmailDetail(appUser.getOrganisation().getName(), appUser.getOrganisation().getContactName(), appUser.getEmail(), appUser.getUsername()); EmailDetail emailDetail = new EmailDetail(appUser.getFirstname(), appUser.getFirstname(), appUser.getEmail(), appUser.getUsername());
this.emailService.sendToUserAccount(emailDetail, unencodedPassword); this.emailService.sendToUserAccount(emailDetail, unencodedPassword);
} }
@@ -2,7 +2,6 @@ package org.mifosng.platform.user.domain;
import java.util.Arrays; import java.util.Arrays;
import org.mifosng.platform.organisation.domain.Organisation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -18,48 +17,48 @@ public class JpaUserPriviledgeDomainService implements UserPriviledgeDomainServi
@Transactional @Transactional
@Override @Override
public void createAllOrganisationRolesAndPermissions(final Organisation organisation) { public void createAllOrganisationRolesAndPermissions() {
// 2. create out of the box application permissions and roles // 2. create out of the box application permissions and roles
Permission viewUsersAndRolesPermission = new PermissionBuilder().viewUsersAndRoles().with(organisation).build(); Permission viewUsersAndRolesPermission = new PermissionBuilder().viewUsersAndRoles().build();
Permission createUserPermission = new PermissionBuilder().userCreation().with(organisation).build(); Permission createUserPermission = new PermissionBuilder().userCreation().build();
Permission createRolePermission = new PermissionBuilder().roleCreation().with(organisation).build(); Permission createRolePermission = new PermissionBuilder().roleCreation().build();
Permission updateApplicationPermissionsPermission = new PermissionBuilder().updateApplicationPermissions().with(organisation).build(); Permission updateApplicationPermissionsPermission = new PermissionBuilder().updateApplicationPermissions().build();
Permission[] userAdminPermissions = new Permission[] {viewUsersAndRolesPermission, createUserPermission, Permission[] userAdminPermissions = new Permission[] {viewUsersAndRolesPermission, createUserPermission,
createRolePermission, updateApplicationPermissionsPermission}; createRolePermission, updateApplicationPermissionsPermission};
Permission viewOrganisationOfficesStaffAndProductsPermission = new PermissionBuilder().viewOrganisationsOfficesStaffAndProducts().with(organisation).build(); Permission viewOrganisationOfficesStaffAndProductsPermission = new PermissionBuilder().viewOrganisationsOfficesStaffAndProducts().build();
Permission addOfficePermission = new PermissionBuilder().addOffice().with(organisation).build(); Permission addOfficePermission = new PermissionBuilder().addOffice().build();
Permission addStaffPermission = new PermissionBuilder().addStaff().with(organisation).build(); Permission addStaffPermission = new PermissionBuilder().addStaff().build();
Permission addLoanProductPermission = new PermissionBuilder().addLoanProduct().with(organisation).build(); Permission addLoanProductPermission = new PermissionBuilder().addLoanProduct().build();
Permission[] organisationAdminPermissions = new Permission[] {viewOrganisationOfficesStaffAndProductsPermission, addOfficePermission Permission[] organisationAdminPermissions = new Permission[] {viewOrganisationOfficesStaffAndProductsPermission, addOfficePermission
,addStaffPermission, addLoanProductPermission}; ,addStaffPermission, addLoanProductPermission};
Permission viewLoanPortfolioPermission = new PermissionBuilder().viewLoanPortfolio().with(organisation).build(); Permission viewLoanPortfolioPermission = new PermissionBuilder().viewLoanPortfolio().build();
Permission addLoanPermission = new PermissionBuilder().addLoan().with(organisation).build(); Permission addLoanPermission = new PermissionBuilder().addLoan().build();
Permission addBackdatedLoanPermission = new PermissionBuilder().addBackdatedLoan().with(organisation).build(); Permission addBackdatedLoanPermission = new PermissionBuilder().addBackdatedLoan().build();
Permission approveLoanPermission = new PermissionBuilder().approveLoan().with(organisation).build(); Permission approveLoanPermission = new PermissionBuilder().approveLoan().build();
Permission approveLoanWithPastDatePermission = new PermissionBuilder().approveLoanInThePast().with(organisation).build(); Permission approveLoanWithPastDatePermission = new PermissionBuilder().approveLoanInThePast().build();
Permission rejectLoanPermission = new PermissionBuilder().rejectLoan().with(organisation).build(); Permission rejectLoanPermission = new PermissionBuilder().rejectLoan().build();
Permission rejectLoanWithPastDatePermission = new PermissionBuilder().rejectLoanInThePast().with(organisation).build(); Permission rejectLoanWithPastDatePermission = new PermissionBuilder().rejectLoanInThePast().build();
Permission withdrawLoanPermission = new PermissionBuilder().withdrawLoan().with(organisation).build(); Permission withdrawLoanPermission = new PermissionBuilder().withdrawLoan().build();
Permission withdrawLoanWithPastDatePermission = new PermissionBuilder().withdrawLoanInThePast().with(organisation).build(); Permission withdrawLoanWithPastDatePermission = new PermissionBuilder().withdrawLoanInThePast().build();
Permission undoLoanApprovalPermission = new PermissionBuilder().undoLoanApproval().with(organisation).build(); Permission undoLoanApprovalPermission = new PermissionBuilder().undoLoanApproval().build();
Permission disburseLoanPermission = new PermissionBuilder().disburseLoan().with(organisation).build(); Permission disburseLoanPermission = new PermissionBuilder().disburseLoan().build();
Permission disburseLoanWithPastDatePermission = new PermissionBuilder().disburseLoanInThePast().with(organisation).build(); Permission disburseLoanWithPastDatePermission = new PermissionBuilder().disburseLoanInThePast().build();
Permission undoLoanDisbursalPermission = new PermissionBuilder().undoLoanDisbursal().with(organisation).build(); Permission undoLoanDisbursalPermission = new PermissionBuilder().undoLoanDisbursal().build();
Permission makeLoanRepaymentPermission = new PermissionBuilder().makeLoanRepayment().with(organisation).build(); Permission makeLoanRepaymentPermission = new PermissionBuilder().makeLoanRepayment().build();
Permission makeLoanRepaymentWithPastDatePermission = new PermissionBuilder().makeLoanRepaymentInThePast().with(organisation).build(); Permission makeLoanRepaymentWithPastDatePermission = new PermissionBuilder().makeLoanRepaymentInThePast().build();
// Permission writeoffLoanPermission = new PermissionBuilder().writeoffLoan().with(organisation).build(); // Permission writeoffLoanPermission = new PermissionBuilder().writeoffLoan().build();
// Permission writeoffLoanWithPastDatePermission = new PermissionBuilder().writeoffLoanInThePast().with(organisation).build(); // Permission writeoffLoanWithPastDatePermission = new PermissionBuilder().writeoffLoanInThePast().build();
// Permission rescheduleLoanPermission = new PermissionBuilder().rescheduleLoan().with(organisation).build(); // Permission rescheduleLoanPermission = new PermissionBuilder().rescheduleLoan().build();
// Permission rescheduleLoanWithPastDatePermission = new PermissionBuilder().rescheduleInThePast().with(organisation).build(); // Permission rescheduleLoanWithPastDatePermission = new PermissionBuilder().rescheduleInThePast().build();
// MIFOS-2878 - support recovery of payments for written off loans. // MIFOS-2878 - support recovery of payments for written off loans.
@@ -89,7 +88,7 @@ public class JpaUserPriviledgeDomainService implements UserPriviledgeDomainServi
}; };
Permission dataMigrationPermission = new PermissionBuilder() Permission dataMigrationPermission = new PermissionBuilder()
.dataMigration().with(organisation).build(); .dataMigration().build();
Permission[] migrationPermissions = new Permission[] { dataMigrationPermission }; Permission[] migrationPermissions = new Permission[] { dataMigrationPermission };
@@ -101,13 +100,13 @@ public class JpaUserPriviledgeDomainService implements UserPriviledgeDomainServi
// 2. roles // 2. roles
String userAdminRoleDescription = "A user administrator can create new roles, assign and update roles assigned to users and create and deactivate users."; String userAdminRoleDescription = "A user administrator can create new roles, assign and update roles assigned to users and create and deactivate users.";
Role userAdminRole = new Role(organisation, "User Administrator", userAdminRoleDescription, Arrays.asList(userAdminPermissions)); Role userAdminRole = new Role("User Administrator", userAdminRoleDescription, Arrays.asList(userAdminPermissions));
String organisationAdminRoleDescription = "A organisation administrator can view, create and update organisation office hierarchy, staff and products."; String organisationAdminRoleDescription = "A organisation administrator can view, create and update organisation office hierarchy, staff and products.";
Role organisatonAdminRole = new Role(organisation, "Organisation Administrator", organisationAdminRoleDescription, Arrays.asList(organisationAdminPermissions)); Role organisatonAdminRole = new Role("Organisation Administrator", organisationAdminRoleDescription, Arrays.asList(organisationAdminPermissions));
String fullLoanPortfolioRoleDescription = "A loan portfolio user can view, create and update client, group and loan information."; String fullLoanPortfolioRoleDescription = "A loan portfolio user can view, create and update client, group and loan information.";
Role loanPortfolioFullRole = new Role(organisation, "Full Loan Portfolio", fullLoanPortfolioRoleDescription, Arrays.asList(fullLoanPortfolioPermissions)); Role loanPortfolioFullRole = new Role("Full Loan Portfolio", fullLoanPortfolioRoleDescription, Arrays.asList(fullLoanPortfolioPermissions));
this.roleRepository.save(Arrays.asList(userAdminRole, organisatonAdminRole, loanPortfolioFullRole)); this.roleRepository.save(Arrays.asList(userAdminRole, organisatonAdminRole, loanPortfolioFullRole));
} }
@@ -4,12 +4,9 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType; import javax.persistence.EnumType;
import javax.persistence.Enumerated; import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.mifosng.platform.api.data.PermissionData; import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.organisation.domain.Organisation;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity @Entity
@@ -29,21 +26,14 @@ public class Permission extends AbstractPersistable<Long> {
@Enumerated(EnumType.ORDINAL) @Enumerated(EnumType.ORDINAL)
private final PermissionGroup permissionGroup; private final PermissionGroup permissionGroup;
@ManyToOne
@JoinColumn(name = "org_id", nullable = false)
private final Organisation organisation;
public Permission() { public Permission() {
this.code = null; this.code = null;
this.defaultDescription = null; this.defaultDescription = null;
this.organisation = null;
this.defaultName = null; this.defaultName = null;
this.permissionGroup = null; this.permissionGroup = null;
} }
public Permission(final Organisation organisation, final String code, final String defaultDescription, final String defaultName, public Permission(final String code, final String defaultDescription, final String defaultName, final PermissionGroup permissionGroup) {
final PermissionGroup permissionGroup) {
this.organisation = organisation;
this.code = code; this.code = code;
this.defaultDescription = defaultDescription; this.defaultDescription = defaultDescription;
this.permissionGroup = permissionGroup; this.permissionGroup = permissionGroup;
@@ -59,6 +49,6 @@ public class Permission extends AbstractPersistable<Long> {
} }
public PermissionData toData() { public PermissionData toData() {
return new PermissionData(this.getId(), this.organisation.getId(), this.defaultName, this.defaultDescription, this.code, this.permissionGroup.ordinal()); return new PermissionData(this.getId(), this.defaultName, this.defaultDescription, this.code, this.permissionGroup.ordinal());
} }
} }
@@ -1,245 +1,238 @@
package org.mifosng.platform.user.domain; package org.mifosng.platform.user.domain;
import org.mifosng.platform.organisation.domain.Organisation;
public class PermissionBuilder { public class PermissionBuilder {
private Organisation organisation; private String code;
private String code; private String name;
private String name; private String description;
private String description; private PermissionGroup permissionGroup;
private PermissionGroup permissionGroup;
public Permission build() { public Permission build() {
return new Permission(this.organisation, this.code, this.description, this.name, this.permissionGroup); return new Permission(this.code, this.description, this.name,
} this.permissionGroup);
}
public PermissionBuilder with(final Organisation withOrg) { public PermissionBuilder userCreation() {
this.organisation = withOrg; this.code = "CAN_CREATE_APPLICATION_USER_ROLE";
return this; this.name = "User Creation";
} this.description = "Allows an application user to create other users for the application.";
this.permissionGroup = PermissionGroup.USER_ADMINISTRATION;
return this;
}
public PermissionBuilder userCreation() { public PermissionBuilder roleCreation() {
this.code = "CAN_CREATE_APPLICATION_USER_ROLE"; this.code = "CAN_CREATE_APPLICATION_ROLE_ROLE";
this.name = "User Creation"; this.name = "Role Creation";
this.description = "Allows an application user to create other users for the application."; this.description = "Allows an application user to create other application roles for assigning to users.";
this.permissionGroup = PermissionGroup.USER_ADMINISTRATION; this.permissionGroup = PermissionGroup.USER_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder roleCreation() { public PermissionBuilder viewUsersAndRoles() {
this.code = "CAN_CREATE_APPLICATION_ROLE_ROLE"; this.code = "CAN_VIEW_USERS_AND_ROLES_ROLE";
this.name = "Role Creation"; this.name = "View users and roles";
this.description = "Allows an application user to create other application roles for assigning to users."; this.description = "Allows an application user to view other application users and roles in their organisation.";
this.permissionGroup = PermissionGroup.USER_ADMINISTRATION; this.permissionGroup = PermissionGroup.USER_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder viewUsersAndRoles() { public PermissionBuilder updateApplicationPermissions() {
this.code = "CAN_VIEW_USERS_AND_ROLES_ROLE"; this.code = "CAN_UPDATE_APPLICATION_PERMISSION_NAMES_AND_DESCRIPTIONS_ROLE";
this.name = "View users and roles"; this.name = "Update name and descriptions of application permissions";
this.description = "Allows an application user to view other application users and roles in their organisation."; this.description = "Allows an application user to update the names and description of application permissions for their organisation.";
this.permissionGroup = PermissionGroup.USER_ADMINISTRATION; this.permissionGroup = PermissionGroup.USER_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder updateApplicationPermissions() { public PermissionBuilder viewOrganisationsOfficesStaffAndProducts() {
this.code = "CAN_UPDATE_APPLICATION_PERMISSION_NAMES_AND_DESCRIPTIONS_ROLE"; this.code = "CAN_VIEW_ORGANISATION_WIDE_VIEW_OF_OFFICES_STAFF_AND_PRODUCTS_ROLE";
this.name = "Update name and descriptions of application permissions"; this.name = "View organisations offices, staff and products";
this.description = "Allows an application user to update the names and description of application permissions for their organisation."; this.description = "Allows an application user to view all offices, staff and products for their organisation.";
this.permissionGroup = PermissionGroup.USER_ADMINISTRATION; this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder viewOrganisationsOfficesStaffAndProducts() { public PermissionBuilder addOffice() {
this.code = "CAN_VIEW_ORGANISATION_WIDE_VIEW_OF_OFFICES_STAFF_AND_PRODUCTS_ROLE"; this.code = "CAN_ADD_OFFICE_ROLE";
this.name = "View organisations offices, staff and products"; this.name = "Add offices";
this.description = "Allows an application user to view all offices, staff and products for their organisation."; this.description = "Allows an application user add new offices for their organisation.";
this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION; this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder addOffice() { public PermissionBuilder addStaff() {
this.code = "CAN_ADD_OFFICE_ROLE"; this.code = "CAN_ADD_STAFF_ROLE";
this.name = "Add offices"; this.name = "Add staff";
this.description = "Allows an application user add new offices for their organisation."; this.description = "Allows an application user add new staff members for their organisation.";
this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION; this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder addStaff() { public PermissionBuilder addLoanProduct() {
this.code = "CAN_ADD_STAFF_ROLE"; this.code = "CAN_ADD_LOAN_PRODUCT_ROLE";
this.name = "Add staff"; this.name = "Add loan product";
this.description = "Allows an application user add new staff members for their organisation."; this.description = "Allows an application user add new loan products for their organisation.";
this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION; this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION;
return this; return this;
} }
public PermissionBuilder addLoanProduct() { public PermissionBuilder viewLoanPortfolio() {
this.code = "CAN_ADD_LOAN_PRODUCT_ROLE"; this.code = "CAN_VIEW_LOAN_PORTFOLIO_ROLE";
this.name = "Add loan product"; this.name = "View client, group and loan information";
this.description = "Allows an application user add new loan products for their organisation."; this.description = "Allows an application user to view client, group and loan information for their organisation.";
this.permissionGroup = PermissionGroup.ORGANISATION_ADMINISTRATION; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder viewLoanPortfolio() { public PermissionBuilder addLoan() {
this.code = "CAN_VIEW_LOAN_PORTFOLIO_ROLE"; this.code = "CAN_ADD_LOAN_ROLE";
this.name = "View client, group and loan information"; this.name = "Add loan.";
this.description = "Allows an application user to view client, group and loan information for their organisation."; this.description = "Allows an application user to add a loan.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder addLoan() { public PermissionBuilder addBackdatedLoan() {
this.code = "CAN_ADD_LOAN_ROLE"; this.code = "CAN_ADD_BACKDATED_LOAN_ROLE";
this.name = "Add loan."; this.name = "Add backdated loan.";
this.description = "Allows an application user to add a loan."; this.description = "Allows an application user to add a loan where the submitted on date is in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder addBackdatedLoan() { public PermissionBuilder approveLoan() {
this.code = "CAN_ADD_BACKDATED_LOAN_ROLE"; this.code = "CAN_APPROVE_LOAN_ROLE";
this.name = "Add backdated loan."; this.name = "Approve loan.";
this.description = "Allows an application user to add a loan where the submitted on date is in the past."; this.description = "Allows an application user to approve a loan.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder approveLoan() { public PermissionBuilder approveLoanInThePast() {
this.code = "CAN_APPROVE_LOAN_ROLE"; this.code = "CAN_APPROVE_LOAN_IN_THE_PAST_ROLE";
this.name = "Approve loan."; this.name = "Approve loan with date in past.";
this.description = "Allows an application user to approve a loan."; this.description = "Allows an application user to approve a loan with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder approveLoanInThePast() { public PermissionBuilder rejectLoan() {
this.code = "CAN_APPROVE_LOAN_IN_THE_PAST_ROLE"; this.code = "CAN_REJECT_LOAN_ROLE";
this.name = "Approve loan with date in past."; this.name = "Reject loan.";
this.description = "Allows an application user to approve a loan with a date in the past."; this.description = "Allows an application user to reject the loan application.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder rejectLoan() { public PermissionBuilder rejectLoanInThePast() {
this.code = "CAN_REJECT_LOAN_ROLE"; this.code = "CAN_REJECT_LOAN_IN_THE_PAST_ROLE";
this.name = "Reject loan."; this.name = "Reject loan with date in past.";
this.description = "Allows an application user to reject the loan application."; this.description = "Allows an application user to reject the loan application with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder rejectLoanInThePast() { public PermissionBuilder withdrawLoan() {
this.code = "CAN_REJECT_LOAN_IN_THE_PAST_ROLE"; this.code = "CAN_WITHDRAW_LOAN_ROLE";
this.name = "Reject loan with date in past."; this.name = "Withdraw loan.";
this.description = "Allows an application user to reject the loan application with a date in the past."; this.description = "Allows an application user to withdraw the loan application.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder withdrawLoan() { public PermissionBuilder withdrawLoanInThePast() {
this.code = "CAN_WITHDRAW_LOAN_ROLE"; this.code = "CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE";
this.name = "Withdraw loan."; this.name = "Withdraw loan with date in past.";
this.description = "Allows an application user to withdraw the loan application."; this.description = "Allows an application user to withraw the loan application with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder withdrawLoanInThePast() { public PermissionBuilder undoLoanApproval() {
this.code = "CAN_WITHDRAW_LOAN_IN_THE_PAST_ROLE"; this.code = "CAN_UNDO_LOAN_APPROVAL_ROLE";
this.name = "Withdraw loan with date in past."; this.name = "Undo loan approval.";
this.description = "Allows an application user to withraw the loan application with a date in the past."; this.description = "Allows an application user to undo a loan approval.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder undoLoanApproval() { public PermissionBuilder disburseLoan() {
this.code = "CAN_UNDO_LOAN_APPROVAL_ROLE"; this.code = "CAN_DISBURSE_LOAN_ROLE";
this.name = "Undo loan approval."; this.name = "Disburse loan.";
this.description = "Allows an application user to undo a loan approval."; this.description = "Allows an application user to disburse the loan.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder disburseLoan() { public PermissionBuilder disburseLoanInThePast() {
this.code = "CAN_DISBURSE_LOAN_ROLE"; this.code = "CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE";
this.name = "Disburse loan."; this.name = "Disburse loan with date in past.";
this.description = "Allows an application user to disburse the loan."; this.description = "Allows an application user to disburse the loan with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder disburseLoanInThePast() { public PermissionBuilder undoLoanDisbursal() {
this.code = "CAN_DISBURSE_LOAN_IN_THE_PAST_ROLE"; this.code = "CAN_UNDO_LOAN_DISBURSAL_ROLE";
this.name = "Disburse loan with date in past."; this.name = "Undo loan disbursal.";
this.description = "Allows an application user to disburse the loan with a date in the past."; this.description = "Allows an application user to undo a loan disbursal (if no payments already made).";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder undoLoanDisbursal() { public PermissionBuilder makeLoanRepayment() {
this.code = "CAN_UNDO_LOAN_DISBURSAL_ROLE"; this.code = "CAN_MAKE_LOAN_REPAYMENT_ROLE";
this.name = "Undo loan disbursal."; this.name = "Make loan repayment.";
this.description = "Allows an application user to undo a loan disbursal (if no payments already made)."; this.description = "Allows an application user to make a repayment against a loan.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder makeLoanRepayment() { public PermissionBuilder makeLoanRepaymentInThePast() {
this.code = "CAN_MAKE_LOAN_REPAYMENT_ROLE"; this.code = "CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE";
this.name = "Make loan repayment."; this.name = "Make loan repayment with date in past.";
this.description = "Allows an application user to make a repayment against a loan."; this.description = "Allows an application user to disburse the loan with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder makeLoanRepaymentInThePast() { public PermissionBuilder writeoffLoan() {
this.code = "CAN_MAKE_LOAN_REPAYMENT_IN_THE_PAST_ROLE"; this.code = "CAN_WRITEOFF_LOAN_ROLE";
this.name = "Make loan repayment with date in past."; this.name = "Write off loan.";
this.description = "Allows an application user to disburse the loan with a date in the past."; this.description = "Allows an application user to write off the loan application.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder writeoffLoan() { public PermissionBuilder writeoffLoanInThePast() {
this.code = "CAN_WRITEOFF_LOAN_ROLE"; this.code = "CAN_WRITEOFF_LOAN_IN_THE_PAST_ROLE";
this.name = "Write off loan."; this.name = "Write off loan with date in past.";
this.description = "Allows an application user to write off the loan application."; this.description = "Allows an application user to write off the loan application with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder writeoffLoanInThePast() { public PermissionBuilder rescheduleLoan() {
this.code = "CAN_WRITEOFF_LOAN_IN_THE_PAST_ROLE"; this.code = "CAN_RESCHEDULE_LOAN_ROLE";
this.name = "Write off loan with date in past."; this.name = "Reschedule loan.";
this.description = "Allows an application user to write off the loan application with a date in the past."; this.description = "Allows an application user to reschedule the loan application.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder rescheduleLoan() { public PermissionBuilder rescheduleInThePast() {
this.code = "CAN_RESCHEDULE_LOAN_ROLE"; this.code = "CAN_RESCHEDULE_LOAN_IN_THE_PAST_ROLE";
this.name = "Reschedule loan."; this.name = "Reschedule loan with date in past.";
this.description = "Allows an application user to reschedule the loan application."; this.description = "Allows an application user to reschedule the loan application with a date in the past.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT;
return this; return this;
} }
public PermissionBuilder rescheduleInThePast() { public PermissionBuilder dataMigration() {
this.code = "CAN_RESCHEDULE_LOAN_IN_THE_PAST_ROLE"; this.code = "CAN_MIGRATE_DATA_ROLE";
this.name = "Reschedule loan with date in past."; this.name = "Upload client, group and loan data onto application in bulk";
this.description = "Allows an application user to reschedule the loan application with a date in the past."; this.description = "Allows an application user to upload client, group and loan information in bulk for their organisation.";
this.permissionGroup = PermissionGroup.PORTFOLIO_MANAGEMENT; this.permissionGroup = PermissionGroup.DATA_MIGRATION;
return this; return this;
} }
public PermissionBuilder dataMigration() {
this.code = "CAN_MIGRATE_DATA_ROLE";
this.name = "Upload client, group and loan data onto application in bulk";
this.description = "Allows an application user to upload client, group and loan information in bulk for their organisation.";
this.permissionGroup = PermissionGroup.DATA_MIGRATION;
return this;
}
} }
@@ -12,13 +12,11 @@ import javax.persistence.FetchType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.mifosng.platform.api.data.PermissionData; import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData; import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Organisation;
@Entity @Entity
@Table(name = "admin_role") @Table(name = "admin_role")
@@ -30,10 +28,6 @@ public class Role extends AbstractAuditableCustom<AppUser, Long> {
@Column(name="description", nullable=false, length=500) @Column(name="description", nullable=false, length=500)
private String description; private String description;
@ManyToOne
@JoinColumn(name="org_id", nullable=false)
private Organisation organisation;
@ManyToMany(fetch = FetchType.EAGER) @ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "admin_role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id")) @JoinTable(name = "admin_role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id"))
private Set<Permission> permissions; private Set<Permission> permissions;
@@ -42,11 +36,9 @@ public class Role extends AbstractAuditableCustom<AppUser, Long> {
this.name = null; this.name = null;
this.description = null; this.description = null;
this.permissions = new HashSet<Permission>(); this.permissions = new HashSet<Permission>();
this.organisation = null;
} }
public Role(final Organisation organisation, final String name, final String description, final List<Permission> rolePermissions) { public Role(final String name, final String description, final List<Permission> rolePermissions) {
this.organisation = organisation;
this.name = name.trim(); this.name = name.trim();
this.description = description.trim(); this.description = description.trim();
this.permissions = new HashSet<Permission>(rolePermissions); this.permissions = new HashSet<Permission>(rolePermissions);
@@ -69,7 +61,7 @@ public class Role extends AbstractAuditableCustom<AppUser, Long> {
public RoleData toData() { public RoleData toData() {
RoleData data = new RoleData(this.getId(), this.organisation.getId(), this.name, this.description); RoleData data = new RoleData(this.getId(), this.name, this.description);
Collection<PermissionData> rolePermissions = new ArrayList<PermissionData>(); Collection<PermissionData> rolePermissions = new ArrayList<PermissionData>();
for (Permission permission : this.permissions) { for (Permission permission : this.permissions) {
@@ -1,12 +1,10 @@
package org.mifosng.platform.user.domain; package org.mifosng.platform.user.domain;
import org.mifosng.platform.organisation.domain.Office; import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.Organisation;
public interface UserDomainService { public interface UserDomainService {
void createDefaultAdminUser(Organisation organisation, Office office); void createDefaultAdminUser(Office office);
void create(AppUser appUser); void create(AppUser appUser);
} }
@@ -1,10 +1,7 @@
package org.mifosng.platform.user.domain; package org.mifosng.platform.user.domain;
import org.mifosng.platform.organisation.domain.Organisation;
public interface UserPriviledgeDomainService { public interface UserPriviledgeDomainService {
void createAllOrganisationRolesAndPermissions(Organisation organisation); void createAllOrganisationRolesAndPermissions();
} }
@@ -1,7 +1,5 @@
package org.mifosng.platform.user.service; package org.mifosng.platform.user.service;
import static org.mifosng.platform.Specifications.usersThatMatch;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -49,18 +47,16 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic
@Override @Override
public Collection<AppUserData> retrieveAllUsers() { public Collection<AppUserData> retrieveAllUsers() {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
List<OfficeData> offices = new ArrayList<OfficeData>(officeReadPlatformService.retrieveAllOffices()); List<OfficeData> offices = new ArrayList<OfficeData>(officeReadPlatformService.retrieveAllOffices());
String officeIdsList = generateOfficeIdInClause(offices); String officeIdsList = generateOfficeIdInClause(offices);
AppUserMapper mapper = new AppUserMapper(offices); AppUserMapper mapper = new AppUserMapper(offices);
String sql = "select " + mapper.schema() String sql = "select " + mapper.schema()
+ " where u.org_id = ? and u.office_id in (" + officeIdsList + " where u.office_id in (" + officeIdsList + ") order by u.id";
+ ") order by u.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] { currentUser return this.jdbcTemplate.query(sql, mapper, new Object[] {});
.getOrganisation().getId() });
} }
private String generateOfficeIdInClause(List<OfficeData> offices) { private String generateOfficeIdInClause(List<OfficeData> offices) {
@@ -91,15 +87,15 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic
} }
@Override @Override
public AppUserData retrieveUser(Long userId) { public AppUserData retrieveUser(final Long userId) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
List<OfficeLookup> offices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup()); List<OfficeLookup> offices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
List<RoleData> availableRoles = new ArrayList<RoleData>(this.roleReadPlatformService.retrieveAllRoles()); List<RoleData> availableRoles = new ArrayList<RoleData>(this.roleReadPlatformService.retrieveAllRoles());
AppUser user = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), userId)); AppUser user = this.appUserRepository.findOne(userId);
if (user == null) { if (user == null) {
throw new UserNotFoundException(userId); throw new UserNotFoundException(userId);
} }
@@ -111,8 +107,7 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic
} }
AppUserData userData = new AppUserData(user.getId(), AppUserData userData = new AppUserData(user.getId(),
user.getUsername(), user.getEmail(), user.getOrganisation() user.getUsername(), user.getEmail(), user.getOffice().getId(), user.getOffice()
.getId(), user.getOffice().getId(), user.getOffice()
.getName()); .getName());
userData.setFirstname(user.getFirstname()); userData.setFirstname(user.getFirstname());
userData.setLastname(user.getLastname()); userData.setLastname(user.getLastname());
@@ -143,13 +138,12 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic
String firstname = rs.getString("firstname"); String firstname = rs.getString("firstname");
String lastname = rs.getString("lastname"); String lastname = rs.getString("lastname");
String email = rs.getString("email"); String email = rs.getString("email");
Long orgId = JdbcSupport.getLong(rs, "orgId");
Long officeId = JdbcSupport.getLong(rs, "officeId"); Long officeId = JdbcSupport.getLong(rs, "officeId");
// FIXME - change sql query to join to get office id and name information. // FIXME - change sql query to join to get office id and name information.
String officeName = fromOfficeList(this.offices, officeId); String officeName = fromOfficeList(this.offices, officeId);
AppUserData user = new AppUserData(id, username, email, orgId, officeId, officeName); AppUserData user = new AppUserData(id, username, email, officeId, officeName);
user.setLastname(lastname); user.setLastname(lastname);
user.setFirstname(firstname); user.setFirstname(firstname);
@@ -157,7 +151,7 @@ public class AppUserReadPlatformServiceImpl implements AppUserReadPlatformServic
} }
public String schema() { public String schema() {
return " u.id as id, u.username as username, u.firstname as firstname, u.lastname as lastname, u.email as email, u.org_id as orgId, u.office_id as officeId from admin_appuser u "; return " u.id as id, u.username as username, u.firstname as firstname, u.lastname as lastname, u.email as email, u.office_id as officeId from admin_appuser u ";
} }
private String fromOfficeList(final List<OfficeData> officeList, final Long officeId) { private String fromOfficeList(final List<OfficeData> officeList, final Long officeId) {
@@ -1,7 +1,5 @@
package org.mifosng.platform.user.service; package org.mifosng.platform.user.service;
import static org.mifosng.platform.Specifications.usersThatMatch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -64,7 +62,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
public Long createUser(final UserCommand command) { public Long createUser(final UserCommand command) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
UserCommandValidator validator = new UserCommandValidator(command); UserCommandValidator validator = new UserCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
@@ -81,7 +79,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
password = "autogenerate"; password = "autogenerate";
} }
AppUser appUser = AppUser.createNew(currentUser.getOrganisation(), office, AppUser appUser = AppUser.createNew(office,
allRoles, command.getUsername(), command.getEmail(), allRoles, command.getUsername(), command.getEmail(),
command.getFirstname(), command.getLastname(), command.getFirstname(), command.getLastname(),
password); password);
@@ -106,7 +104,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
public Long updateUser(UserCommand command) { public Long updateUser(UserCommand command) {
try { try {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
UserCommandValidator validator = new UserCommandValidator(command); UserCommandValidator validator = new UserCommandValidator(command);
validator.validateForUpdate(); validator.validateForUpdate();
@@ -121,7 +119,7 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit
} }
} }
AppUser userToUpdate = this.appUserRepository.findOne(usersThatMatch(currentUser.getOrganisation(), command.getId())); AppUser userToUpdate = this.appUserRepository.findOne(command.getId());
if (userToUpdate == null) { if (userToUpdate == null) {
throw new UserNotFoundException(command.getId()); throw new UserNotFoundException(command.getId());
} }
@@ -8,7 +8,6 @@ import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
@@ -29,13 +28,12 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
@Override @Override
public Collection<PermissionData> retrieveAllPermissions() { public Collection<PermissionData> retrieveAllPermissions() {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
PermissionMapper mapper = new PermissionMapper(); PermissionMapper mapper = new PermissionMapper();
String sql = "select " + mapper.schema() + " where p.org_id = ? order by p.id"; String sql = "select " + mapper.schema() + " order by p.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] { currentUser return this.jdbcTemplate.query(sql, mapper, new Object[] {});
.getOrganisation().getId() });
} }
private static final class PermissionMapper implements RowMapper<PermissionData> { private static final class PermissionMapper implements RowMapper<PermissionData> {
@@ -44,17 +42,16 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
public PermissionData mapRow(final ResultSet rs, final int rowNum) throws SQLException { public PermissionData mapRow(final ResultSet rs, final int rowNum) throws SQLException {
Long id = JdbcSupport.getLong(rs, "id"); Long id = JdbcSupport.getLong(rs, "id");
Long orgId = JdbcSupport.getLong(rs, "orgId");
String name = rs.getString("name"); String name = rs.getString("name");
String description = rs.getString("description"); String description = rs.getString("description");
String code = rs.getString("code"); String code = rs.getString("code");
Integer groupType = JdbcSupport.getInteger(rs, "groupType"); Integer groupType = JdbcSupport.getInteger(rs, "groupType");
return new PermissionData(id, orgId, name, description, code, groupType); return new PermissionData(id, name, description, code, groupType);
} }
public String schema() { public String schema() {
return " p.id as id, p.org_id as orgId, p.default_name as name, p.default_description as description, p.code as code, p.group_enum as groupType from admin_permission p "; return " p.id as id, p.default_name as name, p.default_description as description, p.code as code, p.group_enum as groupType from admin_permission p ";
} }
} }
} }
@@ -1,7 +1,5 @@
package org.mifosng.platform.user.service; package org.mifosng.platform.user.service;
import static org.mifosng.platform.Specifications.rolesThatMatch;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Collection; import java.util.Collection;
@@ -11,7 +9,6 @@ import org.mifosng.platform.exceptions.RoleNotFoundException;
import org.mifosng.platform.infrastructure.JdbcSupport; import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.Role; import org.mifosng.platform.user.domain.Role;
import org.mifosng.platform.user.domain.RoleRepository; import org.mifosng.platform.user.domain.RoleRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -35,19 +32,19 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
@Override @Override
public Collection<RoleData> retrieveAllRoles() { public Collection<RoleData> retrieveAllRoles() {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
RoleMapper mapper = new RoleMapper(); RoleMapper mapper = new RoleMapper();
String sql = "select " + mapper.schema() + " where r.org_id = ? order by r.id"; String sql = "select " + mapper.schema() + " order by r.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] {currentUser.getOrganisation().getId() }); return this.jdbcTemplate.query(sql, mapper, new Object[] {});
} }
@Override @Override
public RoleData retrieveRole(final Long id) { public RoleData retrieveRole(final Long id) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
Role role = this.roleRepository.findOne(rolesThatMatch(currentUser.getOrganisation(), id)); Role role = this.roleRepository.findOne(id);
if (role == null) { if (role == null) {
throw new RoleNotFoundException(id); throw new RoleNotFoundException(id);
} }
@@ -61,15 +58,14 @@ public class RoleReadPlatformServiceImpl implements RoleReadPlatformService {
throws SQLException { throws SQLException {
Long id = JdbcSupport.getLong(rs, "id"); Long id = JdbcSupport.getLong(rs, "id");
Long orgId = JdbcSupport.getLong(rs, "orgId");
String name = rs.getString("name"); String name = rs.getString("name");
String description = rs.getString("description"); String description = rs.getString("description");
return new RoleData(id, orgId, name, description); return new RoleData(id, name, description);
} }
public String schema() { public String schema() {
return " r.id as id, r.org_id as orgId, r.name as name, r.description as description from admin_role r"; return " r.id as id, r.name as name, r.description as description from admin_role r";
} }
} }
} }
@@ -1,7 +1,5 @@
package org.mifosng.platform.user.service; package org.mifosng.platform.user.service;
import static org.mifosng.platform.Specifications.rolesThatMatch;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -9,7 +7,6 @@ import java.util.List;
import org.mifosng.platform.api.commands.RoleCommand; import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.exceptions.RoleNotFoundException; import org.mifosng.platform.exceptions.RoleNotFoundException;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.mifosng.platform.user.domain.AppUser;
import org.mifosng.platform.user.domain.Permission; import org.mifosng.platform.user.domain.Permission;
import org.mifosng.platform.user.domain.PermissionRepository; import org.mifosng.platform.user.domain.PermissionRepository;
import org.mifosng.platform.user.domain.Role; import org.mifosng.platform.user.domain.Role;
@@ -38,14 +35,14 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf
@Override @Override
public Long createRole(final RoleCommand command) { public Long createRole(final RoleCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
RoleCommandValidator validator = new RoleCommandValidator(command); RoleCommandValidator validator = new RoleCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
List<Permission> selectedPermissions = assembleListOfSelectedPermissions(command.getPermissions()); List<Permission> selectedPermissions = assembleListOfSelectedPermissions(command.getPermissions());
Role entity = new Role(currentUser.getOrganisation(), command.getName(), command.getDescription(), selectedPermissions); Role entity = new Role(command.getName(), command.getDescription(), selectedPermissions);
this.roleRepository.save(entity); this.roleRepository.save(entity);
@@ -56,14 +53,14 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf
@Override @Override
public Long updateRole(RoleCommand command) { public Long updateRole(RoleCommand command) {
AppUser currentUser = context.authenticatedUser(); context.authenticatedUser();
RoleCommandValidator validator = new RoleCommandValidator(command); RoleCommandValidator validator = new RoleCommandValidator(command);
validator.validateForUpdate(); validator.validateForUpdate();
List<Permission> selectedPermissions = assembleListOfSelectedPermissions(command.getPermissions()); List<Permission> selectedPermissions = assembleListOfSelectedPermissions(command.getPermissions());
Role role = this.roleRepository.findOne(rolesThatMatch(currentUser.getOrganisation(), command.getId())); Role role = this.roleRepository.findOne(command.getId());
if (role == null) { if (role == null) {
throw new RoleNotFoundException(command.getId()); throw new RoleNotFoundException(command.getId());
} }