Repository: incubator-fineract Updated Branches: refs/heads/develop 446ff4403 -> 9fedac2ba
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformServiceImpl.java new file mode 100644 index 0000000..743efd6 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformServiceImpl.java @@ -0,0 +1,305 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.tax.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.fineract.accounting.common.AccountingDropdownReadPlatformService; +import org.apache.fineract.accounting.common.AccountingEnumerations; +import org.apache.fineract.accounting.glaccount.data.GLAccountData; +import org.apache.fineract.infrastructure.core.data.EnumOptionData; +import org.apache.fineract.infrastructure.core.domain.JdbcSupport; +import org.apache.fineract.infrastructure.core.service.RoutingDataSource; +import org.apache.fineract.portfolio.tax.data.TaxComponentData; +import org.apache.fineract.portfolio.tax.data.TaxComponentHistoryData; +import org.apache.fineract.portfolio.tax.data.TaxGroupData; +import org.apache.fineract.portfolio.tax.data.TaxGroupMappingsData; +import org.joda.time.LocalDate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class TaxReadPlatformServiceImpl implements TaxReadPlatformService { + + final TaxComponentMapper taxComponentMapper = new TaxComponentMapper(); + final TaxGroupMapper taxGroupMapper = new TaxGroupMapper(); + final TaxComponentLookUpMapper taxComponentLookUpMapper = new TaxComponentLookUpMapper(); + final TaxGroupLookUpMapper taxGroupLookUpMapper = new TaxGroupLookUpMapper(); + + private final JdbcTemplate jdbcTemplate; + private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService; + + @Autowired + public TaxReadPlatformServiceImpl(final RoutingDataSource dataSource, + final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService; + } + + @Override + public Collection<TaxComponentData> retrieveAllTaxComponents() { + String sql = "select " + this.taxComponentMapper.getSchema(); + return this.jdbcTemplate.query(sql, this.taxComponentMapper); + } + + @Override + public TaxComponentData retrieveTaxComponentData(final Long id) { + String sql = "select " + this.taxComponentMapper.getSchema() + " where tc.id=?"; + return this.jdbcTemplate.queryForObject(sql, this.taxComponentMapper, new Object[] { id }); + } + + @Override + public TaxComponentData retrieveTaxComponentTemplate() { + return TaxComponentData.template(this.accountingDropdownReadPlatformService.retrieveAccountMappingOptions(), + this.accountingDropdownReadPlatformService.retrieveGLAccountTypeOptions()); + } + + @Override + public Collection<TaxGroupData> retrieveAllTaxGroups() { + String sql = "select " + this.taxGroupMapper.getSchema(); + return this.jdbcTemplate.query(sql, this.taxGroupMapper); + } + + @Override + public TaxGroupData retrieveTaxGroupData(final Long id) { + String sql = "select " + this.taxGroupMapper.getSchema() + " where tg.id=?"; + return this.jdbcTemplate.queryForObject(sql, this.taxGroupMapper, new Object[] { id }); + } + + @Override + public TaxGroupData retrieveTaxGroupWithTemplate(final Long id) { + TaxGroupData taxGroupData = retrieveTaxGroupData(id); + taxGroupData = TaxGroupData.template(taxGroupData, retrieveTaxComponentsForLookUp()); + return taxGroupData; + } + + @Override + public TaxGroupData retrieveTaxGroupTemplate() { + return TaxGroupData.template(retrieveTaxComponentsForLookUp()); + } + + private Collection<TaxComponentData> retrieveTaxComponentsForLookUp() { + String sql = "select " + this.taxComponentLookUpMapper.getSchema(); + return this.jdbcTemplate.query(sql, this.taxComponentLookUpMapper); + } + + @Override + public Collection<TaxGroupData> retrieveTaxGroupsForLookUp() { + String sql = "select " + this.taxGroupLookUpMapper.getSchema(); + return this.jdbcTemplate.query(sql, this.taxGroupLookUpMapper); + } + + private static final class TaxComponentMapper implements RowMapper<TaxComponentData> { + + private final String schema; + private TaxComponentHistoryDataMapper componentHistoryDataMapper = new TaxComponentHistoryDataMapper(); + + public TaxComponentMapper() { + StringBuilder sb = new StringBuilder(); + sb.append("tc.id as id, tc.name as name,"); + sb.append("tc.percentage as percentage, tc.start_date as startDate,"); + sb.append("tc.debit_account_type_enum as debitAccountTypeEnum,"); + sb.append("dgl.id as debitAccountId, dgl.name as debitAccountName, dgl.gl_code as debitAccountGlCode,"); + sb.append("tc.credit_account_type_enum as creditAccountTypeEnum,"); + sb.append("cgl.id as creditAccountId, cgl.name as creditAccountName, cgl.gl_code as creditAccountGlCode,"); + sb.append("history.percentage as historyPercentage, history.start_date as historyStartDate,"); + sb.append("history.end_date as historyEndDate"); + sb.append(" from m_tax_component tc "); + sb.append(" left join acc_gl_account dgl on dgl.id = tc.debit_account_id"); + sb.append(" left join acc_gl_account cgl on cgl.id = tc.credit_account_id"); + sb.append(" left join m_tax_component_history history on history.tax_component_id = tc.id"); + + this.schema = sb.toString(); + } + + @Override + public TaxComponentData mapRow(ResultSet rs, int rowNum) throws SQLException { + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + final BigDecimal percentage = rs.getBigDecimal("percentage"); + final Integer debitAccountTypeEnum = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "debitAccountTypeEnum"); + EnumOptionData debitAccountType = null; + if (debitAccountTypeEnum != null) { + debitAccountType = AccountingEnumerations.gLAccountType(debitAccountTypeEnum); + } + GLAccountData debitAccountData = null; + if (debitAccountTypeEnum != null && debitAccountTypeEnum > 0) { + final Long debitAccountId = rs.getLong("debitAccountId"); + final String debitAccountName = rs.getString("debitAccountName"); + final String debitAccountGlCode = rs.getString("debitAccountGlCode"); + debitAccountData = new GLAccountData(debitAccountId, debitAccountName, debitAccountGlCode); + } + + final Integer creditAccountTypeEnum = JdbcSupport.getIntegerDefaultToNullIfZero(rs, "creditAccountTypeEnum"); + EnumOptionData creditAccountType = null; + if (creditAccountTypeEnum != null) { + creditAccountType = AccountingEnumerations.gLAccountType(creditAccountTypeEnum); + } + GLAccountData creditAccountData = null; + if (creditAccountTypeEnum != null && creditAccountTypeEnum > 0) { + final Long creditAccountId = rs.getLong("creditAccountId"); + final String creditAccountName = rs.getString("creditAccountName"); + final String creditAccountGlCode = rs.getString("creditAccountGlCode"); + creditAccountData = new GLAccountData(creditAccountId, creditAccountName, creditAccountGlCode); + } + final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate"); + + Collection<TaxComponentHistoryData> historyDatas = new ArrayList<>(); + historyDatas.add(componentHistoryDataMapper.mapRow(rs, rowNum)); + while (rs.next()) { + if (id.equals(rs.getLong("id"))) { + historyDatas.add(componentHistoryDataMapper.mapRow(rs, rowNum)); + } else { + rs.previous(); + break; + } + } + return TaxComponentData.instance(id, name, percentage, debitAccountType, debitAccountData, creditAccountType, + creditAccountData, startDate, historyDatas); + } + + public String getSchema() { + return this.schema; + } + + } + + private static final class TaxComponentHistoryDataMapper implements RowMapper<TaxComponentHistoryData> { + + @Override + public TaxComponentHistoryData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final BigDecimal percentage = rs.getBigDecimal("historyPercentage"); + final LocalDate startDate = JdbcSupport.getLocalDate(rs, "historyStartDate"); + final LocalDate endDate = JdbcSupport.getLocalDate(rs, "historyEndDate"); + return new TaxComponentHistoryData(percentage, startDate, endDate); + } + + } + + private static final class TaxGroupMapper implements RowMapper<TaxGroupData> { + + private final String schema; + private final TaxGroupMappingsDataMapper taxGroupMappingsDataMapper = new TaxGroupMappingsDataMapper(); + + public TaxGroupMapper() { + StringBuilder sb = new StringBuilder(); + sb.append("tg.id as id, tg.name as name,"); + sb.append("tgm.id as mappingId,"); + sb.append("tc.id as taxComponentId, tc.name as taxComponentName,"); + sb.append("tgm.start_date as startDate, tgm.end_date as endDate "); + sb.append(" from m_tax_group tg "); + sb.append(" inner join m_tax_group_mappings tgm on tgm.tax_group_id = tg.id "); + sb.append(" inner join m_tax_component tc on tc.id = tgm.tax_component_id "); + this.schema = sb.toString(); + } + + @Override + public TaxGroupData mapRow(ResultSet rs, int rowNum) throws SQLException { + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + final Collection<TaxGroupMappingsData> taxAssociations = new ArrayList<>(); + taxAssociations.add(this.taxGroupMappingsDataMapper.mapRow(rs, rowNum)); + while (rs.next()) { + if (id.equals(rs.getLong("id"))) { + taxAssociations.add(this.taxGroupMappingsDataMapper.mapRow(rs, rowNum)); + } else { + rs.previous(); + break; + } + } + return TaxGroupData.instance(id, name, taxAssociations); + } + + public String getSchema() { + return this.schema; + } + + } + + private static final class TaxGroupMappingsDataMapper implements RowMapper<TaxGroupMappingsData> { + + @Override + public TaxGroupMappingsData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long mappingId = rs.getLong("mappingId"); + final Long id = rs.getLong("taxComponentId"); + final String name = rs.getString("taxComponentName"); + TaxComponentData componentData = TaxComponentData.lookup(id, name); + + final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate"); + final LocalDate endDate = JdbcSupport.getLocalDate(rs, "endDate"); + return new TaxGroupMappingsData(mappingId, componentData, startDate, endDate); + } + + } + + private static final class TaxComponentLookUpMapper implements RowMapper<TaxComponentData> { + + private final String schema; + + public TaxComponentLookUpMapper() { + StringBuilder sb = new StringBuilder(); + sb.append("tc.id as id, tc.name as name "); + sb.append(" from m_tax_component tc "); + this.schema = sb.toString(); + } + + public String getSchema() { + return this.schema; + } + + @Override + public TaxComponentData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + return TaxComponentData.lookup(id, name); + } + + } + + private static final class TaxGroupLookUpMapper implements RowMapper<TaxGroupData> { + + private final String schema; + + public TaxGroupLookUpMapper() { + StringBuilder sb = new StringBuilder(); + sb.append("tg.id as id, tg.name as name "); + sb.append(" from m_tax_group tg "); + this.schema = sb.toString(); + } + + public String getSchema() { + return this.schema; + } + + @Override + public TaxGroupData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + return TaxGroupData.lookup(id, name); + } + + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java new file mode 100644 index 0000000..02368df --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxUtils.java @@ -0,0 +1,94 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.tax.service; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.fineract.organisation.monetary.domain.MoneyHelper; +import org.apache.fineract.portfolio.tax.domain.TaxComponent; +import org.apache.fineract.portfolio.tax.domain.TaxGroupMappings; +import org.joda.time.LocalDate; + +public class TaxUtils { + + public static Map<TaxComponent, BigDecimal> splitTax(final BigDecimal amount, final LocalDate date, + final List<TaxGroupMappings> taxGroupMappings, final int scale) { + Map<TaxComponent, BigDecimal> map = new HashMap<>(3); + if (amount != null) { + final double amountVal = amount.doubleValue(); + double cent_percentage = Double.valueOf("100.0"); + for (TaxGroupMappings groupMappings : taxGroupMappings) { + if (groupMappings.occursOnDayFromAndUpToAndIncluding(date)) { + TaxComponent component = groupMappings.getTaxComponent(); + BigDecimal percentage = component.getApplicablePercentage(date); + if (percentage != null) { + double percentageVal = percentage.doubleValue(); + double tax = amountVal * percentageVal / cent_percentage; + map.put(component, BigDecimal.valueOf(tax).setScale(scale, MoneyHelper.getRoundingMode())); + } + } + } + } + return map; + } + + public static BigDecimal incomeAmount(final BigDecimal amount, final LocalDate date, final List<TaxGroupMappings> taxGroupMappings, + final int scale) { + Map<TaxComponent, BigDecimal> map = splitTax(amount, date, taxGroupMappings, scale); + return incomeAmount(amount, map); + } + + public static BigDecimal incomeAmount(final BigDecimal amount, final Map<TaxComponent, BigDecimal> map) { + BigDecimal totalTax = totalTaxAmount(map); + return amount.subtract(totalTax); + } + + public static BigDecimal totalTaxAmount(final Map<TaxComponent, BigDecimal> map) { + BigDecimal totalTax = BigDecimal.ZERO; + for (BigDecimal tax : map.values()) { + totalTax = totalTax.add(tax); + } + return totalTax; + } + + public static BigDecimal addTax(final BigDecimal amount, final LocalDate date, final List<TaxGroupMappings> taxGroupMappings, + final int scale) { + BigDecimal totalAmount = null; + if (amount != null && amount.compareTo(BigDecimal.ZERO) == 1) { + double percentageVal = 0; + double amountVal = amount.doubleValue(); + double cent_percentage = Double.valueOf("100.0"); + for (TaxGroupMappings groupMappings : taxGroupMappings) { + if (groupMappings.occursOnDayFromAndUpToAndIncluding(date)) { + TaxComponent component = groupMappings.getTaxComponent(); + BigDecimal percentage = component.getApplicablePercentage(date); + if (percentage != null) { + percentageVal = percentageVal + percentage.doubleValue(); + } + } + } + double total = amountVal * cent_percentage / (cent_percentage - percentageVal); + totalAmount = BigDecimal.valueOf(total).setScale(scale, MoneyHelper.getRoundingMode()); + } + return totalAmount; + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java new file mode 100644 index 0000000..950b62b --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.tax.service; + +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; + +public interface TaxWritePlatformService { + + public CommandProcessingResult createTaxComponent(JsonCommand command); + + public CommandProcessingResult updateTaxComponent(final Long id, final JsonCommand command); + + public CommandProcessingResult createTaxGroup(JsonCommand command); + + public CommandProcessingResult updateTaxGroup(final Long id, final JsonCommand command); + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java new file mode 100644 index 0000000..a96b57d --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformServiceImpl.java @@ -0,0 +1,111 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.tax.service; + +import java.util.List; +import java.util.Map; + +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; +import org.apache.fineract.portfolio.tax.domain.TaxComponent; +import org.apache.fineract.portfolio.tax.domain.TaxComponentRepository; +import org.apache.fineract.portfolio.tax.domain.TaxComponentRepositoryWrapper; +import org.apache.fineract.portfolio.tax.domain.TaxGroup; +import org.apache.fineract.portfolio.tax.domain.TaxGroupMappings; +import org.apache.fineract.portfolio.tax.domain.TaxGroupRepository; +import org.apache.fineract.portfolio.tax.domain.TaxGroupRepositoryWrapper; +import org.apache.fineract.portfolio.tax.serialization.TaxValidator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class TaxWritePlatformServiceImpl implements TaxWritePlatformService { + + private final TaxValidator validator; + private final TaxAssembler taxAssembler; + private final TaxComponentRepository taxComponentRepository; + private final TaxComponentRepositoryWrapper taxComponentRepositoryWrapper; + private final TaxGroupRepository taxGroupRepository; + private final TaxGroupRepositoryWrapper taxGroupRepositoryWrapper; + + @Autowired + public TaxWritePlatformServiceImpl(final TaxValidator validator, final TaxAssembler taxAssembler, + final TaxComponentRepository taxComponentRepository, final TaxGroupRepository taxGroupRepository, + final TaxComponentRepositoryWrapper taxComponentRepositoryWrapper, final TaxGroupRepositoryWrapper taxGroupRepositoryWrapper) { + this.validator = validator; + this.taxAssembler = taxAssembler; + this.taxComponentRepository = taxComponentRepository; + this.taxGroupRepository = taxGroupRepository; + this.taxComponentRepositoryWrapper = taxComponentRepositoryWrapper; + this.taxGroupRepositoryWrapper = taxGroupRepositoryWrapper; + } + + @Override + public CommandProcessingResult createTaxComponent(final JsonCommand command) { + this.validator.validateForTaxComponentCreate(command.json()); + TaxComponent taxComponent = this.taxAssembler.assembleTaxComponentFrom(command); + this.taxComponentRepository.save(taxComponent); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(taxComponent.getId()) // + .build(); + } + + @Override + public CommandProcessingResult updateTaxComponent(final Long id, final JsonCommand command) { + this.validator.validateForTaxComponentUpdate(command.json()); + final TaxComponent taxComponent = this.taxComponentRepositoryWrapper.findOneWithNotFoundDetection(id); + this.validator.validateStartDate(taxComponent.startDate(), command); + Map<String, Object> changes = taxComponent.update(command); + this.validator.validateTaxComponentForUpdate(taxComponent); + this.taxComponentRepository.save(taxComponent); + return new CommandProcessingResultBuilder() // + .withEntityId(id) // + .with(changes).build(); + } + + @Override + public CommandProcessingResult createTaxGroup(final JsonCommand command) { + this.validator.validateForTaxGroupCreate(command.json()); + final TaxGroup taxGroup = this.taxAssembler.assembleTaxGroupFrom(command); + this.validator.validateTaxGroup(taxGroup); + this.taxGroupRepository.save(taxGroup); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(taxGroup.getId()) // + .build(); + } + + @Override + public CommandProcessingResult updateTaxGroup(final Long id, final JsonCommand command) { + this.validator.validateForTaxGroupUpdate(command.json()); + final TaxGroup taxGroup = this.taxGroupRepositoryWrapper.findOneWithNotFoundDetection(id); + final boolean isUpdate = true; + List<TaxGroupMappings> groupMappings = this.taxAssembler.assembleTaxGroupMappingsFrom(command, isUpdate); + this.validator.validateTaxGroupEndDateAndTaxComponent(taxGroup, groupMappings); + Map<String, Object> changes = taxGroup.update(command, groupMappings); + this.validator.validateTaxGroup(taxGroup); + this.taxGroupRepository.save(taxGroup); + return new CommandProcessingResultBuilder() // + .withEntityId(id) // + .with(changes).build(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/resources/sql/migrations/core_db/V298__savings_interest_tax.sql ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V298__savings_interest_tax.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V298__savings_interest_tax.sql new file mode 100644 index 0000000..1bc0854 --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V298__savings_interest_tax.sql @@ -0,0 +1,111 @@ +CREATE TABLE `m_tax_component` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(50) NOT NULL, + `percentage` DECIMAL(19,6) NOT NULL, + `debit_account_type_enum` SMALLINT(2) NULL DEFAULT NULL, + `debit_account_id` BIGINT(20) NULL DEFAULT NULL, + `credit_account_type_enum` SMALLINT(2) NULL DEFAULT NULL, + `credit_account_id` BIGINT(20) NULL DEFAULT NULL, + `start_date` DATE NOT NULL, + `createdby_id` BIGINT(20) NOT NULL, + `created_date` DATETIME NOT NULL, + `lastmodifiedby_id` BIGINT(20) NOT NULL, + `lastmodified_date` DATETIME NOT NULL, + PRIMARY KEY (`id`), + INDEX `FK_tax_component_debit_gl_account` (`debit_account_id`), + INDEX `FK_tax_component_credit_gl_account` (`credit_account_id`), + INDEX `FK_tax_component_createdby` (`createdby_id`), + INDEX `FK_tax_component_lastmodifiedby` (`lastmodifiedby_id`), + CONSTRAINT `FK_tax_component_createdby` FOREIGN KEY (`createdby_id`) REFERENCES `m_appuser` (`id`), + CONSTRAINT `FK_tax_component_credit_gl_account` FOREIGN KEY (`credit_account_id`) REFERENCES `acc_gl_account` (`id`), + CONSTRAINT `FK_tax_component_debit_gl_account` FOREIGN KEY (`debit_account_id`) REFERENCES `acc_gl_account` (`id`), + CONSTRAINT `FK_tax_component_lastmodifiedby` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `m_appuser` (`id`) +); + +CREATE TABLE `m_tax_component_history` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `tax_component_id` BIGINT(20) NOT NULL, + `percentage` DECIMAL(19,6) NOT NULL, + `start_date` DATE NOT NULL, + `end_date` DATE NOT NULL, + `createdby_id` BIGINT(20) NOT NULL, + `created_date` DATETIME NOT NULL, + `lastmodifiedby_id` BIGINT(20) NOT NULL, + `lastmodified_date` DATETIME NOT NULL, + PRIMARY KEY (`id`), + INDEX `FK_tax_component_history_tax_component_id` (`tax_component_id`), + INDEX `FK_tax_component_history_createdby` (`createdby_id`), + INDEX `FK_tax_component_history_lastmodifiedby` (`lastmodifiedby_id`), + CONSTRAINT `FK_tax_component_history_createdby` FOREIGN KEY (`createdby_id`) REFERENCES `m_appuser` (`id`), + CONSTRAINT `FK_tax_component_history_lastmodifiedby` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `m_appuser` (`id`), + CONSTRAINT `FK_tax_component_history_tax_component_id` FOREIGN KEY (`tax_component_id`) REFERENCES `m_tax_component` (`id`) +); + +CREATE TABLE `m_tax_group` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `name` VARCHAR(50) NOT NULL, + `createdby_id` BIGINT(20) NOT NULL, + `created_date` DATETIME NOT NULL, + `lastmodifiedby_id` BIGINT(20) NOT NULL, + `lastmodified_date` DATETIME NOT NULL, + PRIMARY KEY (`id`), + INDEX `FK_tax_group_createdby` (`createdby_id`), + INDEX `FK_tax_group_lastmodifiedby` (`lastmodifiedby_id`), + CONSTRAINT `FK_tax_group_createdby` FOREIGN KEY (`createdby_id`) REFERENCES `m_appuser` (`id`), + CONSTRAINT `FK_tax_group_lastmodifiedby` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `m_appuser` (`id`) +); + +CREATE TABLE `m_tax_group_mappings` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `tax_group_id` BIGINT(20) NOT NULL, + `tax_component_id` BIGINT(20) NOT NULL, + `start_date` DATE NOT NULL, + `end_date` DATE NULL DEFAULT NULL, + `createdby_id` BIGINT(20) NOT NULL, + `created_date` DATETIME NOT NULL, + `lastmodifiedby_id` BIGINT(20) NOT NULL, + `lastmodified_date` DATETIME NOT NULL, + PRIMARY KEY (`id`), + INDEX `FK_tax_group_mappings_tax_group` (`tax_group_id`), + INDEX `FK_tax_group_mappings_tax_component` (`tax_component_id`), + INDEX `FK_tax_group_mappings_createdby` (`createdby_id`), + INDEX `FK_tax_group_mappings_lastmodifiedby` (`lastmodifiedby_id`), + CONSTRAINT `FK_tax_group_mappings_createdby` FOREIGN KEY (`createdby_id`) REFERENCES `m_appuser` (`id`), + CONSTRAINT `FK_tax_group_mappings_lastmodifiedby` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `m_appuser` (`id`), + CONSTRAINT `FK_tax_group_mappings_tax_component` FOREIGN KEY (`tax_component_id`) REFERENCES `m_tax_component` (`id`), + CONSTRAINT `FK_tax_group_mappings_tax_group` FOREIGN KEY (`tax_group_id`) REFERENCES `m_tax_group` (`id`) +); + +ALTER TABLE `m_charge` + ADD COLUMN `tax_group_id` BIGINT(20) NULL DEFAULT NULL, + ADD CONSTRAINT `FK_m_charge_m_tax_group` FOREIGN KEY (`tax_group_id`) REFERENCES `m_tax_group` (`id`); + +ALTER TABLE `m_savings_product` + ADD COLUMN `withhold_tax` TINYINT NOT NULL DEFAULT '0', + ADD COLUMN `tax_group_id` BIGINT NULL DEFAULT NULL, + ADD CONSTRAINT `FK_savings_product_tax_group` FOREIGN KEY (`tax_group_id`) REFERENCES `m_tax_group` (`id`); + +ALTER TABLE `m_savings_account` + ADD COLUMN `withhold_tax` TINYINT NOT NULL DEFAULT '0', + ADD COLUMN `tax_group_id` BIGINT NULL DEFAULT NULL, + ADD COLUMN `total_withhold_tax_derived` DECIMAL(19,6) NULL DEFAULT NULL AFTER `total_overdraft_interest_derived`, + ADD CONSTRAINT `FK_savings_account_tax_group` FOREIGN KEY (`tax_group_id`) REFERENCES `m_tax_group` (`id`); + +CREATE TABLE `m_savings_account_transaction_tax_details` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `savings_transaction_id` BIGINT(20) NOT NULL, + `tax_component_id` BIGINT(20) NOT NULL, + `amount` DECIMAL(19,6) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `FK_savings_account_transaction_tax_details_savings_transaction` FOREIGN KEY (`savings_transaction_id`) REFERENCES `m_savings_account_transaction` (`id`), + CONSTRAINT `FK_savings_account_transaction_tax_details_tax_component` FOREIGN KEY (`tax_component_id`) REFERENCES `m_tax_component` (`id`) +); + + + +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('organisation', 'READ_TAXCOMPONENT', 'TAXCOMPONENT', 'READ', 0),('organisation', 'CREATE_TAXCOMPONENT', 'TAXCOMPONENT', 'CREATE', 0),('organisation', 'CREATE_TAXCOMPONENT_CHECKER', 'TAXCOMPONENT', 'CREATE_CHECKER', 0), ('organisation', 'UPDATE_TAXCOMPONENT', 'TAXCOMPONENT', 'UPDATE', 0),('organisation', 'UPDATE_TAXCOMPONENT_CHECKER', 'TAXCOMPONENT', 'UPDATE_CHECKER', 0),('organisation', 'READ_TAXGROUP', 'TAXGROUP', 'READ', 0),('organisation', 'CREATE_TAXGROUP', 'TAXGROUP', 'CREATE', 0),('organisation', 'CREATE_TAXGROUP_CHECKER', 'TAXGROUP', 'CREATE_CHECKER', 0), ('organisation', 'UPDATE_TAXGROUP', 'TAXGROUP', 'UPDATE', 0),('organisation', 'UPDATE_TAXGROUP_CHECKER', 'TAXGROUP', 'UPDATE_CHECKER', 0),('portfolio', 'UPDATEWITHHOLDTAX_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'UPDATEWITHHOLDTAX', 0),('portfolio', 'UPDATEWITHHOLDTAX_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'UPDATEWITHHOLD TAX_CHECKER', 0); + + + + +
