cut-to-pack-service/src/main/java/com/utopiaindustries/service/ReportingService.java

343 lines
17 KiB
Java

package com.utopiaindustries.service;
import com.utopiaindustries.dao.ctp.*;
import com.utopiaindustries.model.ctp.*;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class ReportingService {
private final JobCardItemDAO jobCardItemDAO;
private final CutPieceDAO cutPieceDAO;
private final BundleDAO bundleDAO;
private final InventoryTransactionLegDAO inventoryTransactionLegDAO;
private final InventoryTransactionDAO inventoryTransactionDAO;
private final JobCardDAO jobCardDAO;
private final CryptographyService cryptographyService;
private final MasterBundleDAO masterBundleDAO;
private final FinishedItemDAO finishedItemDAO;
private final StitchingOfflineItemDAO stitchingOfflineItemDAO;
private final InventoryAccountDAO inventoryAccountDAO;
public ReportingService( JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, BundleDAO bundleDAO, InventoryTransactionLegDAO inventoryTransactionLegDAO, InventoryTransactionDAO inventoryTransactionDAO, JobCardDAO jobCardDAO, CryptographyService cryptographyService, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, InventoryAccountDAO inventoryAccountDAO) {
this.jobCardItemDAO = jobCardItemDAO;
this.cutPieceDAO = cutPieceDAO;
this.bundleDAO = bundleDAO;
this.inventoryTransactionLegDAO = inventoryTransactionLegDAO;
this.inventoryTransactionDAO = inventoryTransactionDAO;
this.jobCardDAO = jobCardDAO;
this.cryptographyService = cryptographyService;
this.masterBundleDAO = masterBundleDAO;
this.finishedItemDAO = finishedItemDAO;
this.stitchingOfflineItemDAO = stitchingOfflineItemDAO;
this.inventoryAccountDAO = inventoryAccountDAO;
}
public Map<String,Integer> getJobCardProgress(String jobCardID){
if (jobCardID == null){
return new HashMap<>();
}else {
HashMap<String,Integer> totalProgress = new HashMap<>();
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
BigDecimal totalProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal actualProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal expectedProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getExpectedProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
if (actualProduction.compareTo(BigDecimal.ZERO) == 0 ) {
totalProgress.put("Cutting Progress", BigDecimal.ZERO.intValue());
} else if (actualProduction.compareTo(expectedProduction) < 0) {
BigDecimal cuttingProgress = expectedProduction
.divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
totalProgress.put("Cutting Progress", cuttingProgress.intValue());
}else if (actualProduction.compareTo(expectedProduction) > 0 || actualProduction.compareTo(expectedProduction) == 0){
totalProgress.put("Cutting Progress", 100);
}
if (totalProduction.compareTo(BigDecimal.ZERO) == 0){
totalProgress.put("Stitching Progress", BigDecimal.ZERO.intValue());
}else {
BigDecimal stitchingProgress = totalProduction
.divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
totalProgress.put("Stitching Progress", stitchingProgress.intValue());
}
Long qaProgressItems = stitchingOfflineItemDAO.CalculateTotalQA(Long.parseLong(jobCardID));
if (qaProgressItems == 0){
totalProgress.put("QA Progress", 0);
}else {
BigDecimal qaProgress = BigDecimal.valueOf(qaProgressItems)
.divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
totalProgress.put("QA Progress", qaProgress.intValue());
}
Long totalFinishItem = finishedItemDAO.calculateTotalFinishItem(Long.parseLong(jobCardID));
if (totalFinishItem == 0){
totalProgress.put("Finishing Progress", BigDecimal.ZERO.intValue());
}else {
BigDecimal finishItemProgress = BigDecimal.valueOf(totalFinishItem)
.divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP)
.multiply(BigDecimal.valueOf(100));
totalProgress.put("Finishing Progress", finishItemProgress.intValue());
}
if (totalProduction.compareTo(BigDecimal.ZERO) == 0 && actualProduction.compareTo(BigDecimal.ZERO) == 0 ) {
totalProgress.put("Job Card Progress", BigDecimal.ZERO.intValue());
} else {
if (actualProduction.compareTo(expectedProduction)>0){
BigDecimal progressPercentage = actualProduction.add(totalProduction).add(BigDecimal.valueOf(qaProgressItems)).add(BigDecimal.valueOf(totalFinishItem))
.divide(actualProduction.multiply(BigDecimal.valueOf(4)), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
totalProgress.put("Job Card Progress", progressPercentage.intValue());
}else {
BigDecimal progressPercentage = actualProduction.add(totalProduction).add(BigDecimal.valueOf(qaProgressItems)).add(BigDecimal.valueOf(totalFinishItem))
.divide(expectedProduction.multiply(BigDecimal.valueOf(4)), 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100));
totalProgress.put("Job Card Progress", progressPercentage.intValue());
}
}
return totalProgress;
}
}
public Integer getTotalProduction(String jobCardID){
if (jobCardID == null){
return 0;
}else {
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
BigDecimal actualProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return actualProduction.intValue();
}
}
public Map<String,Integer> getCompleteProduction(String jobCardID){
if (jobCardID == null){
return new HashMap<>();
}else {
HashMap<String,Integer> totalProgress = new HashMap<>();
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
BigDecimal totalProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal actualProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal expectedProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getExpectedProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
Long qaProgressItems = stitchingOfflineItemDAO.CalculateTotalQA(Long.parseLong(jobCardID));
Long totalFinishItem = finishedItemDAO.calculateTotalFinishItem(Long.parseLong(jobCardID));
totalProgress.put("Cutting Progress", actualProduction.intValue());
totalProgress.put("Stitching Progress", totalProduction.intValue());
totalProgress.put("QA Progress", qaProgressItems.intValue());
totalProgress.put("Finishing Progress", totalFinishItem.intValue());
return totalProgress;
}
}
public Map<String,Integer> getSegregateItems(String jobCardID){
if (jobCardID == null){
return new HashMap<>();
}else {
HashMap<String,Integer> gradingItems = new HashMap<>();
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.getPackagingAccounts();
List<FinishedItem> finishedItems = finishedItemDAO.findByJobCardId(Long.parseLong(jobCardID));
List<Long> finishItemsIds = finishedItems.stream()
.map(FinishedItem::getId).collect(Collectors.toList());
if (finishItemsIds.isEmpty()){
return gradingItems;
}else {
for (InventoryAccount inventoryAccount : inventoryAccounts){
long totalGradingItems = inventoryTransactionLegDAO.CalculateTotalGradingItems(finishItemsIds,(int) inventoryAccount.getId());
gradingItems.put(inventoryAccount.getTitle(), (int) totalGradingItems);
}
return gradingItems;
}
}
}
public HashMap<String,String> getEachPhaseTotalTime(String jobCardID){
if (jobCardID == null){
return new HashMap<>();
}else {
HashMap<String,String> phasesTimes = new HashMap<>();
JobCard jobCard = jobCardDAO.find(Long.parseLong(jobCardID));
Bundle lastBundle = bundleDAO.findLastBundleByCardId(Long.parseLong(jobCardID));
//Cutting time
StringBuilder cuttingTime = generateTime(jobCard.getCreatedAt(),lastBundle.getCreatedAt());
phasesTimes.put("Cutting Total Time",cuttingTime.toString());
//Stitching time
List<Long> bundlesIds = bundleDAO.findByCardId(Long.parseLong(jobCardID)).stream().map(Bundle::getId).collect(Collectors.toList());
if (!bundlesIds.isEmpty()){
InventoryTransactionLeg inventoryTransactionLeg = inventoryTransactionLegDAO.getFirstStitchBundleTime(bundlesIds,"STITCH_BUNDLE");
StitchingOfflineItem lastStitchItem = stitchingOfflineItemDAO.getLastStitchItemByCardIdAndTime(Long.parseLong(jobCardID));
StringBuilder stitchingTime = generateTime(inventoryTransactionLeg.getTransactionLegDateTime(),lastStitchItem.getCreatedAt());
phasesTimes.put("Stitching Total Time",stitchingTime.toString());
}else {
phasesTimes.put("Stitching Total Time",null);
}
return phasesTimes;
}
}
public HashMap<String,String> countPendingItemsOnDifferentPhases(String jobCardID){
if (jobCardID == null){
return new HashMap<>();
}else {
HashMap<String,String> phasePending = new HashMap<String,String>();
List<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID));
BigDecimal totalProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal actualProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal expectedProduction = jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getExpectedProduction()).orElse(BigDecimal.ZERO))
.reduce(BigDecimal.ZERO, BigDecimal::add);
if(actualProduction.compareTo(totalProduction) == 0) {
phasePending.put("Stitching Total Time", null);
}else {
phasePending.put("Stitching Total Time", "Pending");
}
return phasePending;
}
}
public Map<String, Map<String, Object>> getCuttingDetails(String jobCardID) {
if (jobCardID == null) {
return Collections.emptyMap();
}
Map<String, Map<String, Object>> cuttingDetails = new HashMap<>();
Map<String, InventoryAccount> cuttingAccount = new HashMap<>();
Map<String, String> cuttingPersonName = new HashMap<>();
Map<String, LocalDate> cuttingDate = new HashMap<>();
List<Bundle> bundles = bundleDAO.findByCardId(Long.parseLong(jobCardID));
if (bundles.isEmpty()) {
return cuttingDetails;
}
Map<Long, Bundle> bundleMap = bundles.stream()
.collect(Collectors.toMap(Bundle::getId, Function.identity()));
List<Long> bundleIds = new ArrayList<>(bundleMap.keySet());
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO
.getTransactionByParentIdAndType(bundleIds, "BUNDLE");
for (InventoryTransactionLeg inventoryTransactionLeg : inventoryTransactionLegs) {
Integer accountId = inventoryTransactionLeg.getAccountId();
InventoryAccount inventoryAccount = inventoryAccountDAO.find(accountId.longValue());
if (inventoryAccount != null) {
String accountTitle = inventoryAccount.getTitle();
cuttingAccount.put(accountTitle, inventoryAccount);
Bundle bundle = bundleMap.get(inventoryTransactionLeg.getParentDocumentId());
cuttingPersonName.put(accountTitle, (bundle != null) ? bundle.getCreatedBy() : null);
cuttingDate.put(accountTitle,(bundle != null) ? bundle.getCreatedAt().toLocalDate() : null);
}
}
cuttingDetails.put("accounts", new HashMap<>(cuttingAccount));
cuttingDetails.put("personName", new HashMap<>(cuttingPersonName));
cuttingDetails.put("date", new HashMap<>(cuttingDate));
return cuttingDetails;
}
public Map<String, Map<String, Object>> getStitchingDetails(String jobCardID) {
if (jobCardID == null) {
return Collections.emptyMap();
}
Map<String, Map<String, Object>> stitchingDetails = new HashMap<>();
Map<String, InventoryAccount> stitchingAccount = new HashMap<>();
Map<String, String> stitchingPersonName = new HashMap<>();
Map<String, LocalDate> stitchingDate = new HashMap<>();
List<StitchingOfflineItem> stitchingOfflineItems = stitchingOfflineItemDAO.findByJobCardId(Long.parseLong(jobCardID));
if (stitchingOfflineItems.isEmpty()) {
return stitchingDetails;
}
Map<Long, StitchingOfflineItem> stitchingOfflineItemMap = stitchingOfflineItems.stream()
.collect(Collectors.toMap(StitchingOfflineItem::getId, Function.identity()));
List<Long> stitchingItemsArray = new ArrayList<>(stitchingOfflineItemMap.keySet());
List<InventoryTransactionLeg> inventoryTransactionLegs = inventoryTransactionLegDAO
.getTransactionByParentIdAndType(stitchingItemsArray, "STITCHING_OFFLINE");
for (InventoryTransactionLeg inventoryTransactionLeg : inventoryTransactionLegs) {
Integer accountId = inventoryTransactionLeg.getAccountId();
InventoryAccount inventoryAccount = inventoryAccountDAO.find(accountId.longValue());
if (inventoryAccount != null) {
String accountTitle = inventoryAccount.getTitle();
stitchingAccount.put(accountTitle, inventoryAccount);
StitchingOfflineItem stitchingOfflineItem = stitchingOfflineItemMap.get(inventoryTransactionLeg.getParentDocumentId());
stitchingPersonName.put(accountTitle, (stitchingOfflineItem != null) ? stitchingOfflineItem.getCreatedBy() : null);
stitchingDate.put(accountTitle,(stitchingOfflineItem != null) ? stitchingOfflineItem.getCreatedAt().toLocalDate() : null);
}
}
stitchingDetails.put("accounts", new HashMap<>(stitchingAccount));
stitchingDetails.put("personName", new HashMap<>(stitchingPersonName));
stitchingDetails.put("date", new HashMap<>(stitchingDate));
return stitchingDetails;
}
private StringBuilder generateTime(LocalDateTime startDate, LocalDateTime endDate){
StringBuilder totalTime = new StringBuilder();
if(startDate != null && endDate != null){
Duration duration = Duration.between(startDate, endDate);
if (duration.toDays() > 0) {
totalTime.append(String.format("%d days, ", duration.toDays()));
}
if (duration.toHours() % 24 > 0) {
totalTime.append(String.format("%d hours, ", duration.toHours() % 24));
}
if (duration.toMinutes() % 60 > 0) {
totalTime.append(String.format("%d minutes ", duration.toMinutes() % 60));
}
return totalTime;
}else return totalTime.append("");
}
}