FINERACT-1932: Fineract modularization - fineract-tax
This commit is contained in:
committed by
Adam Saghy
parent
35ff4363a8
commit
0292171f6f
-38
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* 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.api;
|
||||
|
||||
public interface TaxApiConstants {
|
||||
|
||||
String nameParamName = "name";
|
||||
String percentageParamName = "percentage";
|
||||
String debitAccountTypeParamName = "debitAccountType";
|
||||
String debitAcountIdParamName = "debitAcountId";
|
||||
String creditAccountTypeParamName = "creditAccountType";
|
||||
String creditAcountIdParamName = "creditAcountId";
|
||||
|
||||
String startDateParamName = "startDate";
|
||||
String endDateParamName = "endDate";
|
||||
|
||||
String chargeIncludesTaxParamName = "chargeIncludesTax";
|
||||
String taxComponentsParamName = "taxComponents";
|
||||
String idParamName = "id";
|
||||
String taxComponentIdParamName = "taxComponentId";
|
||||
|
||||
}
|
||||
-206
@@ -1,206 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
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
|
||||
@Table(name = "m_tax_component")
|
||||
public class TaxComponent extends AbstractAuditableCustom {
|
||||
|
||||
@Column(name = "name", length = 100)
|
||||
private String name;
|
||||
|
||||
@Column(name = "percentage", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal percentage;
|
||||
|
||||
@Column(name = "debit_account_type_enum")
|
||||
private Integer debitAccountType;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "debit_account_id")
|
||||
private GLAccount debitAcount;
|
||||
|
||||
@Column(name = "credit_account_type_enum")
|
||||
private Integer creditAccountType;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "credit_account_id")
|
||||
private GLAccount creditAcount;
|
||||
|
||||
@Column(name = "start_date", nullable = false)
|
||||
private LocalDate startDate;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "tax_component_id", referencedColumnName = "id", nullable = false)
|
||||
private Set<TaxComponentHistory> taxComponentHistories = new HashSet<>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.DETACH, mappedBy = "taxComponent", orphanRemoval = false, fetch = FetchType.EAGER)
|
||||
private Set<TaxGroupMappings> taxGroupMappings = new HashSet<>();
|
||||
|
||||
protected TaxComponent() {
|
||||
|
||||
}
|
||||
|
||||
private TaxComponent(final String name, final BigDecimal percentage, final GLAccountType debitAccountType, final GLAccount debitAcount,
|
||||
final GLAccountType creditAccountType, final GLAccount creditAcount, final LocalDate startDate) {
|
||||
this.name = name;
|
||||
this.percentage = percentage;
|
||||
if (debitAccountType != null) {
|
||||
this.debitAccountType = debitAccountType.getValue();
|
||||
}
|
||||
this.debitAcount = debitAcount;
|
||||
if (creditAccountType != null) {
|
||||
this.creditAccountType = creditAccountType.getValue();
|
||||
}
|
||||
this.creditAcount = creditAcount;
|
||||
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);
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command) {
|
||||
final Map<String, Object> changes = new HashMap<>();
|
||||
|
||||
if (command.isChangeInStringParameterNamed(TaxApiConstants.nameParamName, this.name)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(TaxApiConstants.nameParamName);
|
||||
changes.put(TaxApiConstants.nameParamName, newValue);
|
||||
this.name = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
if (command.isChangeInBigDecimalParameterNamed(TaxApiConstants.percentageParamName, this.percentage)) {
|
||||
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(TaxApiConstants.percentageParamName);
|
||||
changes.put(TaxApiConstants.percentageParamName, newValue);
|
||||
|
||||
LocalDate oldStartDate = this.startDate;
|
||||
updateStartDate(command, changes, true);
|
||||
LocalDate newStartDate = this.startDate;
|
||||
|
||||
TaxComponentHistory history = TaxComponentHistory.createTaxComponentHistory(this.percentage, oldStartDate, newStartDate);
|
||||
this.taxComponentHistories.add(history);
|
||||
this.percentage = newValue;
|
||||
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
private void updateStartDate(final JsonCommand command, final Map<String, Object> changes, boolean setAsCurrentDate) {
|
||||
LocalDate startDate = DateUtils.getBusinessLocalDate();
|
||||
if (command.parameterExists(TaxApiConstants.startDateParamName)) {
|
||||
LocalDate startDateFromUI = command.localDateValueOfParameterNamed(TaxApiConstants.startDateParamName);
|
||||
if (startDateFromUI != null) {
|
||||
startDate = startDateFromUI;
|
||||
}
|
||||
this.startDate = startDate;
|
||||
changes.put(TaxApiConstants.startDateParamName, startDate);
|
||||
} else if (setAsCurrentDate) {
|
||||
changes.put(TaxApiConstants.startDateParamName, startDate);
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BigDecimal getPercentage() {
|
||||
return this.percentage;
|
||||
}
|
||||
|
||||
public LocalDate startDate() {
|
||||
return this.startDate;
|
||||
}
|
||||
|
||||
public BigDecimal getApplicablePercentage(final LocalDate date) {
|
||||
BigDecimal percentage = null;
|
||||
if (occursOnDayFrom(date)) {
|
||||
percentage = getPercentage();
|
||||
} else {
|
||||
for (TaxComponentHistory componentHistory : taxComponentHistories) {
|
||||
if (componentHistory.occursOnDayFromAndUpToAndIncluding(date)) {
|
||||
percentage = componentHistory.getPercentage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return percentage;
|
||||
}
|
||||
|
||||
private boolean occursOnDayFrom(final LocalDate target) {
|
||||
return DateUtils.isAfter(target, startDate());
|
||||
}
|
||||
|
||||
public Set<TaxComponentHistory> getTaxComponentHistories() {
|
||||
return this.taxComponentHistories;
|
||||
}
|
||||
|
||||
public Set<TaxGroupMappings> getTaxGroupMappings() {
|
||||
return this.taxGroupMappings;
|
||||
}
|
||||
|
||||
public Collection<LocalDate> allStartDates() {
|
||||
List<LocalDate> dates = new ArrayList<>();
|
||||
dates.add(startDate());
|
||||
for (TaxComponentHistory componentHistory : taxComponentHistories) {
|
||||
dates.add(componentHistory.startDate());
|
||||
}
|
||||
|
||||
return dates;
|
||||
}
|
||||
|
||||
public Integer getDebitAccountType() {
|
||||
return this.debitAccountType;
|
||||
}
|
||||
|
||||
public GLAccount getDebitAcount() {
|
||||
return this.debitAcount;
|
||||
}
|
||||
|
||||
public Integer getCreditAccountType() {
|
||||
return this.creditAccountType;
|
||||
}
|
||||
|
||||
public GLAccount getCreditAcount() {
|
||||
return this.creditAcount;
|
||||
}
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_tax_component_history")
|
||||
public class TaxComponentHistory extends AbstractAuditableCustom {
|
||||
|
||||
@Column(name = "percentage", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal percentage;
|
||||
|
||||
@Column(name = "start_date", nullable = false)
|
||||
private LocalDate startDate;
|
||||
|
||||
@Column(name = "end_date", nullable = false)
|
||||
private LocalDate endDate;
|
||||
|
||||
protected TaxComponentHistory() {
|
||||
|
||||
}
|
||||
|
||||
private TaxComponentHistory(final BigDecimal percentage, final LocalDate startDate, final LocalDate endDate) {
|
||||
this.percentage = percentage;
|
||||
this.startDate = startDate;
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public static TaxComponentHistory createTaxComponentHistory(final BigDecimal percentage, final LocalDate startDate,
|
||||
final LocalDate endDate) {
|
||||
return new TaxComponentHistory(percentage, startDate, endDate);
|
||||
}
|
||||
|
||||
public LocalDate startDate() {
|
||||
return this.startDate;
|
||||
}
|
||||
|
||||
public LocalDate endDate() {
|
||||
return this.endDate;
|
||||
}
|
||||
|
||||
public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) {
|
||||
return DateUtils.isAfter(target, startDate()) && (endDate == null || !DateUtils.isAfter(target, endDate()));
|
||||
}
|
||||
|
||||
public BigDecimal getPercentage() {
|
||||
return this.percentage;
|
||||
}
|
||||
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface TaxComponentRepository extends JpaRepository<TaxComponent, Long>, JpaSpecificationExecutor<TaxComponent> {
|
||||
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import org.apache.fineract.portfolio.tax.exception.TaxComponentNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TaxComponentRepositoryWrapper {
|
||||
|
||||
private final TaxComponentRepository repository;
|
||||
|
||||
@Autowired
|
||||
public TaxComponentRepositoryWrapper(final TaxComponentRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public TaxComponent findOneWithNotFoundDetection(final Long id) {
|
||||
return this.repository.findById(id).orElseThrow(() -> new TaxComponentNotFoundException(id));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||
import org.apache.fineract.portfolio.tax.api.TaxApiConstants;
|
||||
import org.apache.fineract.portfolio.tax.exception.TaxMappingNotFoundException;
|
||||
|
||||
@Entity
|
||||
@Table(name = "m_tax_group")
|
||||
public class TaxGroup extends AbstractAuditableCustom {
|
||||
|
||||
@Column(name = "name", length = 100)
|
||||
private String name;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "taxGroup")
|
||||
private Set<TaxGroupMappings> taxGroupMappings = new HashSet<>();
|
||||
|
||||
protected TaxGroup() {
|
||||
|
||||
}
|
||||
|
||||
private TaxGroup(final String name, final Set<TaxGroupMappings> taxGroupMappings) {
|
||||
this.name = name;
|
||||
this.taxGroupMappings = taxGroupMappings;
|
||||
taxGroupMappings.forEach(m -> m.setTaxGroup(this));
|
||||
}
|
||||
|
||||
public static TaxGroup createTaxGroup(final String name, final Set<TaxGroupMappings> taxGroupMappings) {
|
||||
return new TaxGroup(name, taxGroupMappings);
|
||||
}
|
||||
|
||||
public Map<String, Object> update(final JsonCommand command, final Set<TaxGroupMappings> taxGroupMappings) {
|
||||
final Map<String, Object> changes = new HashMap<>();
|
||||
|
||||
if (command.isChangeInStringParameterNamed(TaxApiConstants.nameParamName, this.name)) {
|
||||
final String newValue = command.stringValueOfParameterNamed(TaxApiConstants.nameParamName);
|
||||
changes.put(TaxApiConstants.nameParamName, newValue);
|
||||
this.name = StringUtils.defaultIfEmpty(newValue, null);
|
||||
}
|
||||
|
||||
List<Long> taxComponentList = new ArrayList<>();
|
||||
final List<Map<String, Object>> modifications = new ArrayList<>();
|
||||
|
||||
for (TaxGroupMappings groupMappings : taxGroupMappings) {
|
||||
TaxGroupMappings mappings = findOneBy(groupMappings);
|
||||
if (mappings == null) {
|
||||
this.taxGroupMappings.add(groupMappings);
|
||||
taxComponentList.add(groupMappings.getTaxComponent().getId());
|
||||
} else {
|
||||
mappings.update(groupMappings.getEndDate(), modifications);
|
||||
}
|
||||
}
|
||||
|
||||
if (!taxComponentList.isEmpty()) {
|
||||
changes.put("addComponents", taxComponentList);
|
||||
}
|
||||
if (!modifications.isEmpty()) {
|
||||
changes.put("modifiedComponents", modifications);
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public TaxGroupMappings findOneBy(final TaxGroupMappings groupMapping) {
|
||||
if (groupMapping.getId() != null) {
|
||||
for (TaxGroupMappings groupMappings : this.taxGroupMappings) {
|
||||
if (groupMappings.getId().equals(groupMapping.getId())) {
|
||||
return groupMappings;
|
||||
}
|
||||
}
|
||||
throw new TaxMappingNotFoundException(groupMapping.getId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<TaxGroupMappings> getTaxGroupMappings() {
|
||||
return this.taxGroupMappings;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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
|
||||
@Table(name = "m_tax_group_mappings")
|
||||
public class TaxGroupMappings extends AbstractAuditableCustom {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "tax_group_id", nullable = false)
|
||||
private TaxGroup taxGroup;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "tax_component_id", nullable = false)
|
||||
private TaxComponent taxComponent;
|
||||
|
||||
@Column(name = "start_date", nullable = false)
|
||||
private LocalDate startDate;
|
||||
|
||||
@Column(name = "end_date", nullable = true)
|
||||
private LocalDate endDate;
|
||||
|
||||
protected TaxGroupMappings() {}
|
||||
|
||||
private TaxGroupMappings(final TaxComponent taxComponent, final LocalDate startDate, final LocalDate endDate) {
|
||||
this.taxComponent = taxComponent;
|
||||
this.startDate = startDate;
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public static TaxGroupMappings createTaxGroupMappings(final TaxComponent taxComponent, final LocalDate startDate) {
|
||||
final LocalDate endDate = null;
|
||||
return new TaxGroupMappings(taxComponent, startDate, endDate);
|
||||
|
||||
}
|
||||
|
||||
public static TaxGroupMappings createTaxGroupMappings(final Long id, final TaxComponent taxComponent, final LocalDate endDate) {
|
||||
final LocalDate startDate = null;
|
||||
TaxGroupMappings groupMappings = new TaxGroupMappings(taxComponent, startDate, endDate);
|
||||
groupMappings.setId(id);
|
||||
return groupMappings;
|
||||
|
||||
}
|
||||
|
||||
public void update(final LocalDate endDate, final List<Map<String, Object>> changes) {
|
||||
if (endDate != null && this.endDate == null) {
|
||||
this.endDate = endDate;
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put(TaxApiConstants.endDateParamName, endDate);
|
||||
map.put(TaxApiConstants.taxComponentIdParamName, this.getTaxComponent().getId());
|
||||
changes.add(map);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) {
|
||||
return DateUtils.isAfter(target, startDate()) && (endDate == null || !DateUtils.isAfter(target, endDate()));
|
||||
}
|
||||
|
||||
public TaxComponent getTaxComponent() {
|
||||
return this.taxComponent;
|
||||
}
|
||||
|
||||
public LocalDate getEndDate() {
|
||||
return this.endDate;
|
||||
}
|
||||
|
||||
public LocalDate startDate() {
|
||||
return this.startDate;
|
||||
}
|
||||
|
||||
public LocalDate endDate() {
|
||||
return this.endDate;
|
||||
}
|
||||
|
||||
public TaxGroup getTaxGroup() {
|
||||
return taxGroup;
|
||||
}
|
||||
|
||||
public void setTaxGroup(TaxGroup taxGroup) {
|
||||
this.taxGroup = taxGroup;
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface TaxGroupRepository extends JpaRepository<TaxGroup, Long>, JpaSpecificationExecutor<TaxGroup> {
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* 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.domain;
|
||||
|
||||
import org.apache.fineract.portfolio.tax.exception.TaxGroupNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TaxGroupRepositoryWrapper {
|
||||
|
||||
private final TaxGroupRepository repository;
|
||||
|
||||
@Autowired
|
||||
public TaxGroupRepositoryWrapper(final TaxGroupRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public TaxGroup findOneWithNotFoundDetection(final Long id) {
|
||||
return this.repository.findById(id).orElseThrow(() -> new TaxGroupNotFoundException(id));
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* 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.exception;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
public class TaxComponentNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public TaxComponentNotFoundException(final Long id) {
|
||||
super("error.msg.tax.component.id.invalid", "tax component with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* 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.exception;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
public class TaxGroupNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public TaxGroupNotFoundException(final Long id) {
|
||||
super("error.msg.tax.group.id.invalid", "tax group with identifier " + id + " does not exist", id);
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* 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.exception;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* {@link AbstractPlatformDomainRuleException} thrown when tax group mapping does not exist.
|
||||
*/
|
||||
public class TaxMappingNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||
|
||||
public TaxMappingNotFoundException(final Long id) {
|
||||
super("error.msg.tax.group.id.invalid", "Tax group mapping with identifier " + id + " does not exist", id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* 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.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||
import org.apache.fineract.portfolio.tax.data.TaxComponentData;
|
||||
import org.apache.fineract.portfolio.tax.data.TaxGroupMappingsData;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxComponent;
|
||||
import org.apache.fineract.portfolio.tax.domain.TaxGroupMappings;
|
||||
|
||||
public final class TaxUtils {
|
||||
|
||||
private TaxUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static Map<TaxComponent, BigDecimal> splitTax(final BigDecimal amount, final LocalDate date,
|
||||
final Set<TaxGroupMappings> taxGroupMappings, final int scale) {
|
||||
Map<TaxComponent, BigDecimal> map = new HashMap<>(3);
|
||||
if (amount != null) {
|
||||
final double amountVal = amount.doubleValue();
|
||||
double cent_percentage = Double.parseDouble("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 Map<TaxComponentData, BigDecimal> splitTaxData(final BigDecimal amount, final LocalDate date,
|
||||
final Set<TaxGroupMappingsData> taxGroupMappings, final int scale) {
|
||||
Map<TaxComponentData, BigDecimal> map = new HashMap<>(3);
|
||||
if (amount != null) {
|
||||
final double amountVal = amount.doubleValue();
|
||||
double cent_percentage = Double.parseDouble("100.0");
|
||||
for (TaxGroupMappingsData groupMappings : taxGroupMappings) {
|
||||
if (groupMappings.occursOnDayFromAndUpToAndIncluding(date)) {
|
||||
TaxComponentData 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 Set<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 totalTaxDataAmount(final Map<TaxComponentData, 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) > 0) {
|
||||
double percentageVal = 0;
|
||||
double amountVal = amount.doubleValue();
|
||||
double cent_percentage = Double.parseDouble("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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user