Skip to content

Commit

Permalink
chore : polish
Browse files Browse the repository at this point in the history
  • Loading branch information
rajadilipkolli committed Apr 29, 2024
1 parent ae87432 commit 3a87dd1
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 35 deletions.
13 changes: 13 additions & 0 deletions src/main/java/com/learning/mfscreener/entities/MFSchemeEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.Version;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -42,6 +43,9 @@ public class MFSchemeEntity extends AuditableEntity<String> implements Serializa
@OneToMany(mappedBy = "mfSchemeEntity", cascade = CascadeType.ALL, orphanRemoval = true)
private List<MFSchemeNavEntity> mfSchemeNavEntities = new ArrayList<>();

@Version
private Short version;

public Long getSchemeId() {
return schemeId;
}
Expand Down Expand Up @@ -105,6 +109,15 @@ public MFSchemeEntity setMfSchemeNavEntities(List<MFSchemeNavEntity> mfSchemeNav
return this;
}

public Short getVersion() {
return version;
}

public MFSchemeEntity setVersion(Short version) {
this.version = version;
return this;
}

public MFSchemeEntity addSchemeNav(MFSchemeNavEntity mfSchemeNavEntity) {
mfSchemeNavEntities.add(mfSchemeNavEntity);
mfSchemeNavEntity.setMfSchemeEntity(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ public static BigDecimal getNav(String isin) {
}
return BigDecimal.ZERO;
}

private NavSearchHelper() {
throw new UnsupportedOperationException("Constructor can't be initialized");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public static <T> T getBean(Class<T> beanClass) {

@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
SpringContext.context = applicationContext;
context = applicationContext;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
public abstract class MfSchemeDtoToEntityMapper {

private final Logger log = LoggerFactory.getLogger(this.getClass());

// Define the regular expressions
private static final Pattern TYPE_CATEGORY_SUBCATEGORY_PATTERN =
Pattern.compile("^(.*?)\\((.*?)\\s*-\\s*(.*?)\\)$");

@Autowired
MFSchemeTypeRepository mfSchemeTypeRepository;

@Mapping(target = "version", ignore = true)
@Mapping(target = "mfSchemeTypeEntity", ignore = true)
@Mapping(target = "mfSchemeNavEntities", ignore = true)
@Mapping(target = "schemeNameAlias", ignore = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.learning.mfscreener.models.response;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

public record ProcessCasResponse(
Map<String, Map<String, Object>> summaryByFY,
BigDecimal investedAmount,
Double currentValue,
List<String> errors,
String importSummary) {

public ProcessCasResponse withImportSummary(String response) {
return new ProcessCasResponse(summaryByFY, investedAmount, currentValue, errors, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -20,6 +21,7 @@ public interface MFSchemeRepository extends JpaRepository<MFSchemeEntity, Long>

@EntityGraph(attributePaths = {"mfSchemeTypeEntity", "mfSchemeNavEntities"})
@Transactional(readOnly = true)
@Cacheable("bySchemeIdAndSchemeNav")
Optional<MFSchemeEntity> findBySchemeIdAndMfSchemeNavEntities_NavDate(
@Param("schemeCode") Long schemeCode, @Param("date") LocalDate navDate);

Expand All @@ -43,6 +45,7 @@ where upper(m.fundHouse) like upper(:fName) order by m.schemeId
@Transactional(readOnly = true)
List<FundDetailProjection> findByFundHouseLikeIgnoringCaseOrderBySchemeIdAsc(@Param("fName") String fName);

@Cacheable("schemeIdByISIN")
@Query("select m.schemeId from MFSchemeEntity m where m.payOut = :isin")
Optional<Long> getSchemeIdByISIN(@Param("isin") String isin);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.learning.mfscreener.models.portfolio.UserFolioDTO;
import com.learning.mfscreener.models.portfolio.UserSchemeDTO;
import com.learning.mfscreener.models.portfolio.UserTransactionDTO;
import com.learning.mfscreener.models.response.ProcessCasResponse;
import com.learning.mfscreener.utils.FIFOUnits;
import com.learning.mfscreener.utils.GainEntry;
import java.math.BigDecimal;
Expand All @@ -24,16 +25,21 @@
public class CapitalGainsService {

private static final double MIN_OPEN_BALANCE = 0.01;
private static final String TAX_LTCG = "tax_ltcg";
private static final String LTCG = "ltcg";
private static final String STCG = "stcg";
private static final String TOTAL = "total";

private BigDecimal investedAmount = BigDecimal.ZERO;
private Double currentValue = 0D;
private final List<GainEntry> gainEntries = new ArrayList<>();
List<String> errors = new ArrayList<>();
private final List<String> errors = new ArrayList<>();

@Loggable(params = false)
Map<String, Map<String, Object>> processData(CasDTO casDTO) throws IncompleteCASError {
ProcessCasResponse processData(CasDTO casDTO) throws IncompleteCASError {
casDTO.folios().forEach(this::processFolio);
return prepareGains(gainEntries);
Map<String, Map<String, Object>> summaryByFY = prepareGains(gainEntries);
return new ProcessCasResponse(summaryByFY, investedAmount, currentValue, errors, null);
}

void processFolio(UserFolioDTO folio) {
Expand Down Expand Up @@ -86,28 +92,28 @@ Map<String, Map<String, Object>> prepareGains(List<GainEntry> gainEntries) {
fySummary = new HashMap<>();
fySummary.put("funds", new ArrayList<>());
Map<String, BigDecimal> totalMap = new HashMap<>();
totalMap.put("ltcg", BigDecimal.ZERO);
totalMap.put("stcg", BigDecimal.ZERO);
totalMap.put("tax_ltcg", BigDecimal.ZERO);
fySummary.put("total", totalMap);
totalMap.put(LTCG, BigDecimal.ZERO);
totalMap.put(STCG, BigDecimal.ZERO);
totalMap.put(TAX_LTCG, BigDecimal.ZERO);
fySummary.put(TOTAL, totalMap);
summary.put(fy, fySummary);
}

Map<String, BigDecimal> netTotal = (Map<String, BigDecimal>) fySummary.get("total");
Map<String, BigDecimal> netTotal = (Map<String, BigDecimal>) fySummary.get(TOTAL);
Map<String, BigDecimal> total = new HashMap<>();
total.put("ltcg", BigDecimal.ZERO);
total.put("stcg", BigDecimal.ZERO);
total.put("tax_ltcg", BigDecimal.ZERO);
total.put(LTCG, BigDecimal.ZERO);
total.put(STCG, BigDecimal.ZERO);
total.put(TAX_LTCG, BigDecimal.ZERO);

Map<String, Object> data = new HashMap<>();
data.put("fy", fy);
data.put("fund", fund);
data.put("txns", new ArrayList<Map<String, Object>>());

value.forEach(txn -> {
total.computeIfPresent("ltcg", (k, v) -> v.add(txn.getLtcg()));
total.computeIfPresent("stcg", (k, v) -> v.add(txn.getStcg()));
total.computeIfPresent("tax_ltcg", (k, v) -> v.add(txn.getLtcgTaxable()));
total.computeIfPresent(LTCG, (k, v) -> v.add(txn.getLtcg()));
total.computeIfPresent(STCG, (k, v) -> v.add(txn.getStcg()));
total.computeIfPresent(TAX_LTCG, (k, v) -> v.add(txn.getLtcgTaxable()));

Map<String, Object> txnData = new HashMap<>();
txnData.put("buy_date", txn.getPurchaseDate());
Expand All @@ -116,20 +122,20 @@ Map<String, Map<String, Object>> prepareGains(List<GainEntry> gainEntries) {
txnData.put("coa", txn.getCoa());
txnData.put("sell_date", txn.getSaleDate());
txnData.put("sell_price", txn.getSaleValue());
txnData.put("ltcg", txn.getLtcg());
txnData.put("stcg", txn.getStcg());
txnData.put("tax_ltcg", txn.getLtcgTaxable());
txnData.put(LTCG, txn.getLtcg());
txnData.put(STCG, txn.getStcg());
txnData.put(TAX_LTCG, txn.getLtcgTaxable());
((List<Map<String, Object>>) data.get("txns")).add(txnData);
});

data.put("total", total);
data.put(TOTAL, total);
((List<Map<String, Object>>) fySummary.get("funds")).add(data);

netTotal.computeIfPresent("ltcg", (k, v) -> v.add(total.get("ltcg")));
netTotal.computeIfPresent("stcg", (k, v) -> v.add(total.get("stcg")));
netTotal.computeIfPresent("tax_ltcg", (k, v) -> v.add(total.get("tax_ltcg")));
netTotal.computeIfPresent(LTCG, (k, v) -> v.add(total.get(LTCG)));
netTotal.computeIfPresent(STCG, (k, v) -> v.add(total.get(STCG)));
netTotal.computeIfPresent(TAX_LTCG, (k, v) -> v.add(total.get(TAX_LTCG)));

fySummary.put("total", netTotal);
fySummary.put(TOTAL, netTotal);
});

return summary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
import com.learning.mfscreener.models.portfolio.UserSchemeDTO;
import com.learning.mfscreener.models.portfolio.UserTransactionDTO;
import com.learning.mfscreener.models.response.PortfolioResponse;
import com.learning.mfscreener.models.response.ProcessCasResponse;
import com.learning.mfscreener.models.response.UploadResponseHolder;
import com.learning.mfscreener.utils.LocalDateUtility;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -73,13 +73,11 @@ public PortfolioService(
this.capitalGainsService = capitalGainsService;
}

public Map<String, Object> upload(MultipartFile portfolioFile) throws IOException {
public ProcessCasResponse upload(MultipartFile portfolioFile) throws IOException {
CasDTO casDTO = parseCasDTO(portfolioFile);
String response = processCasDTO(casDTO);
Map<String, Map<String, Object>> investmentSummary = capitalGainsService.processData(casDTO);
Map<String, Object> responseMap = new HashMap<>(investmentSummary);
responseMap.put("importSummary", response);
return responseMap;
ProcessCasResponse processCasResponse = capitalGainsService.processData(casDTO);
return processCasResponse.withImportSummary(response);
}

public PortfolioResponse getPortfolioByPAN(String panNumber, LocalDate evaluationDate) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package com.learning.mfscreener.web.api;

import com.learning.mfscreener.models.response.PortfolioResponse;
import com.learning.mfscreener.models.response.ProcessCasResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import jakarta.validation.constraints.PastOrPresent;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

public interface PortfolioApi {

@Operation(summary = "Persists the transaction details.")
ResponseEntity<Map<String, Object>> upload(@RequestPart("file") MultipartFile multipartFile) throws IOException;
ResponseEntity<ProcessCasResponse> upload(@RequestPart("file") MultipartFile multipartFile) throws IOException;

@Operation(
summary =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.learning.mfscreener.web.controllers;

import com.learning.mfscreener.models.response.PortfolioResponse;
import com.learning.mfscreener.models.response.ProcessCasResponse;
import com.learning.mfscreener.service.PortfolioService;
import com.learning.mfscreener.web.api.PortfolioApi;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Map;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand All @@ -32,7 +32,7 @@ public PortfolioController(PortfolioService portfolioService) {

@Override
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Map<String, Object>> upload(@RequestPart("file") MultipartFile multipartFile)
public ResponseEntity<ProcessCasResponse> upload(@RequestPart("file") MultipartFile multipartFile)
throws IOException {
return ResponseEntity.ok(portfolioService.upload(multipartFile));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<column name="pay_out" type="${string.type}"/>
<column name="scheme_name_alias" type="${string.type}"/>
<column name="mf_scheme_type_id" type="INT"/>
<column name="version" type="tinyint" />
<column name="created_by" type="${string.type}"/>
<column name="created_date" type="DATETIME"/>
<column name="last_modified_by" type="${string.type}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void uploadFile() throws Exception {
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.importSummary", is("Imported 1 folios and 5 transactions")))
.andExpect(jsonPath("$.FY2022-23", notNullValue()));
.andExpect(jsonPath("$.summaryByFY.FY2022-23", notNullValue()));
} finally {
tempFile.deleteOnExit();
}
Expand Down Expand Up @@ -135,7 +135,7 @@ void uploadFileWithNewScheme() throws Exception {
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.importSummary", is("Imported 0 folios and 6 transactions")))
.andExpect(jsonPath("$.FY2022-23", notNullValue()));
.andExpect(jsonPath("$.summaryByFY.FY2022-23", notNullValue()));
} finally {
tempFile.deleteOnExit();
}
Expand Down

0 comments on commit 3a87dd1

Please sign in to comment.