diff --git a/src/main/java/com/utopiaindustries/controller/ReportingController.java b/src/main/java/com/utopiaindustries/controller/ReportingController.java index 51a4708..2aaf425 100644 --- a/src/main/java/com/utopiaindustries/controller/ReportingController.java +++ b/src/main/java/com/utopiaindustries/controller/ReportingController.java @@ -2,6 +2,7 @@ package com.utopiaindustries.controller; import com.utopiaindustries.auth.CuttingRole; import com.utopiaindustries.auth.ReportingRole; +import com.utopiaindustries.model.ctp.JobCardItem; import com.utopiaindustries.model.ctp.SummaryInventoryReport; import com.utopiaindustries.service.ReportingService; import com.utopiaindustries.service.SummaryInventoryReportService; @@ -9,6 +10,7 @@ import com.utopiaindustries.util.StringUtils; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @@ -17,6 +19,7 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Controller @ReportingRole @@ -64,6 +67,18 @@ public class ReportingController { return "/reporting/job-card-report"; } + @GetMapping( "/po-report") + public String poReport( Model model){ + model.addAttribute("allPOs", reportingService.getAllPOs()); + return "/reporting/po-report"; + } + + @GetMapping( value = "/po-report-view/{poNo}" ) + public String showJobCardDetail( @PathVariable("poNo") String poNo, @RequestParam(value = "select-date", required = false) String selectDate , + Model model ){ + model.addAttribute("allJobCard", reportingService.getAllPoJobCards(poNo, selectDate)); + return "/reporting/po-job-card-report"; + } private ArrayList generateDateList(LocalDate start, LocalDate end) { ArrayList localDates = new ArrayList<>(); diff --git a/src/main/java/com/utopiaindustries/dao/ctp/BundleDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/BundleDAO.java index 7ee6db9..7efbc0f 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/BundleDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/BundleDAO.java @@ -31,6 +31,7 @@ public class BundleDAO { private final String SELECT_LIKE_BARCODE = String.format("SELECT * FROM %s WHERE barcode LIKE :barcode", TABLE_NAME); private final String SELECT_FIRST_BUNDLE_BY_JOB_CARD = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id ORDER BY created_at ASC LIMIT 1", TABLE_NAME); private final String SELECT_LAST_BUNDLE_BY_JOB_CARD = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id ORDER BY created_at DESC LIMIT 1", TABLE_NAME); + private final String SELECT_BY_JOB_CARD_AND_DATE = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR created_at BETWEEN :start_date AND :end_date)", TABLE_NAME ); public BundleDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; @@ -161,4 +162,12 @@ public class BundleDAO { .findFirst().orElse(new Bundle()); } + public List findByCardIdAndDATE( long cardId, String startDate, String endDate){ + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("job_card_id", cardId ); + params.addValue( "start_date", startDate ); + params.addValue( "end_date", endDate ); + return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE, params, new BundleRowMapper() ); + } + } \ No newline at end of file diff --git a/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java index 0063843..8addfd6 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java @@ -33,6 +33,7 @@ public class FinishedItemDAO { private final String SELECT_BY_STITCHED_ITEM_ID = String.format( "SELECT * FROM %s WHERE stitched_item_id = :stitched_item_id", TABLE_NAME ); private final String SELECT_BY_STITCHED_ITEM_IDS = String.format( "SELECT * FROM %s WHERE stitched_item_id IN (:stitched_item_ids)", TABLE_NAME ); private final String COUNT_TOTAL_FINISH_ITEM= String.format("SELECT COUNT(*) FROM %s WHERE job_card_id = :job_card_id AND is_segregated IS TRUE ",TABLE_NAME); + private final String SELECT_BY_JOB_CARD_AND_DATE = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR created_at BETWEEN :start_date AND :end_date)", TABLE_NAME ); public FinishedItemDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; @@ -176,4 +177,13 @@ public class FinishedItemDAO { Long count = namedParameterJdbcTemplate.queryForObject(COUNT_TOTAL_FINISH_ITEM, params, Long.class); return count != null ? count : 0; } + + public List calculateTotalFinishItem( long jobCardId, String startDate, String endDate ){ + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("job_card_id", jobCardId ); + params.addValue( "start_date", startDate ); + params.addValue( "end_date", endDate ); + return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE, params, new FinishedItemRowMapper() ); + } + } \ No newline at end of file diff --git a/src/main/java/com/utopiaindustries/dao/ctp/InventoryTransactionLegDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/InventoryTransactionLegDAO.java index 9b3667c..8c15a7b 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/InventoryTransactionLegDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/InventoryTransactionLegDAO.java @@ -49,6 +49,7 @@ public class InventoryTransactionLegDAO { private final String SELECT_FIRST_TRANSACTION_PARENT_TYPE_PARENT_ID = String.format("SELECT * FROM %s WHERE parent_document_id IN (:parent_document_id) AND parent_document_type = :parent_document_type ORDER BY transaction_leg_datetime ASC LIMIT 1", TABLE_NAME); private final String SELECT_GROUP_By_TRANSACTION_PARENT_TYPE_PARENT_ID = String.format("SELECT * FROM %s WHERE parent_document_id IN (:parent_document_id) AND parent_document_type = :parent_document_type GROUP BY account_id", TABLE_NAME); private final String SELECT_JOB_CARD_DATES = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR transaction_leg_datetime BETWEEN :start_date AND :end_date) AND type = :type ", TABLE_NAME); + private final String SELECT_JOB_CARD_And_Date_Type_Account_Id = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR transaction_leg_datetime BETWEEN :start_date AND :end_date) AND type = :type AND account_id IN (:account_ids)", TABLE_NAME); public InventoryTransactionLegDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; @@ -197,6 +198,20 @@ public class InventoryTransactionLegDAO { params.addValue("start_date", startDate ); params.addValue("end_date", endDate ); params.addValue("type", type ); + System.out.println("Start Date: " + startDate); + System.out.println("End Date: " + endDate); + + System.out.println("Params: " + params.getValues()); return namedParameterJdbcTemplate.query( SELECT_JOB_CARD_DATES , params, new InventoryTransactionLegRowMapper() ); } + + public List getTransactionByJobCardAndDatesAndTypeAndAccountID(long jobCardID, String startDate, String endDate, String type, List accountId){ + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("job_card_id", jobCardID ); + params.addValue("start_date", startDate ); + params.addValue("end_date", endDate ); + params.addValue("type", type ); + params.addValue("account_ids", accountId ); + return namedParameterJdbcTemplate.query( SELECT_JOB_CARD_And_Date_Type_Account_Id , params, new InventoryTransactionLegRowMapper() ); + } } \ No newline at end of file diff --git a/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java index 6ce2d34..71a3b85 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java @@ -28,7 +28,6 @@ public class JobCardDAO { private final String SELECT_BY_LIKE_CODE = String.format( "SELECT * FROM %s WHERE code like :code", TABLE_NAME ); private final String SELECT_BY_LIMIT = String.format( "SELECT * FROM %s WHERE created_by = :created_by ORDER BY id DESC limit :limit", TABLE_NAME ); - // prepare query params private MapSqlParameterSource prepareInsertQueryParams( JobCard jobCard ) { MapSqlParameterSource params = new MapSqlParameterSource(); diff --git a/src/main/java/com/utopiaindustries/dao/ctp/StitchingOfflineItemDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/StitchingOfflineItemDAO.java index 390103d..89aac52 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/StitchingOfflineItemDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/StitchingOfflineItemDAO.java @@ -31,6 +31,7 @@ public class StitchingOfflineItemDAO { private final String SELECT_BY_MASTER_ID = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id", TABLE_NAME ); private final String COUNT_TOTAL_QA_ITEMS= String.format("SELECT COUNT(*) FROM %s WHERE job_card_id = :job_card_id AND is_qa IS TRUE",TABLE_NAME); private final String SELECT_BY_TIME_AND_CARD_ID= String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id ORDER BY created_at DESC LIMIT 1;",TABLE_NAME); + private final String SELECT_BY_JOB_CARD_AND_DATE = String.format( "SELECT * FROM %s WHERE job_card_id = :job_card_id AND (:start_date IS NULL OR :end_date IS NULL OR created_at BETWEEN :start_date AND :end_date)", TABLE_NAME ); public StitchingOfflineItemDAO(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; @@ -160,4 +161,12 @@ public class StitchingOfflineItemDAO { .findFirst() .orElse( new StitchingOfflineItem() ); } + + public List findByJobCardIdAndDate(long jobCardId, String startDate, String endDate){ + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue( "job_card_id", jobCardId ); + params.addValue( "start_date", startDate ); + params.addValue( "end_date", endDate ); + return namedParameterJdbcTemplate.query( SELECT_BY_JOB_CARD_AND_DATE , params, new StitchingOfflineItemRowMapper() ); + } } diff --git a/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java b/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java new file mode 100644 index 0000000..a16d7aa --- /dev/null +++ b/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java @@ -0,0 +1,147 @@ +package com.utopiaindustries.model.ctp; + +public class POsDetails { + private String poNumber; + private String articleTitle; + private long poQuantity; + private long totalCutting; + private long remainingCutting; + private long totalStitching; + private long remainingStitching; + private long totalEndLineQC; + private long remainingEndLineQC; + private long totalFinishing; + private long remainingFinishing; + private long totalAGradeItem; + private long totalBGradeItem; + private long totalCGradeItem; + + public long getPoQuantity() { + return poQuantity; + } + + public void setPoQuantity(long poQuantity) { + this.poQuantity = poQuantity; + } + + public String getPoNumber() { + return poNumber; + } + + public void setPoNumber(String poNumber) { + this.poNumber = poNumber; + } + + public String getArticleTitle() { + return articleTitle; + } + + public void setArticleTitle(String articleTitle) { + this.articleTitle = articleTitle; + } + + public long getTotalCutting() { + return totalCutting; + } + + public void setTotalCutting(long totalCutting) { + this.totalCutting = totalCutting; + } + + public long getRemainingCutting() { + return remainingCutting; + } + + public void setRemainingCutting(long remainingCutting) { + this.remainingCutting = remainingCutting; + } + + public long getTotalStitching() { + return totalStitching; + } + + public void setTotalStitching(long totalStitching) { + this.totalStitching = totalStitching; + } + + public long getRemainingStitching() { + return remainingStitching; + } + + public void setRemainingStitching(long remainingStitching) { + this.remainingStitching = remainingStitching; + } + + public long getTotalEndLineQC() { + return totalEndLineQC; + } + + public void setTotalEndLineQC(long totalEndLineQC) { + this.totalEndLineQC = totalEndLineQC; + } + + public long getRemainingEndLineQC() { + return remainingEndLineQC; + } + + public void setRemainingEndLineQC(long remainingEndLineQC) { + this.remainingEndLineQC = remainingEndLineQC; + } + + public long getTotalFinishing() { + return totalFinishing; + } + + public void setTotalFinishing(long totalFinishing) { + this.totalFinishing = totalFinishing; + } + + public long getRemainingFinishing() { + return remainingFinishing; + } + + public void setRemainingFinishing(long remainingFinishing) { + this.remainingFinishing = remainingFinishing; + } + + public long getTotalAGradeItem() { + return totalAGradeItem; + } + + public void setTotalAGradeItem(long totalAGradeItem) { + this.totalAGradeItem = totalAGradeItem; + } + + public long getTotalBGradeItem() { + return totalBGradeItem; + } + + public void setTotalBGradeItem(long totalBGradeItem) { + this.totalBGradeItem = totalBGradeItem; + } + + public long getTotalCGradeItem() { + return totalCGradeItem; + } + + public void setTotalCGradeItem(long totalCGradeItem) { + this.totalCGradeItem = totalCGradeItem; + } + + @Override + public String toString() { + return "POsDetails{" + + "totalCutting=" + totalCutting + + ", remainingCutting=" + remainingCutting + + ", totalStitching=" + totalStitching + + ", remainingStitching=" + remainingStitching + + ", totalEndLineQC=" + totalEndLineQC + + ", remainingEndLineQC=" + remainingEndLineQC + + ", totalFinishing=" + totalFinishing + + ", remainingFinishing=" + remainingFinishing + + ", totalAGradeItem=" + totalAGradeItem + + ", totalBGradeItem=" + totalBGradeItem + + ", totalCGradeItem=" + totalCGradeItem + + '}'; + } +} diff --git a/src/main/java/com/utopiaindustries/service/ReportingService.java b/src/main/java/com/utopiaindustries/service/ReportingService.java index 4e1a158..acaa4df 100644 --- a/src/main/java/com/utopiaindustries/service/ReportingService.java +++ b/src/main/java/com/utopiaindustries/service/ReportingService.java @@ -46,12 +46,13 @@ public class ReportingService { this.inventoryAccountDAO = inventoryAccountDAO; } - public Map getJobCardProgress(String jobCardID){ - if (jobCardID == null){ - return new HashMap<>(); - }else { - HashMap totalProgress = new HashMap<>(); + public Map getJobCardProgress(String jobCardID) { + if (jobCardID == null) { + return new LinkedHashMap<>(); + } else { + Map totalProgress = new HashMap<>(); List jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID)); + BigDecimal totalProduction = jobCardItems.stream() .map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO)) .reduce(BigDecimal.ZERO, BigDecimal::add); @@ -64,64 +65,87 @@ public class ReportingService { .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()); - + // Cutting Progress Calculation + if (actualProduction.compareTo(BigDecimal.ZERO) == 0) { + totalProgress.put("Cutting Progress", 0); } else if (actualProduction.compareTo(expectedProduction) < 0) { - BigDecimal cuttingProgress = expectedProduction - .divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP) + BigDecimal cuttingProgress = actualProduction + .divide(expectedProduction, 4, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(100)); totalProgress.put("Cutting Progress", cuttingProgress.intValue()); - }else if (actualProduction.compareTo(expectedProduction) > 0 || actualProduction.compareTo(expectedProduction) == 0){ + } else { totalProgress.put("Cutting Progress", 100); } - if (totalProduction.compareTo(BigDecimal.ZERO) == 0){ - totalProgress.put("Stitching Progress", BigDecimal.ZERO.intValue()); - }else { + // Stitching Progress Calculation + if (totalProduction.compareTo(BigDecimal.ZERO) == 0) { + totalProgress.put("Stitching Progress", 0); + } else { BigDecimal stitchingProgress = totalProduction - .divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP) + .divide(actualProduction, 4, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(100)); totalProgress.put("Stitching Progress", stitchingProgress.intValue()); } + + // QA Progress Calculation Long qaProgressItems = stitchingOfflineItemDAO.CalculateTotalQA(Long.parseLong(jobCardID)); - if (qaProgressItems == 0){ - totalProgress.put("QA Progress", 0); - }else { + if (qaProgressItems == 0) { + totalProgress.put("QA Progress", 0); + } else { BigDecimal qaProgress = BigDecimal.valueOf(qaProgressItems) - .divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP) + .divide(actualProduction, 4, RoundingMode.HALF_UP) .multiply(BigDecimal.valueOf(100)); totalProgress.put("QA Progress", qaProgress.intValue()); } + + // Finishing Progress Calculation Long totalFinishItem = finishedItemDAO.calculateTotalFinishItem(Long.parseLong(jobCardID)); - if (totalFinishItem == 0){ - totalProgress.put("Finishing Progress", BigDecimal.ZERO.intValue()); - }else { + if (totalFinishItem == 0) { + totalProgress.put("Finishing Progress", 0); + } else { BigDecimal finishItemProgress = BigDecimal.valueOf(totalFinishItem) - .divide(actualProduction, 4, BigDecimal.ROUND_HALF_UP) + .divide(actualProduction, 4, RoundingMode.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()); + // Job Card Progress Calculation + if (totalProduction.compareTo(BigDecimal.ZERO) == 0 && actualProduction.compareTo(BigDecimal.ZERO) == 0) { + totalProgress.put("Job Card Progress", 0); } else { - if (actualProduction.compareTo(expectedProduction)>0){ - BigDecimal progressPercentage = actualProduction.add(totalProduction).add(BigDecimal.valueOf(qaProgressItems)).add(BigDecimal.valueOf(totalFinishItem)) + BigDecimal progressPercentage; + if (actualProduction.compareTo(expectedProduction) > 0) { + 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)) + } else { + 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()); } + totalProgress.put("Job Card Progress", progressPercentage.intValue()); } - return totalProgress; + + // Sorting Map based on Custom Order + Map indexMap = new HashMap<>(); + indexMap.put("Cutting Progress", 1); + indexMap.put("Stitching Progress", 2); + indexMap.put("QA Progress", 3); + indexMap.put("Finishing Progress", 4); + indexMap.put("Job Card Progress", 5); + + return totalProgress.entrySet() + .stream() + .sorted(Comparator.comparingInt(entry -> indexMap.get(entry.getKey()))) + .collect(LinkedHashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), Map::putAll); } } + public Integer getTotalProduction(String jobCardID){ if (jobCardID == null){ return 0; @@ -135,12 +159,13 @@ public class ReportingService { } } - public Map getCompleteProduction(String jobCardID){ - if (jobCardID == null){ - return new HashMap<>(); - }else { - HashMap totalProgress = new HashMap<>(); + public Map getCompleteProduction(String jobCardID) { + if (jobCardID == null) { + return new LinkedHashMap<>(); + } else { + HashMap totalProgress = new HashMap<>(); List jobCardItems = jobCardItemDAO.findByCardId(Long.parseLong(jobCardID)); + BigDecimal totalProduction = jobCardItems.stream() .map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO)) .reduce(BigDecimal.ZERO, BigDecimal::add); @@ -149,22 +174,37 @@ public class ReportingService { .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)); + // Get Job card Complete Items + Map jobCardCompleteItems = getSegregateItems(jobCardID); + Integer segregateTotalItems = jobCardCompleteItems.values().stream().mapToInt(Integer::intValue).sum(); + + // Add values to totalProgress map totalProgress.put("Cutting Progress", actualProduction.intValue()); totalProgress.put("Stitching Progress", totalProduction.intValue()); - totalProgress.put("QA Progress", qaProgressItems.intValue()); + totalProgress.put("QA Progress", qaProgressItems.intValue()); totalProgress.put("Finishing Progress", totalFinishItem.intValue()); + totalProgress.put("Job Card Progress", segregateTotalItems); - return totalProgress; + //custom order + Map indexMap = new HashMap<>(); + indexMap.put("Job Card Progress", 1); + indexMap.put("Cutting Progress", 2); + indexMap.put("Stitching Progress", 3); + indexMap.put("Finishing Progress", 4); + indexMap.put("QA Progress", 5); + + // Sort the keys based on custom order + return totalProgress.entrySet() + .stream() + .sorted(Comparator.comparingInt(entry -> indexMap.get(entry.getKey()))) + .collect(LinkedHashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), Map::putAll); } } + public Map getSegregateItems(String jobCardID){ if (jobCardID == null){ return new HashMap<>(); @@ -175,6 +215,9 @@ public class ReportingService { List finishItemsIds = finishedItems.stream() .map(FinishedItem::getId).collect(Collectors.toList()); if (finishItemsIds.isEmpty()){ + gradingItems.put("A GRADE",0); + gradingItems.put("B GRADE",0); + gradingItems.put("C GRADE",0); return gradingItems; }else { for (InventoryAccount inventoryAccount : inventoryAccounts){ @@ -399,7 +442,139 @@ public class ReportingService { return barChartData; } + public List getAllPOs() { + List pOsDetailsList = new ArrayList<>(); + List jobCards = jobCardDAO.findAll() ; + HashMap> filterJobCardsByPos = jobCards.stream() + .collect(Collectors.groupingBy( + JobCard::getPurchaseOrderId, + HashMap::new, + Collectors.toList() + )); + Map jobCardCompleteItems = new HashMap<>(); + for (String pos : filterJobCardsByPos.keySet()) { + BigDecimal totalProduction = BigDecimal.ZERO; + BigDecimal actualProduction = BigDecimal.ZERO; + Long qaProgressItems = 0L; + Long totalFinishItem = 0L; + POsDetails pOsDetails = new POsDetails(); + for (JobCard jobCard : filterJobCardsByPos.get(pos)) { + List jobCardItems = jobCardItemDAO.findByCardId(jobCard.getId()); + totalProduction = totalProduction.add(jobCardItems.stream() + .map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO)) + .reduce(BigDecimal.ZERO, BigDecimal::add)); + + actualProduction = actualProduction.add(jobCardItems.stream() + .map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO)) + .reduce(BigDecimal.ZERO, BigDecimal::add)); + + qaProgressItems += Optional.ofNullable(stitchingOfflineItemDAO.CalculateTotalQA(jobCard.getId())).orElse(0L); + totalFinishItem += Optional.ofNullable(finishedItemDAO.calculateTotalFinishItem(jobCard.getId())).orElse(0L); + + jobCardCompleteItems = getSegregateItems(String.valueOf(jobCard.getId())); + if (jobCardCompleteItems == null) { + jobCardCompleteItems = new HashMap<>(); + } + } + + pOsDetails.setPoNumber(pos); + pOsDetails.setPoQuantity(100); + pOsDetails.setTotalCutting(actualProduction.intValue()); + pOsDetails.setTotalStitching(totalProduction.intValue()); + pOsDetails.setTotalEndLineQC(qaProgressItems.intValue()); + pOsDetails.setTotalFinishing(totalFinishItem); + + pOsDetails.setRemainingCutting(100 - actualProduction.intValue()); + pOsDetails.setRemainingStitching(100 - totalProduction.intValue()); + pOsDetails.setRemainingEndLineQC(100 - qaProgressItems); + pOsDetails.setRemainingFinishing(100 - totalFinishItem); + + pOsDetails.setTotalAGradeItem(jobCardCompleteItems.getOrDefault("A GRADE", 0)); + pOsDetails.setTotalBGradeItem(jobCardCompleteItems.getOrDefault("B GRADE", 0)); + pOsDetails.setTotalCGradeItem(jobCardCompleteItems.getOrDefault("C GRADE", 0)); + + pOsDetailsList.add(pOsDetails); + } + return pOsDetailsList; + } + + public HashMap> getAllPoJobCards(String PONumber, String selectDate) { + String startDate = selectDate != null && !selectDate.isEmpty() ? selectDate + " 00:00:01": null; + String endDate = selectDate != null && !selectDate.isEmpty() ? selectDate + " 23:59:59": null; + + HashMap> poJobCardItemsProgress = new HashMap<>(); + List jobCards = jobCardDAO.findAll(); + // Filter JobCards by Purchase Order ID + List filterJobCardsByPos = jobCards.stream() + .filter(e -> e.getPurchaseOrderId().equals(PONumber)) + .collect(Collectors.toList()); + List inventoryAccounts = inventoryAccountDAO.getPackagingAccounts(); + List gradingAccounts = inventoryAccounts.stream().map(e-> (int)(e.getId())).collect(Collectors.toList()); + for (JobCard jobCard : filterJobCardsByPos) { + List bundles = bundleDAO.findByCardIdAndDATE(jobCard.getId(),startDate,endDate); + List stitchingOfflineItems = stitchingOfflineItemDAO.findByJobCardIdAndDate(jobCard.getId(),startDate,endDate); + List finishedItems = finishedItemDAO.calculateTotalFinishItem(jobCard.getId(),startDate,endDate); + List inventoryTransactionLegs = inventoryTransactionLegDAO.getTransactionByJobCardAndDatesAndTypeAndAccountID(jobCard.getId(),startDate,endDate,"IN", gradingAccounts); + + //cutting days wise + BigDecimal cutting = bundles.stream() + .map(bundle -> Optional.ofNullable(bundle.getWrapQuantity()).orElse(BigDecimal.ZERO)) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + //stitching day wise + Integer stitching = stitchingOfflineItems.size(); + + Integer qa = finishedItems.size(); + Map segregateItems = inventoryTransactionLegs.stream() + .filter(leg -> inventoryAccounts.stream() + .anyMatch(account -> (int) account.getId() == (leg.getAccountId()))) + .collect(Collectors.toMap( + leg -> inventoryAccounts.stream() + .filter(account -> (int) account.getId() == (leg.getAccountId())) + .findFirst() + .map(InventoryAccount::getTitle) + .orElse("Unknown"), + leg -> leg.getQuantity().intValue(), + Integer::sum, + HashMap::new + )); + Map items = getCompleteProduction(String.valueOf(jobCard.getId())); + items.put("Cutting Progress",cutting.intValue()); + items.put("Stitching Progress",stitching); + items.put("QA Progress",qa); + items.put("A Grade",segregateItems.get("A GRADE") != null ? segregateItems.get("A GRADE") : 0); + items.put("B Grade",segregateItems.get("B GRADE") != null ? segregateItems.get("B GRADE") : 0); + items.put("C Grade",segregateItems.get("C GRADE") != null ? segregateItems.get("C GRADE") : 0); + + // Define sorting order + Map indexMap = new HashMap<>(); + indexMap.put("Job Card Progress", 1); + indexMap.put("Cutting Progress", 2); + indexMap.put("Stitching Progress", 3); + indexMap.put("QA Progress", 4); + indexMap.put("Finishing Progress", 5); + indexMap.put("A GRADE", 6); + indexMap.put("B GRADE", 7); + indexMap.put("C GRADE", 8); + + // Sort items based on indexMap order + Map sortedItems = items.entrySet() + .stream() + .sorted(Comparator.comparingInt(entry -> indexMap.getOrDefault(entry.getKey(), Integer.MAX_VALUE))) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (oldValue, newValue) -> oldValue, + LinkedHashMap::new + )); + + // Add sorted items to the result map + poJobCardItemsProgress.put(jobCard.getCode(), sortedItems); + } + + return poJobCardItemsProgress; + } private StringBuilder generateTime(LocalDateTime startDate, LocalDateTime endDate){ StringBuilder totalTime = new StringBuilder(); diff --git a/src/main/resources/static/js/charts.js b/src/main/resources/static/js/charts.js index 88d82b8..c9887e2 100644 --- a/src/main/resources/static/js/charts.js +++ b/src/main/resources/static/js/charts.js @@ -73,8 +73,6 @@ document.addEventListener("DOMContentLoaded", function () { if (!document.getElementById(divId)) { return; } - console.log(maxValue); - Highcharts.chart(divId, { chart: { type: 'column', @@ -153,6 +151,7 @@ document.addEventListener("DOMContentLoaded", function () { const total = div.getAttribute('data-totalProduction'); const actual = div.getAttribute('data-actualProduction'); const divId = div.id; + console.log(actual) createGaugeChart(parseInt(progress), color, divId, title, height, width, fontSize, -20, 4, fontColor, total, actual); }); const gaugeDivs = document.querySelectorAll('.gauge-chart'); @@ -191,7 +190,6 @@ document.addEventListener("DOMContentLoaded", function () { const dates = div.getAttribute('data-dates'); const datesArray = dates.split(','); const divId = div.id; - console.log(maxValue, typeof maxValue) createBarChart( divId, height, width, title,aHeading,aData,bHeading,bData,cHeading,cData,dHeading,dData,datesArray,fontSize,maxValue); }); } diff --git a/src/main/resources/templates/_fragments.html b/src/main/resources/templates/_fragments.html index 6e69f52..dc808c2 100644 --- a/src/main/resources/templates/_fragments.html +++ b/src/main/resources/templates/_fragments.html @@ -132,6 +132,10 @@