http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/data/TaxGroupMappingsData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/data/TaxGroupMappingsData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/data/TaxGroupMappingsData.java new file mode 100644 index 0000000..da02492 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/data/TaxGroupMappingsData.java @@ -0,0 +1,40 @@ +/** + * 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.data; + +import org.joda.time.LocalDate; + +public class TaxGroupMappingsData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final TaxComponentData taxComponent; + @SuppressWarnings("unused") + private final LocalDate startDate; + @SuppressWarnings("unused") + private final LocalDate endDate; + + public TaxGroupMappingsData(final Long id, final TaxComponentData taxComponent, final LocalDate startDate, final LocalDate endDate) { + this.id = id; + this.taxComponent = taxComponent; + this.startDate = startDate; + this.endDate = endDate; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java new file mode 100644 index 0000000..32ec96b --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponent.java @@ -0,0 +1,222 @@ +/** + * 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 java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.commons.lang.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; +import org.apache.fineract.useradministration.domain.AppUser; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; +import org.joda.time.LocalDate; + +@Entity +@Table(name = "m_tax_component") +public class TaxComponent extends AbstractAuditableCustom<AppUser, Long> { + + @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) + @Temporal(TemporalType.DATE) + private Date startDate; + + @LazyCollection(LazyCollectionOption.FALSE) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "tax_component_id", referencedColumnName = "id", nullable = false) + private List<TaxComponentHistory> taxComponentHistories = new ArrayList<>(); + + @LazyCollection(LazyCollectionOption.TRUE) + @OneToMany(cascade = CascadeType.DETACH, mappedBy = "taxComponent", orphanRemoval = false) + private List<TaxGroupMappings> taxGroupMappings = new ArrayList<>(); + + 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.toDate(); + } + + 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 = new LocalDate(this.startDate); + updateStartDate(command, changes, true); + LocalDate newStartDate = new LocalDate(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.getLocalDateOfTenant(); + if (command.parameterExists(TaxApiConstants.startDateParamName)) { + LocalDate startDateFromUI = command.localDateValueOfParameterNamed(TaxApiConstants.startDateParamName); + if (startDateFromUI != null) { + startDate = startDateFromUI; + } + this.startDate = startDate.toDate(); + changes.put(TaxApiConstants.startDateParamName, startDate); + } else if (setAsCurrentDate) { + changes.put(TaxApiConstants.startDateParamName, startDate); + this.startDate = startDate.toDate(); + } + + } + + public BigDecimal getPercentage() { + return this.percentage; + } + + public LocalDate startDate() { + LocalDate startDate = null; + if (this.startDate != null) { + startDate = new LocalDate(this.startDate); + } + return 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 target != null && target.isAfter(startDate()); + } + + public List<TaxComponentHistory> getTaxComponentHistories() { + return this.taxComponentHistories; + } + + public List<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; + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentHistory.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentHistory.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentHistory.java new file mode 100644 index 0000000..9074895 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentHistory.java @@ -0,0 +1,92 @@ +/** + * 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 java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; +import org.apache.fineract.useradministration.domain.AppUser; +import org.joda.time.LocalDate; + +@Entity +@Table(name = "m_tax_component_history") +public class TaxComponentHistory extends AbstractAuditableCustom<AppUser, Long> { + + @Column(name = "percentage", scale = 6, precision = 19, nullable = false) + private BigDecimal percentage; + + @Column(name = "start_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date startDate; + + @Column(name = "end_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date endDate; + + protected TaxComponentHistory() { + + } + + private TaxComponentHistory(final BigDecimal percentage, final LocalDate startDate, final LocalDate endDate) { + this.percentage = percentage; + this.startDate = startDate.toDate(); + this.endDate = endDate.toDate(); + } + + public static TaxComponentHistory createTaxComponentHistory(final BigDecimal percentage, final LocalDate startDate, + final LocalDate endDate) { + return new TaxComponentHistory(percentage, startDate, endDate); + } + + public LocalDate startDate(){ + LocalDate startDate = null; + if(this.startDate != null){ + startDate = new LocalDate(this.startDate); + } + return startDate; + } + + public LocalDate endDate(){ + LocalDate endDate = null; + if(this.endDate != null){ + endDate = new LocalDate(this.endDate); + } + return endDate; + } + + public boolean occursOnDayFromAndUpToAndIncluding(final LocalDate target) { + if(this.endDate == null){ + return target != null && target.isAfter(startDate()); + } + return target != null && target.isAfter(startDate()) && !target.isAfter(endDate()); + } + + + public BigDecimal getPercentage() { + return this.percentage; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepository.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepository.java new file mode 100644 index 0000000..ee45584 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepository.java @@ -0,0 +1,26 @@ +/** + * 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> { + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepositoryWrapper.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepositoryWrapper.java new file mode 100644 index 0000000..ae590e7 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxComponentRepositoryWrapper.java @@ -0,0 +1,43 @@ +/** + * 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) { + + final TaxComponent taxComponent = this.repository.findOne(id); + if (taxComponent == null) { throw new TaxComponentNotFoundException(id); } + + return taxComponent; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.java new file mode 100644 index 0000000..0e780f3 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroup.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.portfolio.tax.domain; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.apache.commons.lang.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; +import org.apache.fineract.useradministration.domain.AppUser; +import org.hibernate.annotations.LazyCollection; +import org.hibernate.annotations.LazyCollectionOption; + +@Entity +@Table(name = "m_tax_group") +public class TaxGroup extends AbstractAuditableCustom<AppUser, Long> { + + @Column(name = "name", length = 100) + private String name; + + @LazyCollection(LazyCollectionOption.FALSE) + @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "tax_group_id", referencedColumnName = "id", nullable = false) + private List<TaxGroupMappings> taxGroupMappings = new ArrayList<>(); + + protected TaxGroup() { + + } + + private TaxGroup(final String name, final List<TaxGroupMappings> taxGroupMappings) { + this.name = name; + this.taxGroupMappings = taxGroupMappings; + } + + public static TaxGroup createTaxGroup(final String name, final List<TaxGroupMappings> taxGroupMappings) { + return new TaxGroup(name, taxGroupMappings); + } + + public Map<String, Object> update(final JsonCommand command, final List<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 List<TaxGroupMappings> getTaxGroupMappings() { + return this.taxGroupMappings; + } + + public String getName() { + return this.name; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java new file mode 100644 index 0000000..767e4ba --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupMappings.java @@ -0,0 +1,120 @@ +/** + * 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 java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom; +import org.apache.fineract.portfolio.tax.api.TaxApiConstants; +import org.apache.fineract.useradministration.domain.AppUser; +import org.joda.time.LocalDate; + +@Entity +@Table(name = "m_tax_group_mappings") +public class TaxGroupMappings extends AbstractAuditableCustom<AppUser, Long> { + + @ManyToOne + @JoinColumn(name = "tax_component_id", nullable = false) + private TaxComponent taxComponent; + + @Column(name = "start_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date startDate; + + @Column(name = "end_date", nullable = true) + @Temporal(TemporalType.DATE) + private Date endDate; + + protected TaxGroupMappings() {} + + private TaxGroupMappings(final TaxComponent taxComponent, final LocalDate startDate, final LocalDate endDate) { + + this.taxComponent = taxComponent; + if (startDate != null) { + this.startDate = startDate.toDate(); + } + if (endDate != null) { + this.endDate = endDate.toDate(); + } + } + + 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 Date 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) { + if (this.endDate == null) { return target != null && target.isAfter(startDate()); } + return target != null && target.isAfter(startDate()) && !target.isAfter(endDate()); + } + + public TaxComponent getTaxComponent() { + return this.taxComponent; + } + + public Date getEndDate() { + return this.endDate; + } + + public LocalDate startDate() { + LocalDate startDate = null; + if (this.startDate != null) { + startDate = new LocalDate(this.startDate); + } + return startDate; + } + + public LocalDate endDate() { + LocalDate endDate = null; + if (this.endDate != null) { + endDate = new LocalDate(this.endDate); + } + return endDate; + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepository.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepository.java new file mode 100644 index 0000000..9934541 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepository.java @@ -0,0 +1,26 @@ +/** + * 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> { + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepositoryWrapper.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepositoryWrapper.java new file mode 100644 index 0000000..5ef1776 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/domain/TaxGroupRepositoryWrapper.java @@ -0,0 +1,43 @@ +/** + * 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) { + + final TaxGroup taxGroup = this.repository.findOne(id); + if (taxGroup == null) { throw new TaxGroupNotFoundException(id); } + + return taxGroup; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxComponentNotFoundException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxComponentNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxComponentNotFoundException.java new file mode 100644 index 0000000..0cae305 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxComponentNotFoundException.java @@ -0,0 +1,28 @@ +/** + * 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); + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxGroupNotFoundException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxGroupNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxGroupNotFoundException.java new file mode 100644 index 0000000..76ff42f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxGroupNotFoundException.java @@ -0,0 +1,28 @@ +/** + * 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); + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxMappingNotFoundException.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxMappingNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxMappingNotFoundException.java new file mode 100644 index 0000000..d9ce11f --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/exception/TaxMappingNotFoundException.java @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.tax.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); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java new file mode 100644 index 0000000..cabf0ca --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxComponentCommandHandler.java @@ -0,0 +1,45 @@ +/** + * 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.handler; + +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 +@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); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java new file mode 100644 index 0000000..e5b523d --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/CreateTaxGroupCommandHandler.java @@ -0,0 +1,45 @@ +/** + * 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.handler; + +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 +@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); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java new file mode 100644 index 0000000..b94e369 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxComponentCommandHandler.java @@ -0,0 +1,45 @@ +/** + * 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.handler; + +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 +@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); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java new file mode 100644 index 0000000..1229e46 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/handler/UpdateTaxGroupCommandHandler.java @@ -0,0 +1,45 @@ +/** + * 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.handler; + +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 +@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); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java new file mode 100644 index 0000000..6df786e --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/serialization/TaxValidator.java @@ -0,0 +1,365 @@ +/** + * 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.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.fineract.accounting.glaccount.domain.GLAccountType; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; +import org.apache.fineract.infrastructure.core.exception.InvalidJsonException; +import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.portfolio.tax.api.TaxApiConstants; +import org.apache.fineract.portfolio.tax.domain.TaxComponent; +import org.apache.fineract.portfolio.tax.domain.TaxGroup; +import org.apache.fineract.portfolio.tax.domain.TaxGroupMappings; +import org.joda.time.LocalDate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +@Component +public class TaxValidator { + + final Set<String> supportedTaxComponentCreateParameters = new HashSet<>(Arrays.asList("dateFormat", "locale", + TaxApiConstants.nameParamName, TaxApiConstants.percentageParamName, TaxApiConstants.startDateParamName, + TaxApiConstants.debitAccountTypeParamName, TaxApiConstants.debitAcountIdParamName, TaxApiConstants.creditAccountTypeParamName, + TaxApiConstants.creditAcountIdParamName)); + + final Set<String> supportedTaxComponentUpdateParameters = new HashSet<>(Arrays.asList("dateFormat", "locale", + TaxApiConstants.nameParamName, TaxApiConstants.percentageParamName, TaxApiConstants.startDateParamName)); + + final Set<String> supportedTaxGroupParameters = new HashSet<>(Arrays.asList("dateFormat", "locale", TaxApiConstants.nameParamName, + TaxApiConstants.taxComponentsParamName)); + + final Set<String> supportedTaxGroupTaxComponentsCreateParameters = new HashSet<>(Arrays.asList(TaxApiConstants.taxComponentIdParamName, + TaxApiConstants.startDateParamName)); + + final Set<String> supportedTaxGroupTaxComponentsUpdateParameters = new HashSet<>(Arrays.asList(TaxApiConstants.idParamName, + TaxApiConstants.taxComponentIdParamName, TaxApiConstants.startDateParamName, TaxApiConstants.endDateParamName)); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public TaxValidator(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForTaxComponentCreate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedTaxComponentCreateParameters); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.component"); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.nameParamName).value(name).notBlank(); + + final BigDecimal percentage = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(TaxApiConstants.percentageParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.percentageParamName).value(percentage).notBlank().positiveAmount() + .notGreaterThanMax(BigDecimal.valueOf(100)); + + final Integer debitAccountType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(TaxApiConstants.debitAccountTypeParamName, + element); + baseDataValidator + .reset() + .parameter(TaxApiConstants.debitAccountTypeParamName) + .value(debitAccountType) + .ignoreIfNull() + .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(); + if (debitAccountType != null || debitAccountId != null) { + baseDataValidator.reset().parameter(TaxApiConstants.debitAccountTypeParamName).value(debitAccountType).notBlank(); + baseDataValidator.reset().parameter(TaxApiConstants.debitAcountIdParamName).value(debitAccountId).notBlank(); + } + + final Integer creditAccountType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(TaxApiConstants.creditAccountTypeParamName, + element); + baseDataValidator + .reset() + .parameter(TaxApiConstants.creditAccountTypeParamName) + .value(creditAccountType) + .ignoreIfNull() + .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(); + if (creditAccountType != null || creditAccountId != null) { + baseDataValidator.reset().parameter(TaxApiConstants.creditAcountIdParamName).value(creditAccountId).notBlank(); + baseDataValidator.reset().parameter(TaxApiConstants.creditAccountTypeParamName).value(creditAccountType).notBlank(); + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForTaxComponentUpdate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedTaxComponentUpdateParameters); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.component"); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + + if (this.fromApiJsonHelper.parameterExists(TaxApiConstants.nameParamName, element)) { + final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.nameParamName).value(name).notBlank(); + } + + if (this.fromApiJsonHelper.parameterExists(TaxApiConstants.percentageParamName, element)) { + final BigDecimal percentage = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(TaxApiConstants.percentageParamName, + element); + baseDataValidator.reset().parameter(TaxApiConstants.percentageParamName).value(percentage).notBlank().positiveAmount() + .notGreaterThanMax(BigDecimal.valueOf(100)); + } + + if (this.fromApiJsonHelper.parameterExists(TaxApiConstants.startDateParamName, element)) { + final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(TaxApiConstants.startDateParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.startDateParamName).value(startDate) + .validateDateAfter(DateUtils.getLocalDateOfTenant()); + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForTaxGroupCreate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedTaxGroupParameters); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.group"); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.nameParamName).value(name).notBlank(); + + final JsonArray taxComponents = this.fromApiJsonHelper.extractJsonArrayNamed(TaxApiConstants.taxComponentsParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.taxComponentsParamName).value(taxComponents).notBlank(); + + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + if (topLevelJsonElement.get(TaxApiConstants.taxComponentsParamName).isJsonArray()) { + final JsonArray array = topLevelJsonElement.get(TaxApiConstants.taxComponentsParamName).getAsJsonArray(); + baseDataValidator.reset().parameter(TaxApiConstants.taxComponentsParamName).value(array.size()).integerGreaterThanZero(); + for (int i = 1; i <= array.size(); i++) { + final JsonObject taxComponent = array.get(i - 1).getAsJsonObject(); + final String arrayObjectJson = this.fromApiJsonHelper.toJson(taxComponent); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, arrayObjectJson, + supportedTaxGroupTaxComponentsCreateParameters); + final Long taxComponentId = this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.taxComponentIdParamName, taxComponent); + baseDataValidator.reset().parameter(TaxApiConstants.taxComponentsParamName) + .parameterAtIndexArray(TaxApiConstants.taxComponentIdParamName, i).value(taxComponentId).notNull() + .longGreaterThanZero(); + + } + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForTaxGroupUpdate(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedTaxGroupParameters); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.group"); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + + if (this.fromApiJsonHelper.parameterExists(TaxApiConstants.nameParamName, element)) { + final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.nameParamName).value(name).notBlank(); + } + if (this.fromApiJsonHelper.parameterExists(TaxApiConstants.taxComponentsParamName, element)) { + final JsonArray taxComponents = this.fromApiJsonHelper.extractJsonArrayNamed(TaxApiConstants.taxComponentsParamName, element); + baseDataValidator.reset().parameter(TaxApiConstants.taxComponentsParamName).value(taxComponents).notBlank(); + + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + final String dateFormat = this.fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); + if (topLevelJsonElement.get(TaxApiConstants.taxComponentsParamName).isJsonArray()) { + final JsonArray array = topLevelJsonElement.get(TaxApiConstants.taxComponentsParamName).getAsJsonArray(); + for (int i = 1; i <= array.size(); i++) { + final JsonObject taxComponent = array.get(i - 1).getAsJsonObject(); + final String arrayObjectJson = this.fromApiJsonHelper.toJson(taxComponent); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, arrayObjectJson, + supportedTaxGroupTaxComponentsUpdateParameters); + final Long taxComponentId = this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.taxComponentIdParamName, + taxComponent); + final Long taxMappingId = this.fromApiJsonHelper + .extractLongNamed(TaxApiConstants.taxComponentIdParamName, taxComponent); + if (taxMappingId == null) { + baseDataValidator + .reset() + .parameter( + TaxApiConstants.taxComponentsParamName + "." + TaxApiConstants.taxComponentIdParamName + + ".at.index." + i).value(taxComponentId).notNull().longGreaterThanZero(); + } else { + baseDataValidator + .reset() + .parameter( + TaxApiConstants.taxComponentsParamName + "." + TaxApiConstants.taxComponentIdParamName + + ".at.index." + i).value(taxComponentId).longGreaterThanZero(); + baseDataValidator.reset() + .parameter(TaxApiConstants.taxComponentsParamName + "." + TaxApiConstants.idParamName + ".at.index." + i) + .value(taxMappingId).longGreaterThanZero(); + } + + final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed(TaxApiConstants.endDateParamName, taxComponent, + dateFormat, locale); + baseDataValidator.reset() + .parameter(TaxApiConstants.taxComponentsParamName + "." + TaxApiConstants.endDateParamName + ".at.index." + i) + .value(endDate).ignoreIfNull().validateDateAfter(DateUtils.getLocalDateOfTenant()); + final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(TaxApiConstants.startDateParamName, + taxComponent, dateFormat, locale); + if (endDate != null && startDate != null) { + baseDataValidator.reset().parameter(TaxApiConstants.taxComponentsParamName + ".at.index." + i) + .failWithCode("start.date.end.date.both.should.not.be.present", startDate, endDate); + } + } + } + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateTaxGroupEndDateAndTaxComponent(final TaxGroup taxGroup, final List<TaxGroupMappings> groupMappings) { + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.group"); + + for (TaxGroupMappings mapping : groupMappings) { + if (mapping.getId() != null) { + TaxGroupMappings existing = taxGroup.findOneBy(mapping); + if (existing.endDate() != null && mapping.endDate() != null && !existing.endDate().isEqual(mapping.endDate())) { + baseDataValidator.reset().parameter(TaxApiConstants.endDateParamName) + .failWithCode("can.not.modify.end.date.once.updated"); + } else { + baseDataValidator.reset().parameter(TaxApiConstants.endDateParamName).value(mapping.endDate()).ignoreIfNull() + .validateDateAfter(existing.startDate()); + } + if(mapping.getTaxComponent()!= null && !existing.getTaxComponent().getId().equals(mapping.getTaxComponent().getId())){ + baseDataValidator.reset().parameter(TaxApiConstants.taxComponentIdParamName).failWithCode("update.not.supported");; + } + } else if (mapping.endDate() != null) { + baseDataValidator.reset().parameter(TaxApiConstants.endDateParamName).failWithCode("not.supported.for.new.association"); + } + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateTaxGroup(final TaxGroup taxGroup) { + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.group"); + List<TaxGroupMappings> groupMappings = taxGroup.getTaxGroupMappings(); + validateGroupTotal(groupMappings, baseDataValidator, "total.percentage"); + validateOverlappingComponents(groupMappings, baseDataValidator); + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateTaxComponentForUpdate(final TaxComponent taxComponent) { + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.component"); + validateGroupTotal(taxComponent.getTaxGroupMappings(), baseDataValidator, "group.total." + TaxApiConstants.percentageParamName); + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateStartDate(final LocalDate existingStartDate, final JsonCommand command) { + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.component"); + validateStartDate(existingStartDate, command.localDateValueOfParameterNamed(TaxApiConstants.startDateParamName), baseDataValidator); + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private void validateStartDate(final LocalDate existingStartDate, final LocalDate startDate, + final DataValidatorBuilder baseDataValidator) { + baseDataValidator.reset().parameter(TaxApiConstants.startDateParamName).value(startDate).validateDateAfter(existingStartDate); + } + + private void validateOverlappingComponents(final List<TaxGroupMappings> taxMappings, final DataValidatorBuilder baseDataValidator) { + for (TaxGroupMappings groupMappingsOne : taxMappings) { + final List<TaxGroupMappings> mappings = new ArrayList<>(taxMappings); + mappings.remove(groupMappingsOne); + for (TaxGroupMappings groupMappings : mappings) { + if (groupMappingsOne.getTaxComponent().equals(groupMappings.getTaxComponent())) { + if (groupMappingsOne.endDate() == null && groupMappings.endDate() == null) { + baseDataValidator.reset().parameter("component").failWithCode("dates.are.overlapping"); + } else if (groupMappingsOne.startDate().isAfter(groupMappings.startDate())) { + baseDataValidator.reset().parameter("component.start.date").value(groupMappingsOne.startDate()) + .validateDateAfter(groupMappings.endDate()); + } else { + baseDataValidator.reset().parameter("component.start.date").value(groupMappings.startDate()) + .validateDateAfter(groupMappingsOne.endDate()); + } + } + } + } + } + + private void validateGroupTotal(final List<TaxGroupMappings> taxMappings, final DataValidatorBuilder baseDataValidator, + final String paramenter) { + for (TaxGroupMappings groupMappingsOne : taxMappings) { + Collection<LocalDate> dates = groupMappingsOne.getTaxComponent().allStartDates(); + for (LocalDate date : dates) { + LocalDate applicableDate = date.plusDays(1); + BigDecimal total = BigDecimal.ZERO; + for (TaxGroupMappings groupMappings : taxMappings) { + if (groupMappings.occursOnDayFromAndUpToAndIncluding(applicableDate)) { + BigDecimal applicablePercentage = groupMappings.getTaxComponent().getApplicablePercentage(applicableDate); + if (applicablePercentage != null) { + total = total.add(applicablePercentage); + } + } + } + baseDataValidator.reset().parameter(paramenter).value(total).notGreaterThanMax(BigDecimal.valueOf(100)); + } + } + } + + private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..1e5ad92 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxAssembler.java @@ -0,0 +1,163 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.tax.service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.apache.fineract.accounting.glaccount.domain.GLAccount; +import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper; +import org.apache.fineract.accounting.glaccount.domain.GLAccountType; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; +import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; +import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; +import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.portfolio.tax.api.TaxApiConstants; +import org.apache.fineract.portfolio.tax.domain.TaxComponent; +import org.apache.fineract.portfolio.tax.domain.TaxComponentRepositoryWrapper; +import org.apache.fineract.portfolio.tax.domain.TaxGroup; +import org.apache.fineract.portfolio.tax.domain.TaxGroupMappings; +import org.joda.time.LocalDate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +@Component +public class TaxAssembler { + + private final FromJsonHelper fromApiJsonHelper; + private final GLAccountRepositoryWrapper glAccountRepositoryWrapper; + private final TaxComponentRepositoryWrapper taxComponentRepositoryWrapper; + + @Autowired + public TaxAssembler(final FromJsonHelper fromApiJsonHelper, final GLAccountRepositoryWrapper glAccountRepositoryWrapper, + final TaxComponentRepositoryWrapper taxComponentRepositoryWrapper) { + this.fromApiJsonHelper = fromApiJsonHelper; + this.glAccountRepositoryWrapper = glAccountRepositoryWrapper; + this.taxComponentRepositoryWrapper = taxComponentRepositoryWrapper; + } + + public TaxComponent assembleTaxComponentFrom(final JsonCommand command) { + final JsonElement element = command.parsedJson(); + + final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("tax.component"); + + final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); + 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); + GLAccountType debitGlAccountType = null; + if (debitAccountType != null) { + debitGlAccountType = GLAccountType.fromInt(debitAccountType); + } + GLAccount debitGlAccount = null; + if (debitAccountId != null) { + debitGlAccount = this.glAccountRepositoryWrapper.findOneWithNotFoundDetection(debitAccountId); + if (!debitGlAccount.getType().equals(debitAccountType) || debitGlAccount.isHeaderAccount()) { + baseDataValidator.parameter(TaxApiConstants.debitAcountIdParamName).value(debitAccountId) + .failWithCode("not.a.valid.account"); + } + } + + final Integer creditAccountType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(TaxApiConstants.creditAccountTypeParamName, + element); + GLAccountType creditGlAccountType = null; + if (creditAccountType != null) { + creditGlAccountType = GLAccountType.fromInt(creditAccountType); + } + final Long creditAccountId = this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.creditAcountIdParamName, 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) + .failWithCode("not.a.valid.account"); + } + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(TaxApiConstants.startDateParamName, element); + if (startDate == null) { + startDate = DateUtils.getLocalDateOfTenant(); + } + + return TaxComponent.createTaxComponent(name, percentage, debitGlAccountType, debitGlAccount, creditGlAccountType, creditGlAccount, + startDate); + } + + public TaxGroup assembleTaxGroupFrom(final JsonCommand command) { + final JsonElement element = command.parsedJson(); + + final String name = this.fromApiJsonHelper.extractStringNamed(TaxApiConstants.nameParamName, element); + boolean isUpdate = false; + final List<TaxGroupMappings> groupMappings = assembleTaxGroupMappingsFrom(command, isUpdate); + return TaxGroup.createTaxGroup(name, groupMappings); + } + + public List<TaxGroupMappings> assembleTaxGroupMappingsFrom(final JsonCommand command, boolean isUpdate) { + List<TaxGroupMappings> groupMappings = new ArrayList<>(); + final JsonElement element = command.parsedJson(); + + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + final String dateFormat = this.fromApiJsonHelper.extractDateFormatParameter(topLevelJsonElement); + final Locale locale = this.fromApiJsonHelper.extractLocaleParameter(topLevelJsonElement); + + if (topLevelJsonElement.get(TaxApiConstants.taxComponentsParamName).isJsonArray()) { + final JsonArray array = topLevelJsonElement.get(TaxApiConstants.taxComponentsParamName).getAsJsonArray(); + for (int i = 0; i < array.size(); i++) { + final JsonObject taxComponent = array.get(i).getAsJsonObject(); + final Long mappingId = this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.idParamName, taxComponent); + final Long taxComponentId = this.fromApiJsonHelper.extractLongNamed(TaxApiConstants.taxComponentIdParamName, taxComponent); + TaxComponent component = null; + if(taxComponentId != null){ + component = this.taxComponentRepositoryWrapper.findOneWithNotFoundDetection(taxComponentId); + } + LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(TaxApiConstants.startDateParamName, taxComponent, + dateFormat, locale); + final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed(TaxApiConstants.endDateParamName, taxComponent, + dateFormat, locale); + if (endDate == null && startDate == null) { + startDate = DateUtils.getLocalDateOfTenant(); + } + TaxGroupMappings mappings = null; + if (isUpdate && mappingId != null) { + mappings = TaxGroupMappings.createTaxGroupMappings(mappingId, component, endDate); + } else { + mappings = TaxGroupMappings.createTaxGroupMappings(component, startDate); + } + groupMappings.add(mappings); + + } + } + + return groupMappings; + } + + private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } + } +} http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/3015747f/fineract-provider/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/TaxReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.java new file mode 100644 index 0000000..646255c --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/tax/service/TaxReadPlatformService.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.service; + +import java.util.Collection; + +import org.apache.fineract.portfolio.tax.data.TaxComponentData; +import org.apache.fineract.portfolio.tax.data.TaxGroupData; + +public interface TaxReadPlatformService { + + public TaxComponentData retrieveTaxComponentData(final Long id); + + public TaxComponentData retrieveTaxComponentTemplate(); + + public TaxGroupData retrieveTaxGroupData(final Long id); + + public TaxGroupData retrieveTaxGroupWithTemplate(final Long id); + + public TaxGroupData retrieveTaxGroupTemplate(); + + Collection<TaxComponentData> retrieveAllTaxComponents(); + + Collection<TaxGroupData> retrieveAllTaxGroups(); + + Collection<TaxGroupData> retrieveTaxGroupsForLookUp(); + +}