Java tutorial
/** * 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.floatingrates.domain; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; 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.OrderBy; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO; import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData; import org.apache.fineract.useradministration.domain.AppUser; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.springframework.data.jpa.domain.AbstractPersistable; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @Entity @Table(name = "m_floating_rates", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") }) public class FloatingRate extends AbstractPersistable<Long> { @Column(name = "name", length = 200, unique = true, nullable = false) private String name; @Column(name = "is_base_lending_rate", nullable = false) private boolean isBaseLendingRate; @Column(name = "is_active", nullable = false) private boolean isActive; @OrderBy(value = "fromDate,id") @LazyCollection(LazyCollectionOption.FALSE) @OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate", orphanRemoval = true) private Set<FloatingRatePeriod> floatingRatePeriods; @ManyToOne(optional = true) @JoinColumn(name = "createdby_id", nullable = false) private AppUser createdBy; @ManyToOne(optional = true) @JoinColumn(name = "lastmodifiedby_id", nullable = false) private AppUser modifiedBy; @Column(name = "created_date", nullable = false) private Date createdOn; @Column(name = "lastmodified_date", nullable = false) private Date modifiedOn; public FloatingRate() { } public FloatingRate(String name, boolean isBaseLendingRate, boolean isActive, Set<FloatingRatePeriod> floatingRatePeriods, AppUser createdBy, AppUser modifiedBy, Date createdOn, Date modifiedOn) { this.name = name; this.isBaseLendingRate = isBaseLendingRate; this.isActive = isActive; this.floatingRatePeriods = floatingRatePeriods; this.createdBy = createdBy; this.createdOn = createdOn; this.modifiedBy = modifiedBy; this.modifiedOn = modifiedOn; if (floatingRatePeriods != null) { for (FloatingRatePeriod ratePeriod : floatingRatePeriods) { ratePeriod.updateFloatingRate(this); } } } public static FloatingRate createNew(AppUser currentUser, JsonCommand command) { final String name = command.stringValueOfParameterNamed("name"); final boolean isBaseLendingRate = command.parameterExists("isBaseLendingRate") ? command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate") : false; final boolean isActive = command.parameterExists("isActive") ? command.booleanPrimitiveValueOfParameterNamed("isActive") : true; final Set<FloatingRatePeriod> floatingRatePeriods = getRatePeriods(currentUser, command); final LocalDate currentDate = DateUtils.getLocalDateOfTenant(); return new FloatingRate(name, isBaseLendingRate, isActive, floatingRatePeriods, currentUser, currentUser, currentDate.toDate(), currentDate.toDate()); } private static Set<FloatingRatePeriod> getRatePeriods(final AppUser currentUser, final JsonCommand command) { if (!command.parameterExists("ratePeriods")) { return null; } Set<FloatingRatePeriod> ratePeriods = new HashSet<>(); JsonArray arrayOfParameterNamed = command.arrayOfParameterNamed("ratePeriods"); for (final JsonElement ratePeriod : arrayOfParameterNamed) { final JsonObject ratePeriodObject = ratePeriod.getAsJsonObject(); final JsonParserHelper helper = new JsonParserHelper(); final Date fromDate = helper.extractLocalDateNamed("fromDate", ratePeriod, new HashSet<String>()) .toDate(); final BigDecimal interestRate = ratePeriodObject.get("interestRate").getAsBigDecimal(); final boolean isDifferentialToBaseLendingRate = helper .parameterExists("isDifferentialToBaseLendingRate", ratePeriod) ? ratePeriodObject.get("isDifferentialToBaseLendingRate").getAsBoolean() : false; final boolean isActive = true; final Date currentDate = DateUtils.getDateOfTenant(); ratePeriods.add(new FloatingRatePeriod(fromDate, interestRate, isDifferentialToBaseLendingRate, isActive, currentUser, currentUser, currentDate, currentDate)); } return ratePeriods; } public String getName() { return this.name; } public boolean isBaseLendingRate() { return this.isBaseLendingRate; } public boolean isActive() { return this.isActive; } public Set<FloatingRatePeriod> getFloatingRatePeriods() { return this.floatingRatePeriods; } public AppUser getCreatedBy() { return this.createdBy; } public AppUser getModifiedBy() { return this.modifiedBy; } public Date getCreatedOn() { return this.createdOn; } public Date getModifiedOn() { return this.modifiedOn; } public Map<String, Object> update(final JsonCommand command, final AppUser appUser) { final Map<String, Object> actualChanges = new LinkedHashMap<>(9); if (command.isChangeInStringParameterNamed("name", this.name)) { final String newValue = command.stringValueOfParameterNamed("name"); actualChanges.put("name", newValue); this.name = newValue; } if (command.isChangeInBooleanParameterNamed("isBaseLendingRate", this.isBaseLendingRate)) { final boolean newValue = command.booleanPrimitiveValueOfParameterNamed("isBaseLendingRate"); actualChanges.put("isBaseLendingRate", newValue); this.isBaseLendingRate = newValue; } if (command.isChangeInBooleanParameterNamed("isActive", this.isActive)) { final boolean newValue = command.booleanPrimitiveValueOfParameterNamed("isActive"); actualChanges.put("isActive", newValue); this.isActive = newValue; } final Set<FloatingRatePeriod> newRatePeriods = getRatePeriods(appUser, command); if (newRatePeriods != null && !newRatePeriods.isEmpty()) { updateRatePeriods(newRatePeriods, appUser); actualChanges.put("ratePeriods", command.jsonFragment("ratePeriods")); } return actualChanges; } private void updateRatePeriods(final Set<FloatingRatePeriod> newRatePeriods, final AppUser appUser) { final LocalDate today = DateUtils.getLocalDateOfTenant(); if (this.floatingRatePeriods != null) { for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) { LocalDate fromDate = LocalDate.fromDateFields(ratePeriod.getFromDate()); if (fromDate.isAfter(today)) { ratePeriod.setActive(false); ratePeriod.setModifiedBy(appUser); ratePeriod.setModifiedOn(today.toDate()); } } } for (FloatingRatePeriod newRatePeriod : newRatePeriods) { newRatePeriod.updateFloatingRate(this); this.floatingRatePeriods.add(newRatePeriod); } } public Collection<FloatingRatePeriodData> fetchInterestRates(final FloatingRateDTO floatingRateDTO) { Collection<FloatingRatePeriodData> applicableRates = new ArrayList<>(); FloatingRatePeriod previousPeriod = null; boolean addPeriodData = false; for (FloatingRatePeriod floatingRatePeriod : this.floatingRatePeriods) { if (floatingRatePeriod.isActive()) { // will enter if (applicableRates.isEmpty() && floatingRateDTO.getStartDate().isBefore(floatingRatePeriod.fetchFromDate())) { if (floatingRateDTO.isFloatingInterestRate()) { addPeriodData = true; } if (previousPeriod != null) { applicableRates.add(previousPeriod.toData(floatingRateDTO)); } else if (!addPeriodData) { applicableRates.add(floatingRatePeriod.toData(floatingRateDTO)); } } if (addPeriodData) { applicableRates.add(floatingRatePeriod.toData(floatingRateDTO)); } previousPeriod = floatingRatePeriod; } } if (applicableRates.isEmpty() && previousPeriod != null) { applicableRates.add(previousPeriod.toData(floatingRateDTO)); } return applicableRates; } }