This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new b7306f19d0 FINERACT-2425: Tax component and Tax Group refactoring
b7306f19d0 is described below

commit b7306f19d02462e1f7759877c48d9b5532c39c2e
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Mon Dec 29 16:41:25 2025 -0500

    FINERACT-2425: Tax component and Tax Group refactoring
---
 .../accounting/glaccount/domain/GLAccountType.java |   4 +
 .../glaccount/domain/GLAccountUsage.java           |   5 +
 .../glaccount/mapper/GlAccountMapper.java          |  69 ++++++
 .../glaccount/mapper/GlAccountTypeMapper.java      |  23 +-
 .../glaccount/mapper/GlAccountUsageMapper.java     |  23 +-
 .../portfolio/tax/data/TaxComponentData.java       |  26 +--
 .../portfolio/tax/request/TaxComponentRequest.java |   2 +-
 .../portfolio/tax/service/TaxAssembler.java        |   8 +-
 .../tax/service/TaxReadPlatformServiceImpl.java    | 236 ++-------------------
 .../portfolio/tax/starter/TaxConfiguration.java    |   9 +-
 .../main/resources/static/legacy-docs/apiLive.htm  |  10 +-
 .../portfolio/tax/api/TaxApiConstants.java         |   4 +-
 .../portfolio/tax/api/TaxComponentApiResource.java |   2 +-
 .../tax/api/TaxComponentApiResourceSwagger.java    |   6 +-
 .../portfolio/tax/api/TaxGroupApiResource.java     |   0
 .../tax/api/TaxGroupApiResourceSwagger.java        |   0
 .../portfolio/tax/domain/TaxComponent.java         |  22 +-
 .../portfolio/tax/domain/TaxGroupMappings.java     |   2 +
 .../handler/CreateTaxComponentCommandHandler.java  |   8 +-
 .../tax/handler/CreateTaxGroupCommandHandler.java  |   8 +-
 .../handler/UpdateTaxComponentCommandHandler.java  |   8 +-
 .../tax/handler/UpdateTaxGroupCommandHandler.java  |   8 +-
 .../portfolio/tax/mapper/TaxComponentMapper.java   |  44 ++++
 .../portfolio/tax/mapper/TaxGroupMapper.java       |  28 +--
 .../tax/mapper/TaxGroupMappingsMapper.java         |  20 +-
 .../portfolio/tax/serialization/TaxValidator.java  |  16 +-
 .../tax/service/TaxReadPlatformService.java        |   0
 .../tax/service/TaxWritePlatformService.java       |   0
 .../fineract/integrationtests/TaxesTest.java       | 117 ++++++++++
 .../common/TaxComponentHelper.java                 |   7 +-
 .../integrationtests/common/TaxGroupHelper.java    |   9 +
 .../fineract/integrationtests/common/Utils.java    |   1 +
 .../common/accounting/AccountHelper.java           |  48 +++++
 33 files changed, 429 insertions(+), 344 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
index fa897c8306..7dcf7be7ac 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountType.java
@@ -119,6 +119,10 @@ public enum GLAccountType {
         return name();
     }
 
+    public EnumOptionData toEnumOptionData() {
+        return new EnumOptionData((long) value, code, code);
+    }
+
     public boolean isAssetType() {
         return this.value.equals(GLAccountType.ASSET.getValue());
     }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountUsage.java
 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountUsage.java
index bf2e587ad5..2425e37f3a 100755
--- 
a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountUsage.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccountUsage.java
@@ -20,6 +20,7 @@ package org.apache.fineract.accounting.glaccount.domain;
 
 import java.util.HashMap;
 import java.util.Map;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 
 public enum GLAccountUsage {
 
@@ -81,4 +82,8 @@ public enum GLAccountUsage {
         return name().toString();
     }
 
+    public EnumOptionData toEnumOptionData() {
+        return new EnumOptionData((long) value, code, code);
+    }
+
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountMapper.java
 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountMapper.java
new file mode 100644
index 0000000000..f72a906eeb
--- /dev/null
+++ 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountMapper.java
@@ -0,0 +1,69 @@
+/**
+ * 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.accounting.glaccount.mapper;
+
+import java.util.List;
+import org.apache.fineract.accounting.glaccount.data.GLAccountData;
+import org.apache.fineract.accounting.glaccount.domain.GLAccount;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountUsage;
+import org.apache.fineract.infrastructure.codes.mapper.CodeValueMapper;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Named;
+
+@Mapper(config = MapstructMapperConfig.class, uses = { CodeValueMapper.class })
+public interface GlAccountMapper {
+
+    @Mapping(target = "usage", source = "glAccount.usage", qualifiedByName = 
"glAccountUsage")
+    @Mapping(target = "type", source = "glAccount.type", qualifiedByName = 
"glAccountType")
+    @Mapping(target = "name", source = "glAccount.name")
+    @Mapping(target = "nameDecorated", source = "glAccount.name")
+    @Mapping(target = "parentId", source = "glAccount.parent.id")
+    @Mapping(target = "tagId", source = "glAccount.tagId")
+    @Mapping(target = "accountTypeOptions", ignore = true)
+    @Mapping(target = "usageOptions", ignore = true)
+    @Mapping(target = "assetHeaderAccountOptions", ignore = true)
+    @Mapping(target = "liabilityHeaderAccountOptions", ignore = true)
+    @Mapping(target = "equityHeaderAccountOptions", ignore = true)
+    @Mapping(target = "incomeHeaderAccountOptions", ignore = true)
+    @Mapping(target = "expenseHeaderAccountOptions", ignore = true)
+    @Mapping(target = "allowedAssetsTagOptions", ignore = true)
+    @Mapping(target = "allowedLiabilitiesTagOptions", ignore = true)
+    @Mapping(target = "allowedEquityTagOptions", ignore = true)
+    @Mapping(target = "allowedIncomeTagOptions", ignore = true)
+    @Mapping(target = "allowedExpensesTagOptions", ignore = true)
+    @Mapping(target = "organizationRunningBalance", ignore = true)
+    @Mapping(target = "rowIndex", ignore = true)
+    GLAccountData map(GLAccount glAccount);
+
+    List<GLAccountData> map(List<GLAccount> glAccounts);
+
+    @Named("glAccountType")
+    default EnumOptionData glAccountType(Integer typeId) {
+        return GLAccountType.fromInt(typeId).toEnumOptionData();
+    }
+
+    @Named("glAccountUsage")
+    default EnumOptionData glAccountUsage(Integer usageId) {
+        return GLAccountUsage.fromInt(usageId).toEnumOptionData();
+    }
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountTypeMapper.java
similarity index 54%
copy from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
copy to 
fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountTypeMapper.java
index 0d96b18fa0..83ac11f9ae 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountTypeMapper.java
@@ -16,19 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.tax.service;
+package org.apache.fineract.accounting.glaccount.mapper;
 
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 
-public interface TaxWritePlatformService {
+@Mapper(config = MapstructMapperConfig.class)
+public interface GlAccountTypeMapper {
 
-    CommandProcessingResult createTaxComponent(JsonCommand command);
-
-    CommandProcessingResult updateTaxComponent(Long id, JsonCommand command);
-
-    CommandProcessingResult createTaxGroup(JsonCommand command);
-
-    CommandProcessingResult updateTaxGroup(Long id, JsonCommand command);
+    @Mapping(target = "id", expression = "java((long) 
glAccountType.getValue())")
+    @Mapping(target = "code", source = "glAccountType.code")
+    @Mapping(target = "description", source = "glAccountType.code")
+    EnumOptionData map(GLAccountType glAccountType);
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountUsageMapper.java
similarity index 54%
copy from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
copy to 
fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountUsageMapper.java
index 0d96b18fa0..e727ab33b2 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/accounting/glaccount/mapper/GlAccountUsageMapper.java
@@ -16,19 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.tax.service;
+package org.apache.fineract.accounting.glaccount.mapper;
 
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountUsage;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 
-public interface TaxWritePlatformService {
+@Mapper(config = MapstructMapperConfig.class)
+public interface GlAccountUsageMapper {
 
-    CommandProcessingResult createTaxComponent(JsonCommand command);
-
-    CommandProcessingResult updateTaxComponent(Long id, JsonCommand command);
-
-    CommandProcessingResult createTaxGroup(JsonCommand command);
-
-    CommandProcessingResult updateTaxGroup(Long id, JsonCommand command);
+    @Mapping(target = "id", expression = "java((long) 
glAccountUsage.getValue())")
+    @Mapping(target = "code", source = "glAccountUsage.code")
+    @Mapping(target = "description", source = "glAccountUsage.code")
+    EnumOptionData map(GLAccountUsage glAccountUsage);
 
 }
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/data/TaxComponentData.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/data/TaxComponentData.java
index 11450ff333..e7dbaedc03 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/data/TaxComponentData.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/data/TaxComponentData.java
@@ -49,25 +49,25 @@ public final class TaxComponentData implements Serializable 
{
     private final Collection<EnumOptionData> glAccountTypeOptions;
 
     public static TaxComponentData instance(final Long id, final String name, 
final BigDecimal percentage,
-            final EnumOptionData debitAccountType, final GLAccountData 
debitAcount, final EnumOptionData creditAccountType,
-            final GLAccountData creditAcount, final LocalDate startDate, final 
Collection<TaxComponentHistoryData> taxComponentHistories) {
+            final EnumOptionData debitAccountType, final GLAccountData 
debitAccount, final EnumOptionData creditAccountType,
+            final GLAccountData creditAccount, final LocalDate startDate, 
final Collection<TaxComponentHistoryData> taxComponentHistories) {
         final Map<String, List<GLAccountData>> glAccountOptions = null;
         final Collection<EnumOptionData> glAccountTypeOptions = null;
-        return new TaxComponentData(id, name, percentage, debitAccountType, 
debitAcount, creditAccountType, creditAcount, startDate,
+        return new TaxComponentData(id, name, percentage, debitAccountType, 
debitAccount, creditAccountType, creditAccount, startDate,
                 taxComponentHistories, glAccountOptions, glAccountTypeOptions);
     }
 
     public static TaxComponentData lookup(final Long id, final String name) {
         final BigDecimal percentage = null;
         final EnumOptionData debitAccountType = null;
-        final GLAccountData debitAcount = null;
+        final GLAccountData debitAccount = null;
         final EnumOptionData creditAccountType = null;
-        final GLAccountData creditAcount = null;
+        final GLAccountData creditAccount = null;
         final LocalDate startDate = null;
         final Collection<TaxComponentHistoryData> taxComponentHistories = null;
         final Map<String, List<GLAccountData>> glAccountOptions = null;
         final Collection<EnumOptionData> glAccountTypeOptions = null;
-        return new TaxComponentData(id, name, percentage, debitAccountType, 
debitAcount, creditAccountType, creditAcount, startDate,
+        return new TaxComponentData(id, name, percentage, debitAccountType, 
debitAccount, creditAccountType, creditAccount, startDate,
                 taxComponentHistories, glAccountOptions, glAccountTypeOptions);
     }
 
@@ -77,24 +77,24 @@ public final class TaxComponentData implements Serializable 
{
         final String name = null;
         final BigDecimal percentage = null;
         final EnumOptionData debitAccountType = null;
-        final GLAccountData debitAcount = null;
+        final GLAccountData debitAccount = null;
         final EnumOptionData creditAccountType = null;
-        final GLAccountData creditAcount = null;
+        final GLAccountData creditAccount = null;
         final LocalDate startDate = null;
         final Collection<TaxComponentHistoryData> taxComponentHistories = null;
-        return new TaxComponentData(id, name, percentage, debitAccountType, 
debitAcount, creditAccountType, creditAcount, startDate,
+        return new TaxComponentData(id, name, percentage, debitAccountType, 
debitAccount, creditAccountType, creditAccount, startDate,
                 taxComponentHistories, glAccountOptions, glAccountTypeOptions);
     }
 
-    private TaxComponentData(final Long id, final BigDecimal percentage, final 
GLAccountData debitAcount,
-            final GLAccountData creditAcount) {
+    private TaxComponentData(final Long id, final BigDecimal percentage, final 
GLAccountData debitAccount,
+            final GLAccountData creditAccount) {
         this.id = id;
         this.percentage = percentage;
         this.name = null;
         this.debitAccountType = null;
-        this.debitAccount = debitAcount;
+        this.debitAccount = debitAccount;
         this.creditAccountType = null;
-        this.creditAccount = creditAcount;
+        this.creditAccount = creditAccount;
         this.startDate = null;
         this.taxComponentHistories = null;
         this.glAccountOptions = null;
diff --git 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/request/TaxComponentRequest.java
 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/request/TaxComponentRequest.java
index 4dfc8e3557..1af6b2f0a4 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/request/TaxComponentRequest.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/portfolio/tax/request/TaxComponentRequest.java
@@ -40,7 +40,7 @@ public class TaxComponentRequest implements Serializable {
     private Integer debitAccountType;
     private Long debitAccountId;
     private Integer creditAccountType;
-    private Long creditAcountId;
+    private Long creditAccountId;
     private String startDate;
     private String dateFormat;
     private String locale;
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java
index ac1c1e5d73..8b558e8072 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java
@@ -61,7 +61,7 @@ public class TaxAssembler {
         final BigDecimal percentage = 
this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(TaxApiConstants.percentageParamName,
 element);
         final Integer debitAccountType = 
this.fromApiJsonHelper.extractIntegerSansLocaleNamed(TaxApiConstants.debitAccountTypeParamName,
                 element);
-        final Long debitAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.debitAcountIdParamName, 
element);
+        final Long debitAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.debitAccountIdParamName,
 element);
         GLAccountType debitGlAccountType = null;
         if (debitAccountType != null) {
             debitGlAccountType = GLAccountType.fromInt(debitAccountType);
@@ -70,7 +70,7 @@ public class TaxAssembler {
         if (debitAccountId != null) {
             debitGlAccount = 
this.glAccountRepositoryWrapper.findOneWithNotFoundDetection(debitAccountId);
             if (!debitGlAccount.getType().equals(debitAccountType) || 
debitGlAccount.isHeaderAccount()) {
-                
baseDataValidator.parameter(TaxApiConstants.debitAcountIdParamName).value(debitAccountId)
+                
baseDataValidator.parameter(TaxApiConstants.debitAccountIdParamName).value(debitAccountId)
                         .failWithCode("not.a.valid.account");
             }
         }
@@ -81,12 +81,12 @@ public class TaxAssembler {
         if (creditAccountType != null) {
             creditGlAccountType = GLAccountType.fromInt(creditAccountType);
         }
-        final Long creditAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.creditAcountIdParamName,
 element);
+        final Long creditAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.creditAccountIdParamName,
 element);
         GLAccount creditGlAccount = null;
         if (creditAccountId != null) {
             creditGlAccount = 
this.glAccountRepositoryWrapper.findOneWithNotFoundDetection(creditAccountId);
             if (!creditGlAccount.getType().equals(creditAccountType) || 
creditGlAccount.isHeaderAccount()) {
-                
baseDataValidator.parameter(TaxApiConstants.creditAcountIdParamName).value(creditAccountId)
+                
baseDataValidator.parameter(TaxApiConstants.creditAccountIdParamName).value(creditAccountId)
                         .failWithCode("not.a.valid.account");
             }
         }
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
index 96acb70be4..1a4a0eb6d1 100644
--- 
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
@@ -18,47 +18,34 @@
  */
 package org.apache.fineract.portfolio.tax.service;
 
-import java.math.BigDecimal;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.time.LocalDate;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import lombok.RequiredArgsConstructor;
 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.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.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
+import org.apache.fineract.portfolio.tax.domain.TaxComponentRepository;
+import org.apache.fineract.portfolio.tax.domain.TaxGroupRepository;
+import org.apache.fineract.portfolio.tax.mapper.TaxComponentMapper;
+import org.apache.fineract.portfolio.tax.mapper.TaxGroupMapper;
 
 @RequiredArgsConstructor
 public class TaxReadPlatformServiceImpl implements TaxReadPlatformService {
 
-    private static final TaxComponentMapper TAX_COMPONENT_MAPPER = new 
TaxComponentMapper();
-    private static final TaxGroupMapper TAX_GROUP_MAPPER = new 
TaxGroupMapper();
-    private static final TaxComponentLookUpMapper TAX_COMPONENT_LOOK_UP_MAPPER 
= new TaxComponentLookUpMapper();
-    private static final TaxGroupLookUpMapper TAX_GROUP_LOOK_UP_MAPPER = new 
TaxGroupLookUpMapper();
-
-    private final JdbcTemplate jdbcTemplate;
     private final AccountingDropdownReadPlatformService 
accountingDropdownReadPlatformService;
+    private final TaxComponentRepository taxComponentRepository;
+    private final TaxComponentMapper taxComponentMapper;
+    private final TaxGroupRepository taxGroupRepository;
+    private final TaxGroupMapper taxGroupMapper;
 
     @Override
     public List<TaxComponentData> retrieveAllTaxComponents() {
-        String sql = "select " + TAX_COMPONENT_MAPPER.getSchema();
-        return this.jdbcTemplate.query(sql, TAX_COMPONENT_MAPPER); // NOSONAR
+        return taxComponentMapper.map(taxComponentRepository.findAll());
     }
 
     @Override
     public TaxComponentData retrieveTaxComponentData(final Long id) {
-        String sql = "select " + TAX_COMPONENT_MAPPER.getSchema() + " where 
tc.id=?";
-        return this.jdbcTemplate.queryForObject(sql, TAX_COMPONENT_MAPPER, 
id); // NOSONAR
+        return 
taxComponentMapper.map(taxComponentRepository.getReferenceById(id));
     }
 
     @Override
@@ -69,14 +56,12 @@ public class TaxReadPlatformServiceImpl implements 
TaxReadPlatformService {
 
     @Override
     public List<TaxGroupData> retrieveAllTaxGroups() {
-        String sql = "select " + TAX_GROUP_MAPPER.getSchema();
-        return this.jdbcTemplate.query(sql, TAX_GROUP_MAPPER); // NOSONAR
+        return taxGroupMapper.map(taxGroupRepository.findAll());
     }
 
     @Override
     public TaxGroupData retrieveTaxGroupData(final Long id) {
-        String sql = "select " + TAX_GROUP_MAPPER.getSchema() + " where 
tg.id=?";
-        return this.jdbcTemplate.queryForObject(sql, TAX_GROUP_MAPPER, id); // 
NOSONAR
+        return taxGroupMapper.map(taxGroupRepository.getReferenceById(id));
     }
 
     @Override
@@ -92,205 +77,12 @@ public class TaxReadPlatformServiceImpl implements 
TaxReadPlatformService {
     }
 
     private Collection<TaxComponentData> retrieveTaxComponentsForLookUp() {
-        String sql = "select " + TAX_COMPONENT_LOOK_UP_MAPPER.getSchema();
-        return this.jdbcTemplate.query(sql, TAX_COMPONENT_LOOK_UP_MAPPER); // 
NOSONAR
+        return taxComponentMapper.map(taxComponentRepository.findAll());
     }
 
     @Override
     public List<TaxGroupData> retrieveTaxGroupsForLookUp() {
-        String sql = "select " + TAX_GROUP_LOOK_UP_MAPPER.getSchema();
-        return this.jdbcTemplate.query(sql, TAX_GROUP_LOOK_UP_MAPPER); // 
NOSONAR
-    }
-
-    private static final class TaxComponentMapper implements 
RowMapper<TaxComponentData> {
-
-        private final String schema;
-        private final TaxComponentHistoryDataMapper componentHistoryDataMapper 
= new TaxComponentHistoryDataMapper();
-
-        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().setId(debitAccountId).setName(debitAccountName).setGlCode(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().setId(creditAccountId).setName(creditAccountName).setGlCode(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();
-
-        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 new TaxGroupData(id, name, taxAssociations, null);
-        }
-
-        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;
-
-        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;
-
-        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);
-        }
-
+        return taxGroupMapper.map(taxGroupRepository.findAll());
     }
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/starter/TaxConfiguration.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/starter/TaxConfiguration.java
index 4c1effb1e8..a5a5aa0296 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/starter/TaxConfiguration.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/starter/TaxConfiguration.java
@@ -25,6 +25,8 @@ import 
org.apache.fineract.portfolio.tax.domain.TaxComponentRepository;
 import org.apache.fineract.portfolio.tax.domain.TaxComponentRepositoryWrapper;
 import org.apache.fineract.portfolio.tax.domain.TaxGroupRepository;
 import org.apache.fineract.portfolio.tax.domain.TaxGroupRepositoryWrapper;
+import org.apache.fineract.portfolio.tax.mapper.TaxComponentMapper;
+import org.apache.fineract.portfolio.tax.mapper.TaxGroupMapper;
 import org.apache.fineract.portfolio.tax.serialization.TaxValidator;
 import org.apache.fineract.portfolio.tax.service.TaxAssembler;
 import org.apache.fineract.portfolio.tax.service.TaxReadPlatformService;
@@ -34,7 +36,6 @@ import 
org.apache.fineract.portfolio.tax.service.TaxWritePlatformServiceImpl;
 import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.jdbc.core.JdbcTemplate;
 
 @Configuration
 public class TaxConfiguration {
@@ -48,9 +49,11 @@ public class TaxConfiguration {
 
     @Bean
     @ConditionalOnMissingBean(TaxReadPlatformService.class)
-    public TaxReadPlatformService taxReadPlatformService(JdbcTemplate 
jdbcTemplate,
+    public TaxReadPlatformService taxReadPlatformService(final 
TaxComponentRepository taxComponentRepository,
+            final TaxComponentMapper taxComponentMapper, final 
TaxGroupRepository taxGroupRepository, final TaxGroupMapper taxGroupMapper,
             AccountingDropdownReadPlatformService 
accountingDropdownReadPlatformService) {
-        return new TaxReadPlatformServiceImpl(jdbcTemplate, 
accountingDropdownReadPlatformService);
+        return new 
TaxReadPlatformServiceImpl(accountingDropdownReadPlatformService, 
taxComponentRepository, taxComponentMapper,
+                taxGroupRepository, taxGroupMapper);
     }
 
     @Bean
diff --git 
a/fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm 
b/fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm
index 028496e876..690f353303 100644
--- a/fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm
+++ b/fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm
@@ -44729,7 +44729,7 @@ No Request Body:
                                                        </td>
                                                </tr>
                                                <tr class=alt>
-                                                       <td>debitAcountId</td>
+                                                       <td>debitAccountId</td>
                                                </tr>
                                                <tr>
                                                        <td class=fielddesc>
@@ -44742,7 +44742,7 @@ No Request Body:
                                                        </td>
                                                </tr>
                                                <tr class=alt>
-                                                       <td>debitAcountId</td>
+                                                       <td>debitAccountId</td>
                                                </tr>
                                                <tr>
                                                        <td class=fielddesc>
@@ -44786,13 +44786,13 @@ No Request Body:
                                                        
<td>debitAccountType</td>
                                                </tr>
                                                <tr class=alt>
-                                                       <td>debitAcountId</td>
+                                                       <td>debitAccountId</td>
                                                </tr>
                                                <tr class=alt>
                                                        
<td>creditAccountType</td>
                                                </tr>
                                                <tr class=alt>
-                                                       <td>creditAcountId</td>
+                                                       <td>creditAccountId</td>
                                                </tr>
                                                <tr class=alt>
                                                        <td>startDate</td>
@@ -44811,7 +44811,7 @@ No Request Body:
                                                "name": "tax component 1",
                                                "percentage": "10",
                                                "creditAccountType": 2,
-                                               "creditAcountId": 4,
+                                               "creditAccountId": 4,
                                                "locale": "en",
                                                "dateFormat": "dd MMMM yyyy",
                                                "startDate": "11 April 2016"
diff --git 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxApiConstants.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxApiConstants.java
index ee8e78f5f8..7487a5d941 100644
--- 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxApiConstants.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxApiConstants.java
@@ -23,9 +23,9 @@ public interface TaxApiConstants {
     String nameParamName = "name";
     String percentageParamName = "percentage";
     String debitAccountTypeParamName = "debitAccountType";
-    String debitAcountIdParamName = "debitAcountId";
+    String debitAccountIdParamName = "debitAccountId";
     String creditAccountTypeParamName = "creditAccountType";
-    String creditAcountIdParamName = "creditAcountId";
+    String creditAccountIdParamName = "creditAccountId";
 
     String startDateParamName = "startDate";
     String endDateParamName = "endDate";
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResource.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResource.java
similarity index 98%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResource.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResource.java
index 5429c36847..6bcb381569 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResource.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResource.java
@@ -99,7 +99,7 @@ public class TaxComponentApiResource {
     @Produces({ MediaType.APPLICATION_JSON })
     @Operation(summary = "Create a new Tax Component", description = "Creates 
a new Tax Component\n\n"
             + "Mandatory Fields: name, percentage\n\n"
-            + "Optional Fields: debitAccountType, debitAcountId, 
creditAccountType, creditAcountId, startDate")
+            + "Optional Fields: debitAccountType, debitAccountId, 
creditAccountType, creditAccountId, startDate")
     @RequestBody(required = true, content = @Content(schema = 
@Schema(implementation = 
TaxComponentApiResourceSwagger.PostTaxesComponentsRequest.class)))
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "OK", content = 
@Content(schema = @Schema(implementation = 
TaxComponentApiResourceSwagger.PostTaxesComponentsResponse.class))) })
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResourceSwagger.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResourceSwagger.java
similarity index 96%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResourceSwagger.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResourceSwagger.java
index d2caece1ac..9b9bcc78ee 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResourceSwagger.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxComponentApiResourceSwagger.java
@@ -86,9 +86,13 @@ final class TaxComponentApiResourceSwagger {
         @Schema(example = "10")
         public Float percentage;
         @Schema(example = "2")
+        public Integer debitAccountType;
+        @Schema(example = "4")
+        public Long debitAccountId;
+        @Schema(example = "4")
         public Integer creditAccountType;
         @Schema(example = "4")
-        public Long creditAcountId;
+        public Long creditAccountId;
         @Schema(example = "en")
         public String locale;
         @Schema(example = "dd MMMM yyyy")
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResource.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResource.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResource.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResource.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResourceSwagger.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResourceSwagger.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResourceSwagger.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/api/TaxGroupApiResourceSwagger.java
diff --git 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java
index ac0d0a0ef4..bc7498aaec 100644
--- 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java
@@ -35,6 +35,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import lombok.Getter;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.accounting.glaccount.domain.GLAccount;
 import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
@@ -44,6 +45,7 @@ import 
org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.portfolio.tax.api.TaxApiConstants;
 
 @Entity
+@Getter
 @Table(name = "m_tax_component")
 public class TaxComponent extends AbstractAuditableCustom {
 
@@ -58,14 +60,14 @@ public class TaxComponent extends AbstractAuditableCustom {
 
     @ManyToOne
     @JoinColumn(name = "debit_account_id")
-    private GLAccount debitAcount;
+    private GLAccount debitAccount;
 
     @Column(name = "credit_account_type_enum")
     private Integer creditAccountType;
 
     @ManyToOne
     @JoinColumn(name = "credit_account_id")
-    private GLAccount creditAcount;
+    private GLAccount creditAccount;
 
     @Column(name = "start_date", nullable = false)
     private LocalDate startDate;
@@ -81,24 +83,24 @@ public class TaxComponent extends AbstractAuditableCustom {
 
     }
 
-    private TaxComponent(final String name, final BigDecimal percentage, final 
GLAccountType debitAccountType, final GLAccount debitAcount,
-            final GLAccountType creditAccountType, final GLAccount 
creditAcount, final LocalDate startDate) {
+    private TaxComponent(final String name, final BigDecimal percentage, final 
GLAccountType debitAccountType, final GLAccount debitAccount,
+            final GLAccountType creditAccountType, final GLAccount 
creditAccount, final LocalDate startDate) {
         this.name = name;
         this.percentage = percentage;
         if (debitAccountType != null) {
             this.debitAccountType = debitAccountType.getValue();
         }
-        this.debitAcount = debitAcount;
+        this.debitAccount = debitAccount;
         if (creditAccountType != null) {
             this.creditAccountType = creditAccountType.getValue();
         }
-        this.creditAcount = creditAcount;
+        this.creditAccount = creditAccount;
         this.startDate = startDate;
     }
 
     public static TaxComponent createTaxComponent(final String name, final 
BigDecimal percentage, final GLAccountType debitAccountType,
-            final GLAccount debitAcount, final GLAccountType 
creditAccountType, final GLAccount creditAcount, final LocalDate startDate) {
-        return new TaxComponent(name, percentage, debitAccountType, 
debitAcount, creditAccountType, creditAcount, startDate);
+            final GLAccount debitAccount, final GLAccountType 
creditAccountType, final GLAccount creditAccount, final LocalDate startDate) {
+        return new TaxComponent(name, percentage, debitAccountType, 
debitAccount, creditAccountType, creditAccount, startDate);
     }
 
     public Map<String, Object> update(final JsonCommand command) {
@@ -193,7 +195,7 @@ public class TaxComponent extends AbstractAuditableCustom {
     }
 
     public GLAccount getDebitAcount() {
-        return this.debitAcount;
+        return this.debitAccount;
     }
 
     public Integer getCreditAccountType() {
@@ -201,6 +203,6 @@ public class TaxComponent extends AbstractAuditableCustom {
     }
 
     public GLAccount getCreditAcount() {
-        return this.creditAcount;
+        return this.creditAccount;
     }
 }
diff --git 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java
index ff95a1abd8..181d681ccb 100644
--- 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java
@@ -27,11 +27,13 @@ import java.time.LocalDate;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import lombok.Getter;
 import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.portfolio.tax.api.TaxApiConstants;
 
 @Entity
+@Getter
 @Table(name = "m_tax_group_mappings")
 public class TaxGroupMappings extends AbstractAuditableCustom {
 
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java
similarity index 86%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java
index cabf0caf81..96b045767f 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java
@@ -18,25 +18,21 @@
  */
 package org.apache.fineract.portfolio.tax.handler;
 
+import lombok.AllArgsConstructor;
 import org.apache.fineract.commands.annotation.CommandType;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.portfolio.tax.service.TaxWritePlatformService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
+@AllArgsConstructor
 @CommandType(entity = "TAXCOMPONENT", action = "CREATE")
 public class CreateTaxComponentCommandHandler implements 
NewCommandSourceHandler {
 
     private final TaxWritePlatformService taxWritePlatformService;
 
-    @Autowired
-    public CreateTaxComponentCommandHandler(final TaxWritePlatformService 
taxWritePlatformService) {
-        this.taxWritePlatformService = taxWritePlatformService;
-    }
-
     @Override
     public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
         return this.taxWritePlatformService.createTaxComponent(jsonCommand);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java
similarity index 86%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java
index e5b523d9ef..2da805e27e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java
@@ -18,25 +18,21 @@
  */
 package org.apache.fineract.portfolio.tax.handler;
 
+import lombok.AllArgsConstructor;
 import org.apache.fineract.commands.annotation.CommandType;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.portfolio.tax.service.TaxWritePlatformService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
+@AllArgsConstructor
 @CommandType(entity = "TAXGROUP", action = "CREATE")
 public class CreateTaxGroupCommandHandler implements NewCommandSourceHandler {
 
     private final TaxWritePlatformService taxWritePlatformService;
 
-    @Autowired
-    public CreateTaxGroupCommandHandler(final TaxWritePlatformService 
taxWritePlatformService) {
-        this.taxWritePlatformService = taxWritePlatformService;
-    }
-
     @Override
     public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
         return this.taxWritePlatformService.createTaxGroup(jsonCommand);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java
similarity index 86%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java
index b94e369f20..15d6572052 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java
@@ -18,25 +18,21 @@
  */
 package org.apache.fineract.portfolio.tax.handler;
 
+import lombok.AllArgsConstructor;
 import org.apache.fineract.commands.annotation.CommandType;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.portfolio.tax.service.TaxWritePlatformService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
+@AllArgsConstructor
 @CommandType(entity = "TAXCOMPONENT", action = "UPDATE")
 public class UpdateTaxComponentCommandHandler implements 
NewCommandSourceHandler {
 
     private final TaxWritePlatformService taxWritePlatformService;
 
-    @Autowired
-    public UpdateTaxComponentCommandHandler(final TaxWritePlatformService 
taxWritePlatformService) {
-        this.taxWritePlatformService = taxWritePlatformService;
-    }
-
     @Override
     public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
         return 
this.taxWritePlatformService.updateTaxComponent(jsonCommand.entityId(), 
jsonCommand);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java
similarity index 87%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java
index 1229e460d7..d7f1105990 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java
@@ -18,25 +18,21 @@
  */
 package org.apache.fineract.portfolio.tax.handler;
 
+import lombok.AllArgsConstructor;
 import org.apache.fineract.commands.annotation.CommandType;
 import org.apache.fineract.commands.handler.NewCommandSourceHandler;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
 import org.apache.fineract.portfolio.tax.service.TaxWritePlatformService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
+@AllArgsConstructor
 @CommandType(entity = "TAXGROUP", action = "UPDATE")
 public class UpdateTaxGroupCommandHandler implements NewCommandSourceHandler {
 
     private final TaxWritePlatformService taxWritePlatformService;
 
-    @Autowired
-    public UpdateTaxGroupCommandHandler(final TaxWritePlatformService 
taxWritePlatformService) {
-        this.taxWritePlatformService = taxWritePlatformService;
-    }
-
     @Override
     public CommandProcessingResult processCommand(JsonCommand jsonCommand) {
         return 
this.taxWritePlatformService.updateTaxGroup(jsonCommand.entityId(), 
jsonCommand);
diff --git 
a/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxComponentMapper.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxComponentMapper.java
new file mode 100644
index 0000000000..939d4e8387
--- /dev/null
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxComponentMapper.java
@@ -0,0 +1,44 @@
+/**
+ * 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.mapper;
+
+import java.util.List;
+import org.apache.fineract.accounting.glaccount.mapper.GlAccountMapper;
+import org.apache.fineract.accounting.glaccount.mapper.GlAccountTypeMapper;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.portfolio.tax.data.TaxComponentData;
+import org.apache.fineract.portfolio.tax.domain.TaxComponent;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+
+@Mapper(config = MapstructMapperConfig.class, uses = { GlAccountMapper.class, 
GlAccountTypeMapper.class })
+public interface TaxComponentMapper {
+
+    @Mapping(target = "creditAccount", source = "taxComponent.creditAccount")
+    @Mapping(target = "debitAccount", source = "taxComponent.debitAccount")
+    @Mapping(target = "creditAccountType", source = 
"taxComponent.creditAccountType")
+    @Mapping(target = "debitAccountType", source = 
"taxComponent.debitAccountType")
+    @Mapping(target = "glAccountOptions", ignore = true)
+    @Mapping(target = "glAccountTypeOptions", ignore = true)
+    @Mapping(target = "taxComponentHistories", ignore = true)
+    TaxComponentData map(TaxComponent taxComponent);
+
+    List<TaxComponentData> map(List<TaxComponent> taxComponents);
+
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxGroupMapper.java
similarity index 60%
copy from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
copy to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxGroupMapper.java
index 4b61676fb1..3edadeef55 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxGroupMapper.java
@@ -16,28 +16,22 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.tax.service;
+package org.apache.fineract.portfolio.tax.mapper;
 
 import java.util.List;
-import org.apache.fineract.portfolio.tax.data.TaxComponentData;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
 import org.apache.fineract.portfolio.tax.data.TaxGroupData;
+import org.apache.fineract.portfolio.tax.domain.TaxGroup;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 
-public interface TaxReadPlatformService {
+@Mapper(config = MapstructMapperConfig.class, uses = { 
TaxGroupMappingsMapper.class })
+public interface TaxGroupMapper {
 
-    TaxComponentData retrieveTaxComponentData(Long id);
+    @Mapping(target = "taxAssociations", source = "taxGroup.taxGroupMappings")
+    @Mapping(target = "taxComponents", ignore = true)
+    TaxGroupData map(TaxGroup taxGroup);
 
-    TaxComponentData retrieveTaxComponentTemplate();
-
-    TaxGroupData retrieveTaxGroupData(Long id);
-
-    TaxGroupData retrieveTaxGroupWithTemplate(Long id);
-
-    TaxGroupData retrieveTaxGroupTemplate();
-
-    List<TaxComponentData> retrieveAllTaxComponents();
-
-    List<TaxGroupData> retrieveAllTaxGroups();
-
-    List<TaxGroupData> retrieveTaxGroupsForLookUp();
+    List<TaxGroupData> map(List<TaxGroup> taxGroups);
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxGroupMappingsMapper.java
similarity index 58%
copy from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
copy to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxGroupMappingsMapper.java
index 0d96b18fa0..4afc643fe3 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/mapper/TaxGroupMappingsMapper.java
@@ -16,19 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.fineract.portfolio.tax.service;
+package org.apache.fineract.portfolio.tax.mapper;
 
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import java.util.List;
+import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
+import org.apache.fineract.portfolio.tax.data.TaxGroupMappingsData;
+import org.apache.fineract.portfolio.tax.domain.TaxGroupMappings;
+import org.mapstruct.Mapper;
 
-public interface TaxWritePlatformService {
+@Mapper(config = MapstructMapperConfig.class, uses = { 
TaxComponentMapper.class })
+public interface TaxGroupMappingsMapper {
 
-    CommandProcessingResult createTaxComponent(JsonCommand command);
+    TaxGroupMappingsData map(TaxGroupMappings taxGroupMapping);
 
-    CommandProcessingResult updateTaxComponent(Long id, JsonCommand command);
-
-    CommandProcessingResult createTaxGroup(JsonCommand command);
-
-    CommandProcessingResult updateTaxGroup(Long id, JsonCommand command);
+    List<TaxGroupMappingsData> map(List<TaxGroupMappings> taxGroupMappings);
 
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java
similarity index 97%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java
index cbb103ff59..37898b021f 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java
+++ 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java
@@ -63,8 +63,8 @@ public class TaxValidator {
     public static final String COMPONENT_START_DATE = "component.start.date";
     private static final Set<String> SUPPORTED_TAX_COMPONENT_CREATE_PARAMETERS 
= new HashSet<>(
             Arrays.asList(DATE_FORMAT, LOCALE, TaxApiConstants.nameParamName, 
TaxApiConstants.percentageParamName,
-                    TaxApiConstants.startDateParamName, 
TaxApiConstants.debitAccountTypeParamName, 
TaxApiConstants.debitAcountIdParamName,
-                    TaxApiConstants.creditAccountTypeParamName, 
TaxApiConstants.creditAcountIdParamName));
+                    TaxApiConstants.startDateParamName, 
TaxApiConstants.debitAccountTypeParamName, 
TaxApiConstants.debitAccountIdParamName,
+                    TaxApiConstants.creditAccountTypeParamName, 
TaxApiConstants.creditAccountIdParamName));
     private static final Set<String> SUPPORTED_TAX_COMPONENT_UPDATE_PARAMETERS 
= new HashSet<>(Arrays.asList(DATE_FORMAT, LOCALE,
             TaxApiConstants.nameParamName, 
TaxApiConstants.percentageParamName, TaxApiConstants.startDateParamName));
     private static final Set<String> SUPPORTED_TAX_GROUP_PARAMETERS = new 
HashSet<>(
@@ -111,11 +111,11 @@ public class TaxValidator {
                 .isOneOfTheseValues(GLAccountType.ASSET.getValue(), 
GLAccountType.LIABILITY.getValue(), GLAccountType.EQUITY.getValue(),
                         GLAccountType.INCOME.getValue(), 
GLAccountType.EXPENSE.getValue());
 
-        final Long debitAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.debitAcountIdParamName, 
element);
-        
baseDataValidator.reset().parameter(TaxApiConstants.debitAcountIdParamName).value(debitAccountId).longGreaterThanZero();
+        final Long debitAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.debitAccountIdParamName,
 element);
+        
baseDataValidator.reset().parameter(TaxApiConstants.debitAccountIdParamName).value(debitAccountId).longGreaterThanZero();
         if (debitAccountType != null || debitAccountId != null) {
             
baseDataValidator.reset().parameter(TaxApiConstants.debitAccountTypeParamName).value(debitAccountType).notBlank();
-            
baseDataValidator.reset().parameter(TaxApiConstants.debitAcountIdParamName).value(debitAccountId).notBlank();
+            
baseDataValidator.reset().parameter(TaxApiConstants.debitAccountIdParamName).value(debitAccountId).notBlank();
         }
 
         final Integer creditAccountType = 
this.fromApiJsonHelper.extractIntegerSansLocaleNamed(TaxApiConstants.creditAccountTypeParamName,
@@ -124,10 +124,10 @@ public class TaxValidator {
                 .isOneOfTheseValues(GLAccountType.ASSET.getValue(), 
GLAccountType.LIABILITY.getValue(), GLAccountType.EQUITY.getValue(),
                         GLAccountType.INCOME.getValue(), 
GLAccountType.EXPENSE.getValue());
 
-        final Long creditAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.creditAcountIdParamName,
 element);
-        
baseDataValidator.reset().parameter(TaxApiConstants.creditAcountIdParamName).value(creditAccountId).longGreaterThanZero();
+        final Long creditAccountId = 
this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.creditAccountIdParamName,
 element);
+        
baseDataValidator.reset().parameter(TaxApiConstants.creditAccountIdParamName).value(creditAccountId).longGreaterThanZero();
         if (creditAccountType != null || creditAccountId != null) {
-            
baseDataValidator.reset().parameter(TaxApiConstants.creditAcountIdParamName).value(creditAccountId).notBlank();
+            
baseDataValidator.reset().parameter(TaxApiConstants.creditAccountIdParamName).value(creditAccountId).notBlank();
             
baseDataValidator.reset().parameter(TaxApiConstants.creditAccountTypeParamName).value(creditAccountType).notBlank();
         }
         throwExceptionIfValidationWarningsExist(dataValidationErrors);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
 
b/fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
similarity index 100%
rename from 
fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
rename to 
fineract-tax/src/main/java/org/apache/fineract/portfolio/tax/service/TaxWritePlatformService.java
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/TaxesTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/TaxesTest.java
new file mode 100644
index 0000000000..baba20f1d8
--- /dev/null
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/TaxesTest.java
@@ -0,0 +1,117 @@
+/**
+ * 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.integrationtests;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.fineract.client.models.GetTaxesComponentsResponse;
+import org.apache.fineract.client.models.GetTaxesGroupResponse;
+import org.apache.fineract.client.models.GetTaxesGroupTaxAssociations;
+import org.apache.fineract.client.models.PostTaxesComponentsRequest;
+import org.apache.fineract.client.models.PostTaxesComponentsResponse;
+import org.apache.fineract.client.models.PostTaxesGroupRequest;
+import org.apache.fineract.client.models.PostTaxesGroupResponse;
+import org.apache.fineract.client.models.PostTaxesGroupTaxComponents;
+import org.apache.fineract.integrationtests.common.TaxComponentHelper;
+import org.apache.fineract.integrationtests.common.TaxGroupHelper;
+import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.accounting.Account;
+import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class TaxesTest {
+
+    @Test
+    public void createTaxComponentTest() {
+        Long taxComponentId = 
createTaxComponentWithLiabilityToCredit("taxComponent");
+
+        GetTaxesComponentsResponse taxComponentDetails = 
TaxComponentHelper.retrieveTaxComponent(taxComponentId);
+        Assertions.assertNotNull(taxComponentDetails);
+        Assertions.assertNotNull(taxComponentDetails.getId());
+        Assertions.assertEquals(taxComponentId, taxComponentDetails.getId());
+
+        taxComponentId = 
createTaxComponentWithLiabilityToDebit("taxComponent");
+
+        taxComponentDetails = 
TaxComponentHelper.retrieveTaxComponent(taxComponentId);
+        Assertions.assertNotNull(taxComponentDetails);
+        Assertions.assertNotNull(taxComponentDetails.getId());
+        Assertions.assertEquals(taxComponentId, taxComponentDetails.getId());
+    }
+
+    @Test
+    public void createTaxGroupTest() {
+        List<GetTaxesGroupResponse> allTaxGroups = 
TaxGroupHelper.retrieveAllTaxGroups();
+        Assertions.assertNotNull(allTaxGroups);
+
+        final Long taxComponentId = 
createTaxComponentWithLiabilityToCredit("taxComponent");
+
+        final Set<PostTaxesGroupTaxComponents> taxComponentsSet = new 
HashSet<>();
+        taxComponentsSet.add(new 
PostTaxesGroupTaxComponents().taxComponentId(taxComponentId).startDate("01 
January 2023"));
+        final PostTaxesGroupRequest taxGroupRequest = new 
PostTaxesGroupRequest().name(Utils.randomStringGenerator("TAX_GRP_", 4))
+                .taxComponents(taxComponentsSet).dateFormat("dd MMMM 
yyyy").locale("en");
+        final PostTaxesGroupResponse taxGroupResponse = 
TaxGroupHelper.createTaxGroup(taxGroupRequest);
+        Assertions.assertNotNull(taxGroupResponse);
+        Assertions.assertNotNull(taxGroupResponse.getResourceId());
+
+        final GetTaxesGroupResponse taxGroupDetails = 
TaxGroupHelper.retrieveTaxGroup(taxGroupResponse.getResourceId());
+        Assertions.assertNotNull(taxGroupDetails);
+        Assertions.assertEquals(taxGroupResponse.getResourceId(), 
taxGroupDetails.getId());
+        Assertions.assertFalse(taxGroupDetails.getTaxAssociations().isEmpty());
+        GetTaxesGroupTaxAssociations taxAssociation = 
taxGroupDetails.getTaxAssociations().iterator().next();
+        Assertions.assertNotNull(taxAssociation);
+        Assertions.assertEquals(taxComponentId, 
taxAssociation.getTaxComponent().getId());
+
+        allTaxGroups = TaxGroupHelper.retrieveAllTaxGroups();
+        Assertions.assertNotNull(allTaxGroups);
+        Assertions.assertTrue(allTaxGroups.size() > 0);
+    }
+
+    private Long createTaxComponentWithLiabilityToCredit(final String 
taxComponentPrefix) {
+        final Account taxComponentGlAccount = 
AccountHelper.createLiabilityGlAccount(taxComponentPrefix);
+
+        final PostTaxesComponentsRequest taxComponentRequest = new 
PostTaxesComponentsRequest()
+                .name(Utils.randomStringGenerator(taxComponentPrefix, 
4)).percentage(12.0f).startDate("01 January 2023")
+                
.creditAccountType(Integer.valueOf(taxComponentGlAccount.getAccountType().toString()))
+                
.creditAccountId(taxComponentGlAccount.getAccountID().longValue()).dateFormat(Utils.DATE_FORMAT).locale(Utils.LOCALE);
+
+        final PostTaxesComponentsResponse taxComponentRespose = 
TaxComponentHelper.createTaxComponent(taxComponentRequest);
+        Assertions.assertNotNull(taxComponentRespose);
+        Assertions.assertNotNull(taxComponentRespose.getResourceId());
+
+        return taxComponentRespose.getResourceId();
+    }
+
+    private Long createTaxComponentWithLiabilityToDebit(final String 
taxComponentPrefix) {
+        final Account taxComponentGlAccount = 
AccountHelper.createLiabilityGlAccount(taxComponentPrefix);
+
+        final PostTaxesComponentsRequest taxComponentRequest = new 
PostTaxesComponentsRequest()
+                .name(Utils.randomStringGenerator(taxComponentPrefix, 
4)).percentage(12.0f).startDate("01 January 2023")
+                
.debitAccountType(Integer.valueOf(taxComponentGlAccount.getAccountType().toString()))
+                
.debitAccountId(taxComponentGlAccount.getAccountID().longValue()).dateFormat(Utils.DATE_FORMAT).locale(Utils.LOCALE);
+
+        final PostTaxesComponentsResponse taxComponentRespose = 
TaxComponentHelper.createTaxComponent(taxComponentRequest);
+        Assertions.assertNotNull(taxComponentRespose);
+        Assertions.assertNotNull(taxComponentRespose.getResourceId());
+
+        return taxComponentRespose.getResourceId();
+    }
+
+}
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxComponentHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxComponentHelper.java
index 3a363e0d24..36181c272e 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxComponentHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxComponentHelper.java
@@ -22,6 +22,7 @@ import com.google.gson.Gson;
 import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.util.HashMap;
+import org.apache.fineract.client.models.GetTaxesComponentsResponse;
 import org.apache.fineract.client.models.PostTaxesComponentsRequest;
 import org.apache.fineract.client.models.PostTaxesComponentsResponse;
 import org.apache.fineract.client.util.Calls;
@@ -57,7 +58,7 @@ public final class TaxComponentHelper {
         final HashMap<String, String> map = 
getBasicTaxComponentMap(percentage);
         if (creditAccountId != null) {
             map.put("creditAccountType", 
Account.AccountType.LIABILITY.toString());
-            map.put("creditAcountId", String.valueOf(creditAccountId));
+            map.put("creditAccountId", String.valueOf(creditAccountId));
         }
         LOG.info("map :  {}", map);
         return new Gson().toJson(map);
@@ -81,4 +82,8 @@ public final class TaxComponentHelper {
         return 
Calls.ok(FineractClientHelper.getFineractClient().taxComponents.createTaxComponent(request));
     }
 
+    public static GetTaxesComponentsResponse retrieveTaxComponent(Long 
taxComponentId) {
+        return 
Calls.ok(FineractClientHelper.getFineractClient().taxComponents.retrieveTaxComponent(taxComponentId));
+    }
+
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxGroupHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxGroupHelper.java
index c1c38fe592..e6e772b212 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxGroupHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/TaxGroupHelper.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
+import org.apache.fineract.client.models.GetTaxesGroupResponse;
 import org.apache.fineract.client.models.PostTaxesGroupRequest;
 import org.apache.fineract.client.models.PostTaxesGroupResponse;
 import org.apache.fineract.client.util.Calls;
@@ -91,4 +92,12 @@ public final class TaxGroupHelper {
         return 
Calls.ok(FineractClientHelper.getFineractClient().taxGroups.createTaxGroup(request));
     }
 
+    public static GetTaxesGroupResponse retrieveTaxGroup(Long taxGroupId) {
+        return 
Calls.ok(FineractClientHelper.getFineractClient().taxGroups.retrieveTaxGroup(taxGroupId));
+    }
+
+    public static List<GetTaxesGroupResponse> retrieveAllTaxGroups() {
+        return 
Calls.ok(FineractClientHelper.getFineractClient().taxGroups.retrieveAllTaxGroups());
+    }
+
 }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
index d492e05276..be95c3cfd2 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
@@ -88,6 +88,7 @@ public final class Utils {
     public static final String TENANT_TIME_ZONE = "Asia/Kolkata";
     public static final String DATE_FORMAT = "dd MMMM yyyy";
     public static final String DATE_TIME_FORMAT = "dd MMMM yyyy HH:mm";
+    public static final String LOCALE = "en";
     public static final DateTimeFormatter dateFormatter = new 
DateTimeFormatterBuilder().appendPattern(DATE_FORMAT).toFormatter();
     public static final DateTimeFormatter dateTimeFormatter = new 
DateTimeFormatterBuilder().appendPattern(DATE_TIME_FORMAT).toFormatter();
     private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
index f00279e9d8..42e2820690 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
@@ -21,7 +21,9 @@ package 
org.apache.fineract.integrationtests.common.accounting;
 import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.HashMap;
+import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
 import org.apache.fineract.client.models.DeleteGLAccountsResponse;
 import org.apache.fineract.client.models.GetGLAccountsResponse;
 import org.apache.fineract.client.models.PostGLAccountsRequest;
@@ -31,6 +33,7 @@ import 
org.apache.fineract.client.models.PutGLAccountsResponse;
 import org.apache.fineract.client.util.Calls;
 import org.apache.fineract.integrationtests.common.FineractClientHelper;
 import org.apache.fineract.integrationtests.common.Utils;
+import org.junit.jupiter.api.Assertions;
 
 @SuppressWarnings("rawtypes")
 public class AccountHelper {
@@ -161,4 +164,49 @@ public class AccountHelper {
     public static GetGLAccountsResponse getGLAccount(final Long glAccountId) {
         return 
Calls.ok(FineractClientHelper.getFineractClient().glAccounts.retreiveAccount(glAccountId,
 false));
     }
+
+    public static Account createAssetGlAccount(final String glAccountName) {
+        PostGLAccountsResponse postGLAccountsResponse = createGLAccount(
+                createGlAccount(GLAccountType.ASSET, 
Utils.uniqueRandomStringGenerator(glAccountName, 6), null));
+        Assertions.assertNotNull(postGLAccountsResponse);
+        return new Account(postGLAccountsResponse.getResourceId().intValue(), 
Account.AccountType.ASSET);
+    }
+
+    public static Account createLiabilityGlAccount(final String glAccountName) 
{
+        PostGLAccountsResponse postGLAccountsResponse = createGLAccount(
+                createGlAccount(GLAccountType.LIABILITY, 
Utils.uniqueRandomStringGenerator(glAccountName, 6), null));
+        Assertions.assertNotNull(postGLAccountsResponse);
+        return new Account(postGLAccountsResponse.getResourceId().intValue(), 
Account.AccountType.LIABILITY);
+    }
+
+    public static Account createIncomeGlAccount(final String glAccountName) {
+        PostGLAccountsResponse postGLAccountsResponse = createGLAccount(
+                createGlAccount(GLAccountType.INCOME, 
Utils.uniqueRandomStringGenerator(glAccountName, 6), null));
+        Assertions.assertNotNull(postGLAccountsResponse);
+        return new Account(postGLAccountsResponse.getResourceId().intValue(), 
Account.AccountType.INCOME);
+    }
+
+    public static Account createExpenseGlAccount(final String glAccountName) {
+        PostGLAccountsResponse postGLAccountsResponse = createGLAccount(
+                createGlAccount(GLAccountType.EXPENSE, 
Utils.uniqueRandomStringGenerator(glAccountName, 6), null));
+        Assertions.assertNotNull(postGLAccountsResponse);
+        return new Account(postGLAccountsResponse.getResourceId().intValue(), 
Account.AccountType.EXPENSE);
+    }
+
+    public static Account createEquityGlAccount(final String glAccountName) {
+        PostGLAccountsResponse postGLAccountsResponse = createGLAccount(
+                createGlAccount(GLAccountType.EQUITY, 
Utils.uniqueRandomStringGenerator(glAccountName, 6), null));
+        Assertions.assertNotNull(postGLAccountsResponse);
+        return new Account(postGLAccountsResponse.getResourceId().intValue(), 
Account.AccountType.EQUITY);
+    }
+
+    public static PostGLAccountsRequest createGlAccount(final GLAccountType 
glAccountType, final String glAccountName,
+            final Long parentAccountId) {
+        return new 
PostGLAccountsRequest().type(glAccountType.getValue()).glCode(createGlCode(glAccountType)).manualEntriesAllowed(true)
+                
.usage(1).parentId(parentAccountId).description(glAccountName).name(glAccountName);
+    }
+
+    public static String createGlCode(final GLAccountType glAccountType) {
+        return 
Utils.uniqueRandomStringGenerator(glAccountType.getValue().toString() + 
Calendar.getInstance().getTimeInMillis(), 2);
+    }
 }

Reply via email to