running balance updation for journal entries

This commit is contained in:
Pramod Nuthakki
2013-10-01 22:25:52 +05:30
parent 7c8016726a
commit ba3314f1ee
12 changed files with 366 additions and 51 deletions
+79 -5
View File
@@ -711,7 +711,8 @@
<tr class="alt">
<td><a href="#journalentries">Journal Entries</a></td>
<td>journalentries</td>
<td><a href="#journalentries_create">Create Journal Entries</a></td>
<td><a href="#journalentries_create">Create Journal Entries</a><br>
<a href="#journalentries_updatebalance">Update Journal Entries Running Balance</a></td>
<td><a href="#journalentries_list">List Journal Entries</a></td>
<td></td>
<td></td>
@@ -18734,6 +18735,27 @@ No Request Body:
<tr>
<td class=fielddesc>Denotes the accounting rule id for posting journal entries.
</td>
</tr>
<tr class=alt>
<td>officeRunningBalance</td>
</tr>
<tr>
<td class=fielddesc>Describes office balance after the journal entry for the Ledger Account.
</td>
</tr>
<tr class=alt>
<td>organizationRunningBalance</td>
</tr>
<tr>
<td class=fielddesc>Describes complete organization balances after the journal entry for the Ledger Account.
</td>
</tr>
<tr class=alt>
<td>runningBalanceComputed</td>
</tr>
<tr>
<td class=fielddesc>Describes whether account balances computed for the journal entry.
</td>
</tr>
</table>
</div>
@@ -18869,7 +18891,10 @@ GET https://DomainName/api/v1/journalentries?transactionId=PB37X8Y21EQUY4S
5
],
"createdByUserName": "mifos",
"reversed": false
"reversed": false,
"officeRunningBalance":0,
"organizationRunningBalance":0
"runningBalanceComputed":false
},
{
"id": 2,
@@ -18909,7 +18934,11 @@ GET https://DomainName/api/v1/journalentries?transactionId=PB37X8Y21EQUY4S
5
],
"createdByUserName": "mifos",
"reversed": false
"reversed": false,
"officeRunningBalance":0,
"organizationRunningBalance":0
"runningBalanceComputed":false
}
]
}
@@ -19100,6 +19129,46 @@ Request Body:
</div>
</div>
<a id="journalentries_updatebalance" name="journalentries_updatebalance" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update Running balances for Journal Entries</h4>
<p>
This API calculates the running balances for office. If office ID not provided this API calculates running balances for all offices.
<br>
</p>
<table class=matrixHeading>
<tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Mandatory Fields</div></td>
</tr>
<tr class=alt>
<td>officeId
</td>
</tr>
</table>
</div>
<div class="method-example">
<code class="method-declaration">
POST https://DomainName/api/v1/journalentries?command=updateRunningBalance
</code>
<code class="method-request">
POST journalentries
Content-Type: application/json
Request Body:
{
"officeId": 1,
}
</code>
<code class="method-response">
{
"officeId": 1,
}
</code>
</div>
</div>
<a id="journalentries_retrieve" name="journalentries_retrieve"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
@@ -19149,7 +19218,11 @@ GET https://DomainName/api/v1/journalentries/{entryId}
2
],
"createdByUserName": "mifos",
"reversed": false
"reversed": false,
"officeRunningBalance":0,
"organizationRunningBalance":0
"runningBalanceComputed":false
}
</code>
</div>
@@ -19797,7 +19870,8 @@ GET https://DomainName/api/v1/search?query=000000111
<tr class="alt">
<td><a href="#journalentries">Journal Entries</a></td>
<td>journalentries</td>
<td><a href="#journalentries_create">Create Journal Entries</a></td>
<td><a href="#journalentries_create">Create Journal Entries</a><br>
<a href="#journalentries_updatebalance">Update Journal Entries Running Balance</a></td>
<td><a href="#journalentries_list">List Journal Entries</a></td>
<td></td>
<td></td>
@@ -0,0 +1,5 @@
ALTER TABLE `acc_gl_journal_entry`
ADD COLUMN `is_running_balance_caculated` TINYINT NOT NULL DEFAULT '0' AFTER `lastmodified_date`,
ADD COLUMN `office_running_balance` DECIMAL(19,6) NOT NULL DEFAULT '0.000000' AFTER `is_running_balance_caculated`;
INSERT INTO `job` (`name`, `display_name`, `cron_expression`, `create_time`, `task_priority`, `group_name`, `previous_run_start_time`, `next_run_time`, `job_key`, `initializing_errorlog`, `is_active`, `currently_running`, `updates_allowed`, `scheduler_group`, `is_misfired`) VALUES ('Update Accounting Running Balances', 'Update Accounting Running Balances', '0 1 0 1/1 * ? *', now(), 5, NULL, NULL, NULL, NULL, NULL, 1, 0, 1, 0, 0);
@@ -116,12 +116,17 @@ public class JournalEntriesApiResource {
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createGLJournalEntry(final String jsonRequestBody) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createJournalEntry().withJson(jsonRequestBody).build();
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
public String createGLJournalEntry(final String jsonRequestBody, @QueryParam("command") final String commandParam) {
CommandProcessingResult result = null;
if (is(commandParam, "updateRunningBalance")) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateRunningBalanceForJournalEntry()
.withJson(jsonRequestBody).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
} else {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createJournalEntry().withJson(jsonRequestBody).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
}
return this.apiJsonSerializerService.serialize(result);
}
@@ -12,14 +12,13 @@ import org.mifosplatform.infrastructure.core.data.EnumOptionData;
/**
* Immutable object representing a General Ledger Account
*
*
* Note: no getter/setters required as google will produce json from fields of
* object.
*/
public class JournalEntryData {
private final Long id;
@SuppressWarnings("unused")
private final Long officeId;
@SuppressWarnings("unused")
private final String officeName;
@@ -53,13 +52,20 @@ public class JournalEntryData {
private final Boolean reversed;
@SuppressWarnings("unused")
private final String referenceNumber;
@SuppressWarnings("unused")
private final BigDecimal officeRunningBalance;
@SuppressWarnings("unused")
private final BigDecimal organizationRunningBalance;
@SuppressWarnings("unused")
private final Boolean runningBalanceComputed;
public JournalEntryData(final Long id, final Long officeId, final String officeName, final String glAccountName,
final Long glAccountId, final String glAccountCode, final EnumOptionData glAccountClassification,
final LocalDate transactionDate, final EnumOptionData entryType, final BigDecimal amount, final String transactionId,
final Boolean manualEntry, final EnumOptionData entityType, final Long entityId, final Long createdByUserId,
final LocalDate createdDate, final String createdByUserName, final String comments, final Boolean reversed,
final String referenceNumber) {
final String referenceNumber, final BigDecimal officeRunningBalance, final BigDecimal organizationRunningBalance,
final Boolean runningBalanceComputed) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
@@ -80,22 +86,22 @@ public class JournalEntryData {
this.comments = comments;
this.reversed = reversed;
this.referenceNumber = referenceNumber;
this.officeRunningBalance = officeRunningBalance;
this.organizationRunningBalance = organizationRunningBalance;
this.runningBalanceComputed = runningBalanceComputed;
}
public Long getId() {
return this.id;
}
public Long getId() {
return this.id;
}
public Long getGlAccountId() {
return this.glAccountId;
}
public Long getGlAccountId() {
return this.glAccountId;
}
public EnumOptionData getGlAccountType() {
return this.glAccountType;
}
public EnumOptionData getGlAccountType() {
return this.glAccountType;
}
public BigDecimal getAmount() {
return this.amount;
@@ -104,4 +110,8 @@ public class JournalEntryData {
public EnumOptionData getEntryType() {
return this.entryType;
}
public Long getOfficeId() {
return this.officeId;
}
}
@@ -0,0 +1,51 @@
package org.mifosplatform.accounting.journalentry.data;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.accounting.journalentry.api.JournalEntryJsonInputParams;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.reflect.TypeToken;
@Component
public class JournalEntryDataValidator {
private final FromJsonHelper fromApiJsonHelper;
public static final Set<String> RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList(JournalEntryJsonInputParams.OFFICE_ID.getValue()));
@Autowired
public JournalEntryDataValidator(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
public void validateForUpdateRunningbalance(final JsonCommand command) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, command.json(), RUNNING_BALANCE_UPDATE_REQUEST_DATA_PARAMETERS);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLJournalEntry");
if (this.fromApiJsonHelper.parameterExists(JournalEntryJsonInputParams.OFFICE_ID.getValue(), command.parsedJson())) {
final String officeId = this.fromApiJsonHelper.extractStringNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue(),
command.parsedJson());
baseDataValidator.reset().parameter(JournalEntryJsonInputParams.OFFICE_ID.getValue()).value(officeId).ignoreIfNull()
.longGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -0,0 +1,25 @@
package org.mifosplatform.accounting.journalentry.handler;
import org.mifosplatform.accounting.journalentry.service.JournalEntryRunningBalanceUpdateService;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UpdateRunningBalanceCommandHandler implements NewCommandSourceHandler {
private final JournalEntryRunningBalanceUpdateService journalEntryRunningBalanceUpdateService;
@Autowired
public UpdateRunningBalanceCommandHandler(final JournalEntryRunningBalanceUpdateService journalEntryRunningBalanceUpdateService) {
this.journalEntryRunningBalanceUpdateService = journalEntryRunningBalanceUpdateService;
}
@Override
public CommandProcessingResult processCommand(JsonCommand command) {
return journalEntryRunningBalanceUpdateService.updateOfficeRunningBalance(command);
}
}
@@ -53,7 +53,10 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
+ " journalEntry.type_enum as entryType,journalEntry.amount as amount, journalEntry.transaction_id as transactionId,"
+ " journalEntry.entity_type_enum as entityType, journalEntry.entity_id as entityId, creatingUser.id as createdByUserId, "
+ " creatingUser.username as createdByUserName, journalEntry.description as comments, "
+ " journalEntry.created_date as createdDate, journalEntry.reversed as reversed "
+ " journalEntry.created_date as createdDate, journalEntry.reversed as reversed, "
+ " journalEntry.is_running_balance_caculated as runningBalanceComputed, "
+ " journalEntry.office_running_balance as officeRunningBalance, "
+ " journalEntry.organization_running_balance as organizationRunningBalance "
+ " from acc_gl_journal_entry journalEntry, acc_gl_account glAccount, m_office office, m_appuser creatingUser "
+ " where journalEntry.account_id = glAccount.id "
+ " and journalEntry.office_id = office.id and journalEntry.createdby_id = creatingUser.id ";
@@ -89,10 +92,13 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
final String comments = rs.getString("comments");
final Boolean reversed = rs.getBoolean("reversed");
final String referenceNumber = rs.getString("referenceNumber");
final BigDecimal officeRunningBalance = rs.getBigDecimal("officeRunningBalance");
final BigDecimal organizationRunningBalance = rs.getBigDecimal("organizationRunningBalance");
final Boolean runningBalanceComputed = rs.getBoolean("runningBalanceComputed");
return new JournalEntryData(id, officeId, officeName, glAccountName, glAccountId, glCode, accountType, transactionDate,
entryType, amount, transactionId, manualEntry, entityType, entityId, createdByUserId, createdDate, createdByUserName,
comments, reversed, referenceNumber);
comments, reversed, referenceNumber,officeRunningBalance,organizationRunningBalance,runningBalanceComputed);
}
}
@@ -1,8 +1,12 @@
package org.mifosplatform.accounting.journalentry.service;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
public interface JournalEntryRunningBalanceUpdateService {
void updateRunningBalance();
CommandProcessingResult updateOfficeRunningBalance(JsonCommand command);
}
@@ -15,14 +15,26 @@ import java.util.Map;
import org.mifosplatform.accounting.common.AccountingEnumerations;
import org.mifosplatform.accounting.glaccount.domain.GLAccountType;
import org.mifosplatform.accounting.journalentry.api.JournalEntryJsonInputParams;
import org.mifosplatform.accounting.journalentry.data.JournalEntryData;
import org.mifosplatform.accounting.journalentry.data.JournalEntryDataValidator;
import org.mifosplatform.accounting.journalentry.domain.JournalEntryType;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.jobs.annotation.CronTarget;
import org.mifosplatform.infrastructure.jobs.service.JobName;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@@ -31,52 +43,151 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntryRunningBalanceUpdateService {
private final static Logger logger = LoggerFactory.getLogger(JournalEntryRunningBalanceUpdateServiceImpl.class);
private final JdbcTemplate jdbcTemplate;
private final OfficeRepository officeRepository;
private final JournalEntryDataValidator dataValidator;
private final FromJsonHelper fromApiJsonHelper;
private final GLJournalEntryMapper entryMapper = new GLJournalEntryMapper();
private final String runningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
private final String officeRunningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
+ "inner join (select max(id) as id from acc_gl_journal_entry where office_id=? and entry_date < ? group by account_id,entry_date) je2 "
+ "inner join (select max(entry_date) as date from acc_gl_journal_entry where office_id=? and entry_date < ? group by account_id) je3 "
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC";
private final String organizationRunningBalanceSql = "select je.organization_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
+ "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by account_id,entry_date) je2 "
+ "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by account_id) je3 "
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC";
private final String officesRunningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId,je.office_id as officeId "
+ "from acc_gl_journal_entry je "
+ "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by office_id,account_id,entry_date) je2 "
+ "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by office_id,account_id) je3 "
+ "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC";
@Autowired
public JournalEntryRunningBalanceUpdateServiceImpl(final RoutingDataSource dataSource) {
public JournalEntryRunningBalanceUpdateServiceImpl(final RoutingDataSource dataSource, final OfficeRepository officeRepository,
final JournalEntryDataValidator dataValidator, final FromJsonHelper fromApiJsonHelper) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.officeRepository = officeRepository;
this.dataValidator = dataValidator;
this.fromApiJsonHelper = fromApiJsonHelper;
}
@Override
@CronTarget(jobName = JobName.ACCOUNTING_RUNNING_BALANCE_UPDATE)
public void updateRunningBalance() {
String dateFinder = "select je.office_id as officeId,MIN(je.entry_date) as entityDate " + "from acc_gl_journal_entry je "
+ "where je.is_running_balance_caculated=0 " + "group by je.office_id";
List<Map<String, Object>> list = jdbcTemplate.queryForList(dateFinder);
for (Map<String, Object> entries : list) {
Long officeId = (Long) entries.get("officeId");
Date entityDate = (Date) entries.get("entityDate");
updateRunningBalance(officeId, entityDate);
String dateFinder = "select MIN(je.entry_date) as entityDate from acc_gl_journal_entry je "
+ "where je.is_running_balance_caculated=0 ";
try {
Date entityDate = this.jdbcTemplate.queryForObject(dateFinder, Date.class);
updateOrganizationRunningBalance(entityDate);
} catch (EmptyResultDataAccessException e) {
logger.debug("No results found for updation of running balance ");
}
}
@Transactional
private void updateRunningBalance(Long officeId, Date entityDate) {
Map<Long, BigDecimal> runningBalanceMap = new HashMap<Long, BigDecimal>(5);
@Override
public CommandProcessingResult updateOfficeRunningBalance(JsonCommand command) {
this.dataValidator.validateForUpdateRunningbalance(command);
final Long officeId = this.fromApiJsonHelper.extractLongNamed(JournalEntryJsonInputParams.OFFICE_ID.getValue(),
command.parsedJson());
CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder().withCommandId(command
.commandId());
if (officeId == null) {
updateRunningBalance();
} else {
final Office office = this.officeRepository.findOne(officeId);
if (office == null) { throw new OfficeNotFoundException(officeId); }
List<Map<String, Object>> list = jdbcTemplate.queryForList(runningBalanceSql, officeId, entityDate, officeId, entityDate);
String dateFinder = "select MIN(je.entry_date) as entityDate " + "from acc_gl_journal_entry je "
+ "where je.is_running_balance_caculated=0 and je.office_id=?";
try {
Date entityDate = this.jdbcTemplate.queryForObject(dateFinder, Date.class, officeId);
updateRunningBalance(officeId, entityDate);
} catch (EmptyResultDataAccessException e) {
logger.debug("No results found for updation of office running balance with office id:" + officeId);
}
commandProcessingResultBuilder.withOfficeId(officeId);
}
return commandProcessingResultBuilder.build();
}
@Transactional
private void updateOrganizationRunningBalance(Date entityDate) {
Map<Long, BigDecimal> runningBalanceMap = new HashMap<Long, BigDecimal>(5);
Map<Long, Map<Long, BigDecimal>> officesRunningBalance = new HashMap<Long, Map<Long, BigDecimal>>();
List<Map<String, Object>> list = jdbcTemplate.queryForList(organizationRunningBalanceSql, entityDate, entityDate);
for (Map<String, Object> entries : list) {
Long accountId = (Long) entries.get("accountId");
if (!runningBalanceMap.containsKey(accountId)) {
runningBalanceMap.put(accountId, (BigDecimal) entries.get("runningBalance"));
}
}
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.schema(), entryMapper, new Object[] { officeId, entityDate });
List<Map<String, Object>> officesRunningBalanceList = jdbcTemplate.queryForList(officesRunningBalanceSql, entityDate, entityDate);
for (Map<String, Object> entries : officesRunningBalanceList) {
Long accountId = (Long) entries.get("accountId");
Long officeId = (Long) entries.get("officeId");
Map<Long, BigDecimal> runningBalance = null;
if (officesRunningBalance.containsKey(officeId)) {
runningBalance = officesRunningBalance.get(officeId);
} else {
runningBalance = new HashMap<Long, BigDecimal>();
officesRunningBalance.put(officeId, runningBalance);
}
if (!runningBalance.containsKey(accountId)) {
runningBalance.put(accountId, (BigDecimal) entries.get("runningBalance"));
}
}
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.organizationRunningBalanceSchema(), entryMapper,
new Object[] { entityDate });
String[] updateSql = new String[entryDatas.size()];
int i = 0;
for (JournalEntryData entryData : entryDatas) {
Map<Long, BigDecimal> officeRunningBalanceMap = null;
if (officesRunningBalance.containsKey(entryData.getOfficeId())) {
officeRunningBalanceMap = officesRunningBalance.get(entryData.getOfficeId());
} else {
officeRunningBalanceMap = new HashMap<Long, BigDecimal>();
officesRunningBalance.put(entryData.getOfficeId(), officeRunningBalanceMap);
}
BigDecimal officeRunningBalance = calculateRunningBalance(entryData, officeRunningBalanceMap);
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
String sql = "UPDATE acc_gl_journal_entry je SET je.is_running_balance_caculated=1, je.organization_running_balance="
+ runningBalance + ",je.office_running_balance=" + officeRunningBalance + " WHERE je.id=" + entryData.getId();
updateSql[i++] = sql;
}
this.jdbcTemplate.batchUpdate(updateSql);
}
@Transactional
private void updateRunningBalance(Long officeId, Date entityDate) {
Map<Long, BigDecimal> runningBalanceMap = new HashMap<Long, BigDecimal>(5);
List<Map<String, Object>> list = jdbcTemplate.queryForList(officeRunningBalanceSql, officeId, entityDate, officeId, entityDate);
for (Map<String, Object> entries : list) {
Long accountId = (Long) entries.get("accountId");
if (!runningBalanceMap.containsKey(accountId)) {
runningBalanceMap.put(accountId, (BigDecimal) entries.get("runningBalance"));
}
}
List<JournalEntryData> entryDatas = jdbcTemplate.query(entryMapper.officeRunningBalanceSchema(), entryMapper, new Object[] {
officeId, entityDate });
String[] updateSql = new String[entryDatas.size()];
int i = 0;
for (JournalEntryData entryData : entryDatas) {
BigDecimal runningBalance = calculateRunningBalance(entryData, runningBalanceMap);
String sql = "UPDATE acc_gl_journal_entry je SET je.is_running_balance_caculated=1, je.office_running_balance="
+ runningBalance + " WHERE je.id=" + entryData.getId();
String sql = "UPDATE acc_gl_journal_entry je SET je.office_running_balance=" + runningBalance + " WHERE je.id="
+ entryData.getId();
updateSql[i++] = sql;
}
this.jdbcTemplate.batchUpdate(updateSql);
@@ -128,10 +239,18 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
private static final class GLJournalEntryMapper implements RowMapper<JournalEntryData> {
public String schema() {
public String officeRunningBalanceSchema() {
return "select je.id as id,je.account_id as glAccountId,je.type_enum as entryType,je.amount as amount, "
+ "glAccount.classification_enum as classification,je.office_id as officeId "
+ "from acc_gl_journal_entry je , acc_gl_account glAccount " + "where je.account_id = glAccount.id "
+ "and je.office_id=? and je.entry_date >= ? order by je.entry_date,je.id";
}
public String organizationRunningBalanceSchema() {
return "select je.id as id,je.account_id as glAccountId," + "je.type_enum as entryType,je.amount as amount, "
+ "glAccount.classification_enum as classification " + "from acc_gl_journal_entry je , acc_gl_account glAccount "
+ "where je.account_id = glAccount.id " + "and je.office_id=? and je.entry_date >= ? order by je.entry_date,je.id";
+ "glAccount.classification_enum as classification,je.office_id as officeId "
+ "from acc_gl_journal_entry je , acc_gl_account glAccount " + "where je.account_id = glAccount.id "
+ "and je.entry_date >= ? order by je.entry_date,je.id";
}
@Override
@@ -139,14 +258,15 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
final Long id = rs.getLong("id");
final Long glAccountId = rs.getLong("glAccountId");
final Long officeId = rs.getLong("officeId");
final int accountTypeId = JdbcSupport.getInteger(rs, "classification");
final EnumOptionData accountType = AccountingEnumerations.gLAccountType(accountTypeId);
final BigDecimal amount = rs.getBigDecimal("amount");
final int entryTypeId = JdbcSupport.getInteger(rs, "entryType");
final EnumOptionData entryType = AccountingEnumerations.journalEntryType(entryTypeId);
return new JournalEntryData(id, null, null, null, glAccountId, null, accountType, null, entryType, amount, null, null, null,
null, null, null, null, null, null, null);
return new JournalEntryData(id, officeId, null, null, glAccountId, null, accountType, null, entryType, amount, null, null,
null, null, null, null, null, null, null, null, null, null, null);
}
}
@@ -262,6 +262,10 @@ public class CommandWrapper {
return this.actionName.equalsIgnoreCase("REVERSE") && this.entityName.equalsIgnoreCase("JOURNALENTRY");
}
public boolean isUpdateRunningbalance() {
return this.actionName.equalsIgnoreCase("UPDATERUNNINGBALANCE") && this.entityName.equalsIgnoreCase("JOURNALENTRY");
}
public boolean isFundResource() {
return this.entityName.equalsIgnoreCase("FUND");
}
@@ -773,6 +773,15 @@ public class CommandWrapperBuilder {
this.href = "/journalentries/" + transactionId;
return this;
}
public CommandWrapperBuilder updateRunningBalanceForJournalEntry() {
this.actionName = "UPDATERUNNINGBALANCE";
this.entityName = "JOURNALENTRY";
this.entityId = null;
this.href = "/journalentries/update";
return this;
}
public CommandWrapperBuilder createSavingProduct() {
this.actionName = "CREATE";
@@ -376,7 +376,9 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
handler = this.applicationContext.getBean("createJournalEntryCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isRevertJournalEntry()) {
handler = this.applicationContext.getBean("reverseJournalEntryCommandHandler", NewCommandSourceHandler.class);
} else {
}else if(wrapper.isUpdateRunningbalance()){
handler = this.applicationContext.getBean("updateRunningBalanceCommandHandler", NewCommandSourceHandler.class);
}else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isSavingsProductResource()) {