diff --git a/src/main/java/com/utopiaindustries/controller/POStatusController.java b/src/main/java/com/utopiaindustries/controller/POStatusController.java new file mode 100644 index 0000000..e60301a --- /dev/null +++ b/src/main/java/com/utopiaindustries/controller/POStatusController.java @@ -0,0 +1,56 @@ +package com.utopiaindustries.controller; + +import com.utopiaindustries.auth.PurchaseOrderCTPRole; +import com.utopiaindustries.model.ctp.POsDetails; +import com.utopiaindustries.service.InventoryAccountService; +import com.utopiaindustries.service.PurchaseOrderService; +import com.utopiaindustries.service.ReportingService; +import com.utopiaindustries.service.SummaryInventoryReportService; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +@Controller +@RequestMapping("/po-status") +@PurchaseOrderCTPRole +public class POStatusController { + + private final ReportingService reportingService; + private final PurchaseOrderService purchaseOrderService; + + + public POStatusController(ReportingService reportingService, PurchaseOrderService purchaseOrderService) { + this.reportingService = reportingService; + this.purchaseOrderService = purchaseOrderService; + } + + @GetMapping + public String homePage( Model model ){ + return "redirect:/po-status/all-pos"; + } + + @GetMapping( "/all-pos") + public String poReport(@RequestParam(value = "poName", required = false) String poName, Model model){ + + model.addAttribute("allPOs", reportingService.getAllPOs(poName)); + return "/reporting/po-report"; + } + + @GetMapping( value = "/po-report-view/{poId}" ) + public String showJobCardDetail(@PathVariable("poId") long poId, @RequestParam(value = "select-date", required = false) String selectDate , + Model model ){ + model.addAttribute("allJobCard", reportingService.getAllPoJobCards(poId, selectDate)); + return "/reporting/po-job-card-report"; + } + + @GetMapping(value = "/generate-po-pdf", produces = MediaType.APPLICATION_PDF_VALUE) + public ResponseEntity sendPoAndReturnPdf(@ModelAttribute POsDetails pOsDetails, + @RequestParam(required = false, defaultValue = "true") boolean includeJobCard, + @RequestParam(required = false, defaultValue = "true") boolean includeStoreDetails, + Model model) throws Exception{ + return purchaseOrderService.generatePOPdf(pOsDetails, model, includeJobCard, includeStoreDetails); + } +} diff --git a/src/main/java/com/utopiaindustries/controller/PurchaseOrderCTPController.java b/src/main/java/com/utopiaindustries/controller/PurchaseOrderCTPController.java index 6656c04..140220b 100644 --- a/src/main/java/com/utopiaindustries/controller/PurchaseOrderCTPController.java +++ b/src/main/java/com/utopiaindustries/controller/PurchaseOrderCTPController.java @@ -5,6 +5,7 @@ import com.utopiaindustries.model.ctp.JobCard; import com.utopiaindustries.model.ctp.PurchaseOrderCTP; import com.utopiaindustries.service.PurchaseOrderCTPService; import com.utopiaindustries.util.StringUtils; +import org.springframework.security.core.parameters.P; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @@ -85,6 +86,11 @@ public class PurchaseOrderCTPController { return "redirect:/purchase-order"; } - + @GetMapping( "/store-items/{id}" ) + public String getPOStoreItems( @PathVariable("id") long poId, + Model model ){ + model.addAttribute("storeItems", purchaseOrderCTPService.getStoreItemsByPoId( poId )); + return "/reporting/po-store-items-table"; + } } diff --git a/src/main/java/com/utopiaindustries/controller/ReportingController.java b/src/main/java/com/utopiaindustries/controller/ReportingController.java index 31bd530..c34525b 100644 --- a/src/main/java/com/utopiaindustries/controller/ReportingController.java +++ b/src/main/java/com/utopiaindustries/controller/ReportingController.java @@ -1,17 +1,19 @@ package com.utopiaindustries.controller; import com.utopiaindustries.auth.ReportingRole; +import com.utopiaindustries.model.ctp.POsDetails; import com.utopiaindustries.model.ctp.SummaryInventoryReport; import com.utopiaindustries.service.InventoryAccountService; +import com.utopiaindustries.service.PurchaseOrderService; import com.utopiaindustries.service.ReportingService; import com.utopiaindustries.service.SummaryInventoryReportService; import com.utopiaindustries.util.StringUtils; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; 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.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import java.time.LocalDate; @@ -26,17 +28,19 @@ public class ReportingController { private final ReportingService reportingService; private final SummaryInventoryReportService summaryInventoryReportService; private final InventoryAccountService inventoryAccountService; + private final PurchaseOrderService purchaseOrderService; - public ReportingController(SummaryInventoryReportService summaryInventoryReportService2, ReportingService reportingService, InventoryAccountService inventoryAccountService) { + public ReportingController(SummaryInventoryReportService summaryInventoryReportService2, ReportingService reportingService, InventoryAccountService inventoryAccountService, PurchaseOrderService purchaseOrderService) { this.summaryInventoryReportService = summaryInventoryReportService2; this.reportingService = reportingService; this.inventoryAccountService = inventoryAccountService; + this.purchaseOrderService = purchaseOrderService; } @GetMapping public String homePage( Model model ){ - return "redirect:/reporting/po-report"; + return "redirect:/reporting/job-card-report"; } @GetMapping( "/summary") @@ -73,20 +77,6 @@ public class ReportingController { return "/reporting/job-card-report"; } - @GetMapping( "/po-report") - public String poReport(@RequestParam(value = "poName", required = false) String poName, Model model){ - - model.addAttribute("allPOs", reportingService.getAllPOs(poName)); - 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"; - } - @GetMapping( value = "/cutting-report" ) public String cuttingReport(@RequestParam(value = "job-card-id", required = false ) String jobCardId, @RequestParam(value = "accountId" , required = false) String accountId, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, Model model ){ @@ -129,7 +119,6 @@ public class ReportingController { return "/reporting/accounts-transaction-table"; } - private ArrayList generateDateList(LocalDate start, LocalDate end) { ArrayList localDates = new ArrayList<>(); while (start.isBefore(end)) { diff --git a/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java index f304f46..ec8345d 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/FinishedItemDAO.java @@ -32,7 +32,7 @@ public class FinishedItemDAO { private final String SELECT_BY_TERM_FOR_PACKAGING = String.format("SELECT * FROM %s WHERE barcode LIKE :term AND is_segregated = :is_segregated AND qa_status = :qa_status AND is_packed = FALSE AND is_store = FALSE ORDER BY ID DESC", TABLE_NAME); private final String SELECT_BY_STITCHED_ITEM_ID = String.format("SELECT * FROM %s WHERE stitched_item_id = :stitched_item_id AND is_packed = FALSE", 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 COUNT_TOTAL_FINISH_ITEM = String.format("SELECT COUNT(*) FROM %s WHERE job_card_id = :job_card_id AND is_qa = TRUE AND (is_segregated IS TRUE OR is_store = 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); private final String SELECT_BY_DATE_QA_STATUS = String.format( "SELECT COUNT(*) FROM %s WHERE (:start_date IS NULL OR operation_date >= :start_date) AND operation_date <= :end_date AND qa_status = :qa_status AND id in (:ids) AND is_packed = FALSE AND is_qa = TRUE", TABLE_NAME ); diff --git a/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java b/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java index 04e539b..80028df 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/JobCardDAO.java @@ -21,7 +21,7 @@ public class JobCardDAO { private final String TABLE_NAME = "cut_to_pack.job_card"; private final String SELECT_QUERY = String.format( "SELECT * FROM %s WHERE id = :id", TABLE_NAME ); private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ORDER BY id DESC", TABLE_NAME ); - private final String SELECT_ALL_QUERY_WITH_LIMIT = String.format( "SELECT * FROM %s ORDER BY id DESC limit :limit", TABLE_NAME ); + private final String SELECT_ALL_BY_PO_ID = String.format( "SELECT * FROM %s WHERE purchase_order_id = :purchase_order_id", TABLE_NAME ); private final String DELETE_QUERY = String.format( "DELETE FROM %s WHERE id = :id", TABLE_NAME ); private final String INSERT_QUERY = String.format( "INSERT INTO %s (id, code, job_order_id, created_at, created_by, status, inventory_status, customer, lot_number, purchase_order_id, location_site_id, description, poQuantity, articleName) VALUES (:id, :code, :job_order_id, :created_at, :created_by, :status, :inventory_status, :customer, :lot_number, :purchase_order_id, :location_site_id, :description, :poQuantity, :articleName) ON DUPLICATE KEY UPDATE code = VALUES(code), job_order_id = VALUES(job_order_id), created_at = VALUES(created_at), created_by = VALUES(created_by), status = VALUES(status), inventory_status = VALUES(inventory_status), customer = VALUES(customer), lot_number = VALUES(lot_number), purchase_order_id = VALUES(purchase_order_id), location_site_id = VALUES(location_site_id), description = VALUES(description), poQuantity = VALUES(poQuantity), articleName = VALUES(articleName) ", TABLE_NAME ); private final String SELECT_BY_LIKE_CODE_AND_INV_STATUS_AND_STATUS = String.format( "SELECT * FROM %s WHERE code like :code AND status = :status AND inventory_status = :inventory_status", TABLE_NAME ); @@ -114,9 +114,9 @@ public class JobCardDAO { return namedParameterJdbcTemplate.query( query, new JobCardRowMapper() ); } - public List findByAllWithLimit(Long limit){ + public List findByPoId(long poId){ MapSqlParameterSource params = new MapSqlParameterSource(); - params.addValue("limit", limit.intValue()); - return namedParameterJdbcTemplate.query( SELECT_ALL_QUERY_WITH_LIMIT, params, new JobCardRowMapper() ); + params.addValue("purchase_order_id", poId); + return namedParameterJdbcTemplate.query( SELECT_ALL_BY_PO_ID, params, new JobCardRowMapper() ); } } \ No newline at end of file diff --git a/src/main/java/com/utopiaindustries/dao/ctp/PurchaseOrderCTPDao.java b/src/main/java/com/utopiaindustries/dao/ctp/PurchaseOrderCTPDao.java index 686aaef..77356d7 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/PurchaseOrderCTPDao.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/PurchaseOrderCTPDao.java @@ -23,8 +23,8 @@ public class PurchaseOrderCTPDao { private final String TABLE_NAME = "cut_to_pack.purchase_order"; private final String SELECT_QUERY = String.format( "SELECT * FROM %s WHERE id = :id", TABLE_NAME ); - private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ORDER BY id DESC", TABLE_NAME ); - private final String SELECT_ALL_QUERY_WITH_LIMIT = String.format( "SELECT * FROM %s ORDER BY id DESC limit :limit", TABLE_NAME ); + private final String SELECT_ALL_QUERY = String.format( "SELECT * FROM %s ", TABLE_NAME ); + private final String SELECT_BY_PO_CODE = String.format( "SELECT * FROM %s WHERE purchase_order_code = :purchase_order_code", TABLE_NAME ); private final String DELETE_QUERY = String.format( "DELETE FROM %s WHERE id = :id", TABLE_NAME ); private final String INSERT_QUERY = String.format( "INSERT INTO %s (id, purchase_order_code, purchase_order_quantity, purchase_order_quantity_required, article_name, created_by, status) " + @@ -107,10 +107,10 @@ public class PurchaseOrderCTPDao { return namedParameterJdbcTemplate.query( SELECT_BY_LIMIT, params, new PurchaseOrderCTPRowMapper() ); } - public List findByAllWithLimit(Long limit){ + public List findByPoCode(String poCode){ MapSqlParameterSource params = new MapSqlParameterSource(); - params.addValue("limit", limit.intValue()); - return namedParameterJdbcTemplate.query( SELECT_ALL_QUERY_WITH_LIMIT, params, new PurchaseOrderCTPRowMapper() ); + params.addValue("purchase_order_code", poCode); + return namedParameterJdbcTemplate.query( SELECT_BY_PO_CODE, params, new PurchaseOrderCTPRowMapper() ); } /* diff --git a/src/main/java/com/utopiaindustries/dao/ctp/StoreItemDao.java b/src/main/java/com/utopiaindustries/dao/ctp/StoreItemDao.java index 7c06da3..65f6cc1 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/StoreItemDao.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/StoreItemDao.java @@ -1,6 +1,5 @@ package com.utopiaindustries.dao.ctp; -import com.utopiaindustries.model.ctp.PackagingItems; import com.utopiaindustries.model.ctp.StoreItem; import com.utopiaindustries.util.KeyHolderFunctions; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; @@ -10,7 +9,9 @@ import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Repository public class StoreItemDao { @@ -23,25 +24,24 @@ public class StoreItemDao { private static final String SELECT_ALL = String.format("SELECT * FROM %s ORDER BY id DESC", TABLE_NAME); private static final String DELETE_BY_ID = String.format("DELETE FROM %s WHERE id = :id", TABLE_NAME); private static final String SELECT_BY_JOB_CARD_ID = String.format("SELECT * FROM %s WHERE job_card_id = :job_card_id", TABLE_NAME); + private final String COUNT_TOTAL_FINISH_ITEM = String.format("SELECT COUNT(*) FROM %s WHERE job_card_id = :job_card_id", TABLE_NAME); private static final String INSERT_QUERY = String.format( "INSERT INTO %s (" + "id, item_id, sku, barcode, job_card_id, created_at, created_by, " + - "finish_item_id, account_id, bundle_id" + + "finish_item_id, account_id, bundle_id, reject_reason" + ") VALUES (" + ":id, :item_id, :sku, :barcode, :job_card_id, :created_at, :created_by, " + - ":finish_item_id, :account_id, :bundle_id" + + ":finish_item_id, :account_id, :bundle_id, :reject_reason" + ") ON DUPLICATE KEY UPDATE " + "item_id = VALUES(item_id), sku = VALUES(sku), barcode = VALUES(barcode), " + "job_card_id = VALUES(job_card_id), created_at = VALUES(created_at), created_by = VALUES(created_by), " + - "finish_item_id = VALUES(finish_item_id), account_id = VALUES(account_id), bundle_id = VALUES(bundle_id)", + "finish_item_id = VALUES(finish_item_id), account_id = VALUES(account_id), bundle_id = VALUES(bundle_id), reject_reason = VALUES(reject_reason)", TABLE_NAME ); + String SELECT_BY_JOB_CARD_GROUP_REJECT_REASON = String.format("SELECT reject_reason, COUNT(*) AS total FROM %s WHERE job_card_id IN (:job_card_id) GROUP BY reject_reason", TABLE_NAME); - private static final String SELECT_BY_DATE_AND_IDs = String.format( - "SELECT COUNT(*) FROM %s WHERE (:start_date IS NULL OR created_at >= :start_date) AND created_at <= :end_date AND id IN (:ids)", - TABLE_NAME - ); + private static final String SELECT_BY_DATE_AND_IDs = String.format("SELECT COUNT(*) FROM %s WHERE (:start_date IS NULL OR created_at >= :start_date) AND created_at <= :end_date AND id IN (:ids)", TABLE_NAME); public StoreItemDao(NamedParameterJdbcTemplate namedParameterJdbcTemplate) { this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; @@ -58,7 +58,8 @@ public class StoreItemDao { .addValue("created_by", item.getCreatedBy()) .addValue("finish_item_id", item.getFinishedItemId()) .addValue("account_id", item.getAccountId()) - .addValue("bundle_id", item.getBundleId()); + .addValue("bundle_id", item.getBundleId()) + .addValue("reject_reason", item.getRejectedReason()); } public StoreItem find(long id) { @@ -96,6 +97,13 @@ public class StoreItemDao { return namedParameterJdbcTemplate.query(SELECT_BY_JOB_CARD_ID, params, new StoreItemRowMapper()); } + public Long calculateTotalRejectItemByJobCardId(long jobCardId) { + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("job_card_id", jobCardId); + Long count = namedParameterJdbcTemplate.queryForObject(COUNT_TOTAL_FINISH_ITEM, params, Long.class); + return count != null ? count : 0; + } + public Long findByDateAndIds(String startDate, String endDate, List ids) { MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("start_date", startDate); @@ -104,4 +112,20 @@ public class StoreItemDao { Long count = namedParameterJdbcTemplate.queryForObject(SELECT_BY_DATE_AND_IDs, params, Long.class); return count != null ? count : 0; } + + public Map totalCountByJobCardIdsAndGroupByRejectReason(List jobCardIds) { + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("job_card_id", jobCardIds); + + List> rows = namedParameterJdbcTemplate.queryForList(SELECT_BY_JOB_CARD_GROUP_REJECT_REASON, params); + + Map result = new HashMap<>(); + for (Map row : rows) { + String reason = (String) row.get("reject_reason"); + Integer total = ((Number) row.get("total")).intValue(); + result.put(reason, total); + } + return result; + } + } diff --git a/src/main/java/com/utopiaindustries/dao/ctp/StoreItemRowMapper.java b/src/main/java/com/utopiaindustries/dao/ctp/StoreItemRowMapper.java index aee77de..cbc987e 100644 --- a/src/main/java/com/utopiaindustries/dao/ctp/StoreItemRowMapper.java +++ b/src/main/java/com/utopiaindustries/dao/ctp/StoreItemRowMapper.java @@ -21,6 +21,7 @@ public class StoreItemRowMapper implements RowMapper { item.setFinishedItemId(rs.getLong("finish_item_id")); item.setAccountId(rs.getLong("account_id")); item.setBundleId(rs.getLong("bundle_id")); + item.setRejectedReason(rs.getString("reject_reason")); return item; } } \ No newline at end of file diff --git a/src/main/java/com/utopiaindustries/model/ctp/FinishedItemWrapper.java b/src/main/java/com/utopiaindustries/model/ctp/FinishedItemWrapper.java index c9ec995..8484830 100644 --- a/src/main/java/com/utopiaindustries/model/ctp/FinishedItemWrapper.java +++ b/src/main/java/com/utopiaindustries/model/ctp/FinishedItemWrapper.java @@ -6,6 +6,7 @@ public class FinishedItemWrapper { private String qaStatus; private Long accountId; + private String rejectReason; private List items; @@ -33,6 +34,14 @@ public class FinishedItemWrapper { this.accountId = accountId; } + public String getRejectReason() { + return rejectReason; + } + + public void setRejectReason(String rejectReason) { + this.rejectReason = rejectReason; + } + @Override public String toString() { return "FinishedItemWrapper{" + diff --git a/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java b/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java index a16d7aa..467fe7b 100644 --- a/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java +++ b/src/main/java/com/utopiaindustries/model/ctp/POsDetails.java @@ -1,9 +1,14 @@ package com.utopiaindustries.model.ctp; public class POsDetails { + //po detail + private long poId; private String poNumber; private String articleTitle; private long poQuantity; + private long poRequiredQuantity; + + // items detail private long totalCutting; private long remainingCutting; private long totalStitching; @@ -15,6 +20,7 @@ public class POsDetails { private long totalAGradeItem; private long totalBGradeItem; private long totalCGradeItem; + private boolean poStatus; public long getPoQuantity() { return poQuantity; @@ -128,6 +134,30 @@ public class POsDetails { this.totalCGradeItem = totalCGradeItem; } + public long getPoId() { + return poId; + } + + public void setPoId(long poId) { + this.poId = poId; + } + + public long getPoRequiredQuantity() { + return poRequiredQuantity; + } + + public void setPoRequiredQuantity(long poRequiredQuantity) { + this.poRequiredQuantity = poRequiredQuantity; + } + + public boolean isPoStatus() { + return poStatus; + } + + public void setPoStatus(boolean poStatus) { + this.poStatus = poStatus; + } + @Override public String toString() { return "POsDetails{" + diff --git a/src/main/java/com/utopiaindustries/model/ctp/StoreItem.java b/src/main/java/com/utopiaindustries/model/ctp/StoreItem.java index f8a5f05..5ceabb2 100644 --- a/src/main/java/com/utopiaindustries/model/ctp/StoreItem.java +++ b/src/main/java/com/utopiaindustries/model/ctp/StoreItem.java @@ -18,6 +18,7 @@ public class StoreItem implements InventoryArtifact { private long finishedItemId; private long bundleId; private long accountId; + private String rejectedReason; @Override @@ -122,4 +123,29 @@ public class StoreItem implements InventoryArtifact { public void setAccountId(long accountId) { this.accountId = accountId; } + + public String getRejectedReason() { + return rejectedReason; + } + + public void setRejectedReason(String rejectedReason) { + this.rejectedReason = rejectedReason; + } + + @Override + public String toString() { + return "StoreItem{" + + "id=" + id + + ", itemId=" + itemId + + ", sku='" + sku + '\'' + + ", barcode='" + barcode + '\'' + + ", jobCardId=" + jobCardId + + ", createdAt=" + createdAt + + ", createdBy='" + createdBy + '\'' + + ", finishedItemId=" + finishedItemId + + ", bundleId=" + bundleId + + ", accountId=" + accountId + + ", rejectedReason='" + rejectedReason + '\'' + + '}'; + } } diff --git a/src/main/java/com/utopiaindustries/service/DashboardService.java b/src/main/java/com/utopiaindustries/service/DashboardService.java index 119d0bd..791a15d 100644 --- a/src/main/java/com/utopiaindustries/service/DashboardService.java +++ b/src/main/java/com/utopiaindustries/service/DashboardService.java @@ -131,6 +131,7 @@ public class DashboardService { progress.put("ALTER", (float) alterationPieceFinish); progress.put("Reject", (float) rejectFinishedItem); progress.put("wash", (float) washFinishedItem); + progress.put("finishingValueForBarChart", (float) approved + alterationPieceFinish + rejectFinishedItem + washFinishedItem + packagingItems); progress.put("packaging", (float) packagingItems); progress.put("totalPackaging", (float) packagingItemIDs.size()); diff --git a/src/main/java/com/utopiaindustries/service/InventoryService.java b/src/main/java/com/utopiaindustries/service/InventoryService.java index 5831ae7..64cd142 100644 --- a/src/main/java/com/utopiaindustries/service/InventoryService.java +++ b/src/main/java/com/utopiaindustries/service/InventoryService.java @@ -741,7 +741,7 @@ public class InventoryService { if (finishedItem.getQaStatus().equalsIgnoreCase("REJECT")) { // create OUT and IN transactions for FI - StoreItem storeItem = (createStoreItems(finishedItem)); + StoreItem storeItem = (createStoreItems(finishedItem, wrapper.getRejectReason())); storeItem.setId(storeItemDao.save(storeItem)); if (lastInvTransaction != null) { // OUT @@ -751,7 +751,7 @@ public class InventoryService { // IN createInventoryTransactionLeg(transaction, storeItem, toAccount, InventoryTransactionLeg.Type.IN.name(), InventoryArtifactType.STORED_ITEM.name()); } - finishedItem.setIsSegregated(false); + finishedItem.setIsSegregated(true); finishedItem.setStore(true); storeItems.add(storeItem); } @@ -788,7 +788,7 @@ public class InventoryService { return packagingItems; } - private StoreItem createStoreItems(FinishedItem finishedItem) { + private StoreItem createStoreItems(FinishedItem finishedItem, String reason) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); StoreItem storeItem = new StoreItem(); storeItem.setItemId(finishedItem.getItemId()); @@ -799,6 +799,7 @@ public class InventoryService { storeItem.setBarcode(finishedItem.getBarcode()); storeItem.setCreatedAt(LocalDateTime.now()); storeItem.setCreatedBy(authentication.getName()); + storeItem.setRejectedReason(reason); return storeItem; } } diff --git a/src/main/java/com/utopiaindustries/service/PurchaseOrderCTPService.java b/src/main/java/com/utopiaindustries/service/PurchaseOrderCTPService.java index 71bb926..3ec0e08 100644 --- a/src/main/java/com/utopiaindustries/service/PurchaseOrderCTPService.java +++ b/src/main/java/com/utopiaindustries/service/PurchaseOrderCTPService.java @@ -1,6 +1,8 @@ package com.utopiaindustries.service; +import com.utopiaindustries.dao.ctp.JobCardDAO; import com.utopiaindustries.dao.ctp.PurchaseOrderCTPDao; +import com.utopiaindustries.dao.ctp.StoreItemDao; import com.utopiaindustries.model.ctp.*; import com.utopiaindustries.model.uind.PurchaseOrder; import com.utopiaindustries.querybuilder.ctp.JobCardQueryBuilder; @@ -14,15 +16,22 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service public class PurchaseOrderCTPService { private final PurchaseOrderCTPDao purchaseOrderCTPDao; + private final JobCardDAO jobCardDAO; + private final StoreItemDao storeItemDao; - public PurchaseOrderCTPService(PurchaseOrderCTPDao purchaseOrderCTPDao) { + public PurchaseOrderCTPService(PurchaseOrderCTPDao purchaseOrderCTPDao, JobCardDAO jobCardDAO, StoreItemDao storeItemDao) { this.purchaseOrderCTPDao = purchaseOrderCTPDao; + this.jobCardDAO = jobCardDAO; + this.storeItemDao = storeItemDao; } /* @@ -77,4 +86,17 @@ public class PurchaseOrderCTPService { return purchaseOrderCTPDao.findByTerm( term ); } + public Map getStoreItemsByPoId(Long poId){ + Map totalItems = new HashMap<>(); + List jobCards = jobCardDAO.findByPoId(poId); + List jobCardIds = jobCards.stream() + .map(JobCard::getId) + .collect(Collectors.toList()); + if(!jobCardIds.isEmpty()){ + return storeItemDao.totalCountByJobCardIdsAndGroupByRejectReason(jobCardIds); + }else { + return totalItems; + } + } + } diff --git a/src/main/java/com/utopiaindustries/service/PurchaseOrderService.java b/src/main/java/com/utopiaindustries/service/PurchaseOrderService.java index 63ac636..6de4da8 100644 --- a/src/main/java/com/utopiaindustries/service/PurchaseOrderService.java +++ b/src/main/java/com/utopiaindustries/service/PurchaseOrderService.java @@ -1,21 +1,57 @@ package com.utopiaindustries.service; +import com.utopiaindustries.dao.ctp.StoreItemDao; import com.utopiaindustries.dao.uind.PurchaseOrderDAO; +import com.utopiaindustries.model.ctp.JobCardItem; +import com.utopiaindustries.model.ctp.POsDetails; import com.utopiaindustries.model.uind.PurchaseOrder; +import com.utopiaindustries.util.HTMLBuilder; +import com.utopiaindustries.util.PDFResponseEntityInputStreamResource; +import com.utopiaindustries.util.URLUtils; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.ui.Model; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service public class PurchaseOrderService { private final PurchaseOrderDAO purchaseOrderDAO; + private final PurchaseOrderCTPService purchaseOrderCTPService; + private final HTMLBuilder htmlBuilder; + private PDFResponseEntityInputStreamResource pdfGenerator; - public PurchaseOrderService(PurchaseOrderDAO purchaseOrderDAO) { + public PurchaseOrderService(PurchaseOrderDAO purchaseOrderDAO, PurchaseOrderCTPService purchaseOrderCTPService, HTMLBuilder htmlBuilder, PDFResponseEntityInputStreamResource pdfGenerator) { this.purchaseOrderDAO = purchaseOrderDAO; + this.purchaseOrderCTPService = purchaseOrderCTPService; + this.htmlBuilder = htmlBuilder; + this.pdfGenerator = pdfGenerator; } public List findByTerm( String term ){ return purchaseOrderDAO.findByTerm( term ); } + + /** + * Print Job card * + * **/ + public ResponseEntity generatePOPdf(POsDetails pOsDetails, Model model, boolean jobCardDetail, boolean storeDetail ) throws Exception { + Map storeItems = purchaseOrderCTPService.getStoreItemsByPoId(pOsDetails.getPoId()); + model.addAttribute("poDetail", pOsDetails); + model.addAttribute( "baseUrl", URLUtils.getCurrentBaseUrl() ); + if (storeDetail && !storeItems.isEmpty()){ + model.addAttribute("showStore", true); + model.addAttribute("store", storeItems); + }else { + model.addAttribute("showStore", false); + } + String htmlStr = htmlBuilder.buildHTML( "po-status-pdf", model ); + // return pdf + return pdfGenerator.generatePdf( htmlStr, "Po-status", "inline" ); + } + } diff --git a/src/main/java/com/utopiaindustries/service/ReportingService.java b/src/main/java/com/utopiaindustries/service/ReportingService.java index bd16c24..5f3f15b 100644 --- a/src/main/java/com/utopiaindustries/service/ReportingService.java +++ b/src/main/java/com/utopiaindustries/service/ReportingService.java @@ -22,31 +22,25 @@ import java.util.stream.Collectors; public class ReportingService { private final JobCardItemDAO jobCardItemDAO; - private final ProcessDAO processDAO; 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; - private final PackagingItemsDAO packagingItemsDAO; + private final PurchaseOrderCTPDao purchaseOrderCTPDao; + private final StoreItemDao storeItemDao; - public ReportingService(JobCardItemDAO jobCardItemDAO, ProcessDAO processDAO, BundleDAO bundleDAO, InventoryTransactionLegDAO inventoryTransactionLegDAO, InventoryTransactionDAO inventoryTransactionDAO, JobCardDAO jobCardDAO, CryptographyService cryptographyService, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, InventoryAccountDAO inventoryAccountDAO, PackagingItemsDAO packagingItemsDAO) { + public ReportingService(JobCardItemDAO jobCardItemDAO, BundleDAO bundleDAO, InventoryTransactionLegDAO inventoryTransactionLegDAO, JobCardDAO jobCardDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, InventoryAccountDAO inventoryAccountDAO, PurchaseOrderCTPDao purchaseOrderCTPDao, StoreItemDao storeItemDao) { this.jobCardItemDAO = jobCardItemDAO; - this.processDAO = processDAO; 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; - this.packagingItemsDAO = packagingItemsDAO; + this.purchaseOrderCTPDao = purchaseOrderCTPDao; + this.storeItemDao = storeItemDao; } public Map getJobCardProgress(String jobCardID) { @@ -216,7 +210,7 @@ public class ReportingService { List finishedItems = finishedItemDAO.findByJobCardId(Long.parseLong(jobCardID)); List bGradeFinishItemsIds= finishedItems.stream() - .filter(item -> "B GRADE".equals(item.getQaStatus())).collect(Collectors.toList()); + .filter(item -> "REJECT".equals(item.getQaStatus())).collect(Collectors.toList()); List cGradeFinishItemsIds= finishedItems.stream() .filter(item -> "C GRADE".equals(item.getQaStatus())).collect(Collectors.toList()); @@ -281,9 +275,6 @@ 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); if(actualProduction.compareTo(totalProduction) == 0) { phasePending.put("Stitching Total Time", null); }else { @@ -444,37 +435,28 @@ public class ReportingService { return barChartData; } - public List getAllPOs(String poName) { + public List getAllPOs(String poCode) { + List pOsDetailsList = new ArrayList<>(); - List jobCards = jobCardDAO.findAll() ; - HashMap> filterJobCardsByPos; - if(poName != null && !poName.isEmpty()) { - filterJobCardsByPos = jobCards.stream() - .filter(jobCard -> jobCard.getPurchaseOrderId().equals(poName)) - .collect(Collectors.groupingBy( - JobCard::getPurchaseOrderId, - HashMap::new, - Collectors.toList() - )); + List purchaseOrderCTPList; + + if (poCode != null && !poCode.isEmpty()) { + purchaseOrderCTPList = purchaseOrderCTPDao.findByPoCode(poCode); }else { - filterJobCardsByPos = jobCards.stream() - .collect(Collectors.groupingBy( - JobCard::getPurchaseOrderId, - HashMap::new, - Collectors.toList() - )); + purchaseOrderCTPList = purchaseOrderCTPDao.findAll(); } Map jobCardCompleteItems = new HashMap<>(); - for (String pos : filterJobCardsByPos.keySet()) { + + for (PurchaseOrderCTP pos : purchaseOrderCTPList) { + List jobCards = jobCardDAO.findByPoId(pos.getId()); BigDecimal totalProduction = BigDecimal.ZERO; BigDecimal actualProduction = BigDecimal.ZERO; - int poQuantity = 0; - String articleName = ""; Long qaProgressItems = 0L; Long totalFinishItem = 0L; + Long totalRejectPieces = 0L; POsDetails pOsDetails = new POsDetails(); - for (JobCard jobCard : filterJobCardsByPos.get(pos)) { + for (JobCard jobCard : jobCards) { List jobCardItems = jobCardItemDAO.findByCardId(jobCard.getId()); totalProduction = totalProduction.add(jobCardItems.stream() .map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO)) @@ -483,56 +465,52 @@ public class ReportingService { actualProduction = actualProduction.add(jobCardItems.stream() .map(item -> Optional.ofNullable(item.getActualProduction()).orElse(BigDecimal.ZERO)) .reduce(BigDecimal.ZERO, BigDecimal::add)); - poQuantity = jobCard.getPoQuantity(); - articleName = jobCard.getArticleName(); qaProgressItems += Optional.ofNullable(stitchingOfflineItemDAO.CalculateTotalQA(jobCard.getId())).orElse(0L); totalFinishItem += Optional.ofNullable(finishedItemDAO.calculateTotalFinishItem(jobCard.getId())).orElse(0L); + totalRejectPieces += Optional.ofNullable(storeItemDao.calculateTotalRejectItemByJobCardId(jobCard.getId())).orElse(0L); jobCardCompleteItems = getSegregateItems(String.valueOf(jobCard.getId())); if (jobCardCompleteItems == null) { jobCardCompleteItems = new HashMap<>(); } } - - pOsDetails.setPoNumber(pos); - pOsDetails.setArticleTitle(articleName); - pOsDetails.setPoQuantity(poQuantity); + pOsDetails.setPoId(pos.getId()); + pOsDetails.setPoNumber(pos.getPurchaseOrderCode()); + pOsDetails.setArticleTitle(pos.getArticleName()); + pOsDetails.setPoQuantity(pos.getPurchaseOrderQuantity()); + pOsDetails.setPoRequiredQuantity(pos.getPurchaseOrderQuantityRequired()); pOsDetails.setTotalCutting(actualProduction.intValue()); - pOsDetails.setTotalStitching(totalProduction.intValue()); + pOsDetails.setTotalStitching(qaProgressItems); pOsDetails.setTotalEndLineQC(qaProgressItems.intValue()); pOsDetails.setTotalFinishing(totalFinishItem); + pOsDetails.setPoStatus(false); - pOsDetails.setRemainingCutting(poQuantity - actualProduction.intValue()); - pOsDetails.setRemainingStitching(poQuantity - totalProduction.intValue()); - pOsDetails.setRemainingEndLineQC(poQuantity - qaProgressItems); - pOsDetails.setRemainingFinishing(poQuantity - totalFinishItem); + pOsDetails.setRemainingCutting(pos.getPurchaseOrderQuantityRequired() - actualProduction.intValue()); + pOsDetails.setRemainingStitching(pos.getPurchaseOrderQuantityRequired() - qaProgressItems); + pOsDetails.setRemainingEndLineQC(pos.getPurchaseOrderQuantityRequired() - qaProgressItems); + pOsDetails.setRemainingFinishing(pos.getPurchaseOrderQuantityRequired() - totalFinishItem); pOsDetails.setTotalAGradeItem(jobCardCompleteItems.getOrDefault("A GRADE", 0)); - pOsDetails.setTotalBGradeItem(jobCardCompleteItems.getOrDefault("B GRADE", 0)); - pOsDetails.setTotalCGradeItem(jobCardCompleteItems.getOrDefault("C GRADE", 0)); + pOsDetails.setTotalBGradeItem(totalRejectPieces.intValue()); pOsDetailsList.add(pOsDetails); } return pOsDetailsList; } - public HashMap> getAllPoJobCards(String PONumber, String selectDate) { + public HashMap> getAllPoJobCards(long poId, 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 filterJobCardsByPos = jobCardDAO.findByPoId(poId); 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() @@ -544,26 +522,21 @@ public class ReportingService { //total qa 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 segregateItems = finishedItems.stream() + .collect(Collectors.groupingBy( + FinishedItem::getQaStatus, + Collectors.collectingAndThen( + Collectors.counting(), + Long::intValue + ) )); + 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); + items.put("A Grade",segregateItems.get("APPROVED") != null ? segregateItems.get("APPROVED") : 0); + items.put("B Grade / Reject",segregateItems.get("REJECT") != null ? segregateItems.get("REJECT") : 0); // Define sorting order Map indexMap = new HashMap<>(); @@ -572,9 +545,8 @@ public class ReportingService { 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); + indexMap.put("APPROVED", 6); + indexMap.put("REJECT", 7); // Sort items based on indexMap order Map sortedItems = items.entrySet() diff --git a/src/main/resources/static/js/job-card-form.js b/src/main/resources/static/js/job-card-form.js index 72b106c..95ad9e7 100644 --- a/src/main/resources/static/js/job-card-form.js +++ b/src/main/resources/static/js/job-card-form.js @@ -221,7 +221,7 @@ items: [], purchaseOrderID:0, articleName: '', - purchaseOrderQuantity: 0, + purchaseOrderQuantityRequired: 0, purchaseOrderCode: '', }, methods: { @@ -266,7 +266,7 @@ }, onPoSelect(id,purchaseOrder) { this.purchaseOrderID = id, this.articleName = purchaseOrder.articleName, - this.purchaseOrderQuantity = purchaseOrder.purchaseOrderQuantity, + this.purchaseOrderQuantityRequired = purchaseOrder.purchaseOrderQuantityRequired, this.purchaseOrderCode = purchaseOrder.purchaseOrderCode } }, @@ -274,7 +274,7 @@ this.jobCard = window.ctp.jobCard; this.purchaseOrderID = this.jobCard.purchaseOrderId, this.articleName = this.jobCard.articleName, - this.purchaseOrderQuantity = this.jobCard.poQuantity, + this.purchaseOrderQuantityRequired = this.jobCard.poQuantity, this.purchaseOrderCode = this.jobCard.purchaseOrderTitle this.items = this.jobCard.items; diff --git a/src/main/resources/static/js/packaging/packaging-item-form.js b/src/main/resources/static/js/packaging/packaging-item-form.js index 2139ef3..96c7baf 100644 --- a/src/main/resources/static/js/packaging/packaging-item-form.js +++ b/src/main/resources/static/js/packaging/packaging-item-form.js @@ -76,7 +76,8 @@ let app = new Vue({ el : '#packagingApp', data : { - items : [] + items : [], + reason: '', }, methods : { onItemSelect: function (id, item) { @@ -90,6 +91,18 @@ const uniqueIds = new Set(ids); return ids.length !== uniqueIds.size; }, + submitWithRejectReason: function (reason) { + this.reason = reason; + this.$nextTick(() => { + const form = document.getElementById('packagingApp'); + if (form.checkValidity()) { + form.submit(); + } else { + form.reportValidity(); + } + }); + } + }, mounted : function () { console.log( this.$accounts ) diff --git a/src/main/resources/static/js/qc/finished-items-qc-form.js b/src/main/resources/static/js/qc/finished-items-qc-form.js index 7b640b7..4c04e54 100644 --- a/src/main/resources/static/js/qc/finished-items-qc-form.js +++ b/src/main/resources/static/js/qc/finished-items-qc-form.js @@ -86,11 +86,16 @@ return ids.length !== uniqueIds.size; }, submitWithQaStatus: function (status) { - this.QaStatus = status; - this.$nextTick(() => { - document.getElementById('qcForm').submit(); - }); - } + this.QaStatus = status; + this.$nextTick(() => { + const form = document.getElementById('qcForm'); + if (form.checkValidity()) { + form.submit(); + } else { + form.reportValidity(); + } + }); + } }, mounted: function () { diff --git a/src/main/resources/templates/_fragments.html b/src/main/resources/templates/_fragments.html index c41fdf4..d4802b4 100644 --- a/src/main/resources/templates/_fragments.html +++ b/src/main/resources/templates/_fragments.html @@ -78,6 +78,10 @@ Store +