add po-online-status

po-online-status
usama.jameel 2025-06-03 13:46:09 +05:00
parent 98a4f33f5a
commit c8bffbb24a
16 changed files with 313 additions and 106 deletions

View File

@ -0,0 +1,53 @@
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<InputStreamResource> sendPoAndReturnPdf(@ModelAttribute POsDetails pOsDetails, Model model) throws Exception{
return purchaseOrderService.generatePOPdf(pOsDetails, model);
}
}

View File

@ -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<LocalDate> generateDateList(LocalDate start, LocalDate end) {
ArrayList<LocalDate> localDates = new ArrayList<>();
while (start.isBefore(end)) {

View File

@ -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_packed 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 );

View File

@ -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<JobCard> findByAllWithLimit(Long limit){
public List<JobCard> 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() );
}
}

View File

@ -24,7 +24,7 @@ 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_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<PurchaseOrderCTP> findByAllWithLimit(Long limit){
public List<PurchaseOrderCTP> 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() );
}
/*

View File

@ -23,6 +23,7 @@ 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 (" +
@ -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<Long> ids) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("start_date", startDate);

View File

@ -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;
@ -128,6 +133,22 @@ 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;
}
@Override
public String toString() {
return "POsDetails{" +

View File

@ -1,21 +1,48 @@
package com.utopiaindustries.service;
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.stream.Collectors;
@Service
public class PurchaseOrderService {
private final PurchaseOrderDAO purchaseOrderDAO;
private final ReportingService reportingService;
private final HTMLBuilder htmlBuilder;
private PDFResponseEntityInputStreamResource pdfGenerator;
public PurchaseOrderService(PurchaseOrderDAO purchaseOrderDAO) {
public PurchaseOrderService(PurchaseOrderDAO purchaseOrderDAO, ReportingService reportingService, HTMLBuilder htmlBuilder, PDFResponseEntityInputStreamResource pdfGenerator) {
this.purchaseOrderDAO = purchaseOrderDAO;
this.reportingService = reportingService;
this.htmlBuilder = htmlBuilder;
this.pdfGenerator = pdfGenerator;
}
public List<PurchaseOrder> findByTerm( String term ){
return purchaseOrderDAO.findByTerm( term );
}
/**
* Print Job card *
* **/
public ResponseEntity<InputStreamResource> generatePOPdf(POsDetails pOsDetails, Model model ) throws Exception {
model.addAttribute("poDetail", pOsDetails);
model.addAttribute( "baseUrl", URLUtils.getCurrentBaseUrl() );
String htmlStr = htmlBuilder.buildHTML( "po-status-pdf", model );
// return pdf
return pdfGenerator.generatePdf( htmlStr, "Po-status", "inline" );
}
}

View File

@ -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<String, Integer> getJobCardProgress(String jobCardID) {
@ -216,7 +210,7 @@ public class ReportingService {
List<FinishedItem> finishedItems = finishedItemDAO.findByJobCardId(Long.parseLong(jobCardID));
List<FinishedItem> bGradeFinishItemsIds= finishedItems.stream()
.filter(item -> "B GRADE".equals(item.getQaStatus())).collect(Collectors.toList());
.filter(item -> "REJECT".equals(item.getQaStatus())).collect(Collectors.toList());
List<FinishedItem> cGradeFinishItemsIds= finishedItems.stream()
.filter(item -> "C GRADE".equals(item.getQaStatus())).collect(Collectors.toList());
@ -444,37 +438,28 @@ public class ReportingService {
return barChartData;
}
public List<POsDetails> getAllPOs(String poName) {
public List<POsDetails> getAllPOs(String poCode) {
List<POsDetails> pOsDetailsList = new ArrayList<>();
List<JobCard> jobCards = jobCardDAO.findAll() ;
HashMap<String, List<JobCard>> 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<PurchaseOrderCTP> 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<String,Integer> jobCardCompleteItems = new HashMap<>();
for (String pos : filterJobCardsByPos.keySet()) {
for (PurchaseOrderCTP pos : purchaseOrderCTPList) {
List<JobCard> 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<JobCardItem> jobCardItems = jobCardItemDAO.findByCardId(jobCard.getId());
totalProduction = totalProduction.add(jobCardItems.stream()
.map(item -> Optional.ofNullable(item.getTotalProduction()).orElse(BigDecimal.ZERO))
@ -483,49 +468,45 @@ 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.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<String, Map<String, Integer>> getAllPoJobCards(String PONumber, String selectDate) {
public HashMap<String, Map<String, Integer>> 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<String, Map<String, Integer>> poJobCardItemsProgress = new HashMap<>();
List<JobCard> jobCards = jobCardDAO.findAll();
// Filter JobCards by Purchase Order ID
List<JobCard> filterJobCardsByPos = jobCards.stream()
.filter(e -> e.getPurchaseOrderId().equals(PONumber))
.collect(Collectors.toList());
List<JobCard> filterJobCardsByPos = jobCardDAO.findByPoId(poId);
List<InventoryAccount> inventoryAccounts = inventoryAccountDAO.getPackagingAccounts();
List<Integer> gradingAccounts = inventoryAccounts.stream().map(e-> (int)(e.getId())).collect(Collectors.toList());
for (JobCard jobCard : filterJobCardsByPos) {

View File

@ -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;

View File

@ -78,6 +78,10 @@
<a th:href="@{/store/}" class="nav-link"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/store') ? 'active' : ''}">Store</a>
</li>
<li class="nav-item"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/po-status') ? 'active' : ''}">
<a th:href="@{/po-status/}" class="nav-link">Online PO Status</a>
</li>
<li class="nav-item" sec:authorize="hasAnyRole('ROLE_REPORTING', 'ROLE_ADMIN')">
<a th:href="@{/reporting/}" class="nav-link"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting') ? 'active' : ''}">Reporting</a>
@ -183,10 +187,6 @@
<nav class="navbar navbar-light bg-light navbar-expand-lg justify-content-between"
th:if="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting')}">
<ul class="navbar-nav">
<li class="nav-item"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting/po-report') ? 'active' : ''}">
<a th:href="@{/reporting/po-report}" class="nav-link">PO Report</a>
</li>
<li class="nav-item"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/reporting/job-card-report') ? 'active' : ''}">
<a th:href="@{/reporting/job-card-report}" class="nav-link">Job Card Report</a>
@ -205,6 +205,17 @@
</li>
</ul>
</nav>
<!--Second level of po-status-->
<nav class="navbar navbar-light bg-light navbar-expand-lg justify-content-between"
th:if="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/po-status')}">
<ul class="navbar-nav">
<li class="nav-item"
th:classappend="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/po-status/all-pos') ? 'active' : ''}">
<a th:href="@{/po-status/all-pos}" class="nav-link">All PO's</a>
</li>
</ul>
</nav>
<!-- second level stitching -->
<nav class="navbar navbar-light bg-light navbar-expand-lg justify-content-between"
th:if="${#strings.startsWith(#httpServletRequest.getRequestURI(), '/ctp/stitching')}">

View File

@ -21,7 +21,7 @@
<!-- Hidden Inputs for Dynamic Values -->
<input type="hidden" name="articleName" :value="articleName">
<input type="hidden" name="poQuantity" :value="purchaseOrderQuantity">
<input type="hidden" name="poQuantity" :value="purchaseOrderQuantityRequired">
<input type="hidden" name="purchaseOrderTitle" :value="purchaseOrderCode">
<input type="hidden" name="purchaseOrderId" :value="purchaseOrderID">
@ -57,7 +57,7 @@
<div class="col-sm-3 form-group">
<label>PO Quantity</label>
<!-- Dynamically show PO quantity -->
<span class="form-control">{{ purchaseOrderQuantity || jobCard.poQuantity }}</span>
<span class="form-control">{{ purchaseOrderQuantityRequired || jobCard.poQuantity }}</span>
</div>
<div class="col-sm-3 form-group" th:with="title=*{locationTitle},id=*{locationSiteId}">

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:uind="http://www.w3.org/1999/xhtml"
xml:lang="en"
lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Job Card</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:700|Open+Sans:400,400i&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" th:href="@{|${baseUrl}/css/print.css|}">
</head>
<body>
<div class="container-fluid">
<table>
<tr>
<td width="400">
<img width="200" th:src="@{|${baseUrl}/img/utopia-industries.png|}" alt="Utopia Industries">
</td>
<td width="400">
<table class="bordered">
<tr class="tr-header">
<td colspan="2" th:text="'PO Online Status'"></td>
</tr>
<tbody>
<tr>
<td style="width: 40%; border: 1px solid black;"><i>PO Code</i></td>
<td style="width: 60%; border: 1px solid black;">
<a class="text-reset" target="_blank" th:text="${poDetail.getPoNumber()}"></a>
</td>
</tr>
<tr>
<td style="width: 40%; border: 1px solid black;"><i>Article Name</i></td>
<td style="width: 60%; border: 1px solid black;">
<a class="text-reset" target="_blank" th:text="${poDetail.getArticleTitle()}"></a>
</td>
</tr>
<tr>
<td class="align-middle" style="border: 1px solid black;"><i>PO Quantity</i></td>
<td style="border: 1px solid black;"><span th:text="${poDetail.getPoQuantity()}"></span></td>
</tr>
<tr>
<td class="align-middle" style="border: 1px solid black;"><i>PO Required Excess+</i></td>
<td style="border: 1px solid black;"><span th:text="${poDetail.getPoRequiredQuantity()}"></span></td>
</tr>
<tr>
<td class="align-middle" style="border: 1px solid black;"><i>PO Status</i></td>
<td style="border: 1px solid black;"><span th:text="'OPEN'"></span></td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
<table class="bordered" style="width: 100%; margin-top: 20px; border-collapse: collapse; ">
<h5 class="no-margin-top no-margin-bottom" style="margin-top: 20px;">PO Details</h5>
<thead >
<tr class="tr-header">
<td>Cutting</td>
<td>Cutting Balance</td>
<td>Stitching</td>
<td>Stitching Balance</td>
<td>End Line QC</td>
<td>End Line QC Balance</td>
<td>Finishing Items</td>
<td>Finishing Items Balance</td>
<td>A Grade Items</td>
<td>Reject Items In Store</td>
</tr>
</thead>
<tbody>
<tr >
<td style="border: 1px solid black;" th:text="${poDetail.getTotalCutting()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getRemainingCutting()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getTotalStitching()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getRemainingStitching()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getTotalEndLineQC()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getRemainingEndLineQC()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getTotalFinishing()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getRemainingFinishing()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getTotalAGradeItem()}"></td>
<td style="border: 1px solid black;" th:text="${poDetail.getTotalBGradeItem()}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

View File

@ -8,6 +8,7 @@
<main class="row page-main">
<aside class="col-sm-2" th:replace="/reporting/po-job-card-report-sidebar :: sidebar"></aside>
<div class="col-sm">
<h3>PO Job Cards</h3>
<table class="table">
<tbody>
<tr th:if="${allJobCard != null}" th:each="jobCard : ${allJobCard.keySet()}"

View File

@ -8,7 +8,7 @@
<form th:action="@{${#strings.replace(#httpServletRequest.requestURI, #request.getContextPath(), '')}}">
<h5 class="mb-4">Refine Your Search</h5>
<div class="form-group">
<label>PO Name</label>
<label>PO Code</label>
<input type="text" class="form-control" name="poName" th:value="${param['poName'] ?: poName}">
</div>
<input type="submit" class="btn btn-secondary btn-block" value="Search">

View File

@ -1,22 +1,22 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"
xmlns:ctp="http://www.w3.org/1999/xhtml">
<head th:replace="_fragments :: head('PO Report')"></head>
<body>
<div class="container-fluid">
<header class="row page-header" th:replace="_fragments :: page-header"></header>
<main class="row page-main">
<aside class="col-sm-2" th:replace="/reporting/po-report-sidebar :: sidebar"></aside>
<div class="col-lg-10 col-sm-10">
<h3>PO's Report</h3>
<table class="table table-striped font-sm" data-order="[[ 0, &quot;asc&quot; ]]">
<h3>All PO's </h3>
<table th:if="${ #lists != null && #lists.size(allPOs) != 0 }" class="table table-striped font-sm"
data-order="[[ 0, &quot;asc&quot; ]]">
<thead>
<tr>
<th>PO Number</th>
<th>PO Article</th>
<th>PO Quantity</th>
<th>Req+ Excess</th>
<th>Cutting</th>
<th>Cutting Balance</th>
<th>Stitching</th>
@ -26,16 +26,17 @@
<th>Finishing Items</th>
<th>Finishing Items Balance</th>
<th>A Grade Items</th>
<th>B Grade Items</th>
<th>C Grade Items</th>
<th>Reject Items In Store</th>
</tr>
</thead>
<tbody>
<!-- Dummy data for testing purposes -->
<tr th:each="poDetail : ${allPOs}">
<td><a class="text-reset" th:href="@{'/reporting/po-report-view/' + ${poDetail.poNumber}}" th:text="${poDetail.poNumber}"></a></td>
<td><a class="text-reset" th:href="@{'/po-status/po-report-view/' + ${poDetail.poId}}"
th:text="${poDetail.poNumber}"></a></td>
<td th:text="${poDetail.articleTitle}"></td>
<td th:text="${poDetail.poQuantity}"></td>
<td th:text="${poDetail.poRequiredQuantity}"></td>
<td th:text="${poDetail.totalCutting}"></td>
<td th:text="${poDetail.remainingCutting}"></td>
<td th:text="${poDetail.totalStitching}"></td>
@ -46,18 +47,43 @@
<td th:text="${poDetail.remainingFinishing}"></td>
<td th:text="${poDetail.totalAGradeItem}"></td>
<td th:text="${poDetail.totalBGradeItem}"></td>
<td th:text="${poDetail.totalCGradeItem}"></td>
<td>
<form th:action="@{/po-status/generate-po-pdf}" method="get" target="_blank"
th:id="'form-' + ${poDetail.poId}">
<!-- Hidden inputs for all fields -->
<input type="hidden" name="poId" th:value="${poDetail.poId}"/>
<input type="hidden" name="poNumber" th:value="${poDetail.poNumber}"/>
<input type="hidden" name="articleTitle" th:value="${poDetail.articleTitle}"/>
<input type="hidden" name="poQuantity" th:value="${poDetail.poQuantity}"/>
<input type="hidden" name="poRequiredQuantity" th:value="${poDetail.poRequiredQuantity}"/>
<input type="hidden" name="totalCutting" th:value="${poDetail.totalCutting}"/>
<input type="hidden" name="remainingCutting" th:value="${poDetail.remainingCutting}"/>
<input type="hidden" name="totalStitching" th:value="${poDetail.totalStitching}"/>
<input type="hidden" name="remainingStitching" th:value="${poDetail.remainingStitching}"/>
<input type="hidden" name="totalEndLineQC" th:value="${poDetail.totalEndLineQC}"/>
<input type="hidden" name="remainingEndLineQC" th:value="${poDetail.remainingEndLineQC}"/>
<input type="hidden" name="totalFinishing" th:value="${poDetail.totalFinishing}"/>
<input type="hidden" name="remainingFinishing" th:value="${poDetail.remainingFinishing}"/>
<input type="hidden" name="totalAGradeItem" th:value="${poDetail.totalAGradeItem}"/>
<input type="hidden" name="totalBGradeItem" th:value="${poDetail.totalBGradeItem}"/>
<!-- Link styled as a button -->
<a href="javascript:void(0);"
th:onclick="'document.getElementById(\'form-' + ${poDetail.poId} + '\').submit()'"
class="btn btn-sm btn-secondary"
title="Generate PDF"
target="_blank">
<i class="bi bi-filetype-pdf"></i>
</a>
</form>
</td>
</tr>
</tbody>
</table>
</div>
<!-- <h4 th:if="${#lists.size(cards) == 0 }">No cards found.</h4>-->
<h4 th:if="${#lists.size(allPOs) == 0 }">No PO found.</h4>
</div>
</main>
</div>
<div th:replace="_fragments :: page-footer-scripts"></div>
<script th:src="@{/js/summary.js}"></script>
</body>
</html>