Merge pull request 'print-job-card' (#14) from print-job-card into main
Reviewed-on: http://git.utopiadeals.com:8080/UIND/cut-to-pack-service/pulls/14main
commit
be680eb413
|
@ -8,6 +8,9 @@ import com.utopiaindustries.service.InventoryAccountService;
|
|||
import com.utopiaindustries.service.JobCardService;
|
||||
import com.utopiaindustries.service.LocationService;
|
||||
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.*;
|
||||
|
@ -173,6 +176,11 @@ public class JobCardController {
|
|||
return "job-card-view";
|
||||
}
|
||||
|
||||
@GetMapping( value = "/pdf/{id}", produces = MediaType.APPLICATION_PDF_VALUE )
|
||||
public ResponseEntity<InputStreamResource> generateJobCardPdf(@PathVariable long id, Model model ) throws Exception {
|
||||
return jobCardService.getJobCardReceivingPdf(id,model);
|
||||
}
|
||||
|
||||
private ArrayList<LocalDate> generateDateList(LocalDate start, LocalDate end) {
|
||||
ArrayList<LocalDate> localDates = new ArrayList<>();
|
||||
while (start.isBefore(end)) {
|
||||
|
|
|
@ -7,14 +7,21 @@ import com.utopiaindustries.dao.uind.PurchaseOrderDAO;
|
|||
import com.utopiaindustries.model.ctp.*;
|
||||
import com.utopiaindustries.model.uind.Item;
|
||||
import com.utopiaindustries.querybuilder.ctp.JobCardQueryBuilder;
|
||||
import com.utopiaindustries.util.HTMLBuilder;
|
||||
import com.utopiaindustries.util.PDFResponseEntityInputStreamResource;
|
||||
import com.utopiaindustries.util.StringUtils;
|
||||
import com.utopiaindustries.util.URLUtils;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -36,8 +43,10 @@ public class JobCardService {
|
|||
private final FinishedItemDAO finishedItemDAO;
|
||||
private final StitchingOfflineItemDAO stitchingOfflineItemDAO;
|
||||
private final SkuCutPiecesDAO skuCutPiecesDAO;
|
||||
private final HTMLBuilder htmlBuilder;
|
||||
private PDFResponseEntityInputStreamResource pdfGenerator;
|
||||
|
||||
public JobCardService(JobCardDAO jobCardDAO, CutPieceTypeDAO cutPieceTypeDAO, JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, ItemDAO itemDAO, LocationSiteDAO locationSiteDAO, PurchaseOrderDAO purchaseOrderDAO, UserInventoryAccountDAO userInventoryAccountDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, SkuCutPiecesDAO skuCutPiecesDAO) {
|
||||
public JobCardService(JobCardDAO jobCardDAO, CutPieceTypeDAO cutPieceTypeDAO, JobCardItemDAO jobCardItemDAO, CutPieceDAO cutPieceDAO, ItemDAO itemDAO, LocationSiteDAO locationSiteDAO, PurchaseOrderDAO purchaseOrderDAO, UserInventoryAccountDAO userInventoryAccountDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, SkuCutPiecesDAO skuCutPiecesDAO, HTMLBuilder htmlBuilder, PDFResponseEntityInputStreamResource pdfGenerator) {
|
||||
this.skuCutPiecesDAO = skuCutPiecesDAO;
|
||||
this.jobCardDAO = jobCardDAO;
|
||||
this.cutPieceTypeDAO = cutPieceTypeDAO;
|
||||
|
@ -49,6 +58,8 @@ public class JobCardService {
|
|||
this.userInventoryAccountDAO = userInventoryAccountDAO;
|
||||
this.finishedItemDAO = finishedItemDAO;
|
||||
this.stitchingOfflineItemDAO = stitchingOfflineItemDAO;
|
||||
this.htmlBuilder = htmlBuilder;
|
||||
this.pdfGenerator = pdfGenerator;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -300,4 +311,29 @@ public class JobCardService {
|
|||
public Map<Long, Long> totalFinishItem(List<Long> itemIds, long jobCardId ){
|
||||
return finishedItemDAO.findTotalFinishedItems( itemIds, jobCardId );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print Job card *
|
||||
* **/
|
||||
public ResponseEntity<InputStreamResource> getJobCardReceivingPdf(long id, Model model ) throws Exception {
|
||||
List<JobCardItem> jobCardItems = findJobCardItemByJobCardId(id);
|
||||
List<Long> jobCardItemIds = jobCardItems.stream()
|
||||
.map(JobCardItem::getItemId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Long> itemIds = jobCardItems.stream()
|
||||
.map(JobCardItem::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
model.addAttribute( "baseUrl", URLUtils.getCurrentBaseUrl() );
|
||||
model.addAttribute( "card", findByID(id));
|
||||
model.addAttribute("jobCardItems", jobCardItems);
|
||||
model.addAttribute("cutPiece", findCutPieceByJobCardItemIds(itemIds));
|
||||
model.addAttribute("totalFinishItem", totalFinishItem(jobCardItemIds, id));
|
||||
model.addAttribute("totalStitchingItem", totalStitchingItem(jobCardItemIds, id));
|
||||
// html str
|
||||
String htmlStr = htmlBuilder.buildHTML( "job-card-view-pdf", model );
|
||||
// return pdf
|
||||
return pdfGenerator.generatePdf( htmlStr, "Job-Card", "inline" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.utopiaindustries.util;
|
||||
|
||||
import com.itextpdf.html2pdf.attach.ITagWorker;
|
||||
import com.itextpdf.html2pdf.attach.ProcessorContext;
|
||||
import com.itextpdf.html2pdf.attach.impl.DefaultTagWorkerFactory;
|
||||
import com.itextpdf.html2pdf.html.TagConstants;
|
||||
import com.itextpdf.styledxmlparser.node.IElementNode;
|
||||
|
||||
public class CustomTagWorkerFactory extends DefaultTagWorkerFactory {
|
||||
public ITagWorker getCustomTagWorker( IElementNode tag, ProcessorContext context) {
|
||||
if ( TagConstants.HTML.equals(tag.name())) {
|
||||
return new ZeroMarginHtmlTagWorker(tag, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.utopiaindustries.util;
|
||||
|
||||
import com.utopiaindustries.dialect.CTPDialect;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.w3c.tidy.Tidy;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class HTMLBuilder {
|
||||
private final String UTF_8 = StandardCharsets.UTF_8.displayName();
|
||||
|
||||
public String buildHTML( String templateName, Model model ) throws Exception {
|
||||
// template resolver
|
||||
ClassLoaderTemplateResolver pdfTemplateResolver = createPDFTemplateResolver();
|
||||
// template engine
|
||||
TemplateEngine templateEngine = new TemplateEngine();
|
||||
templateEngine.setTemplateResolver( pdfTemplateResolver );
|
||||
templateEngine.addDialect( new CTPDialect() );
|
||||
// context
|
||||
Context ctx = configureContext( model );
|
||||
// render the template
|
||||
String renderedHTMLContent = templateEngine.process( templateName, ctx );
|
||||
return convertToXhtml( renderedHTMLContent );
|
||||
}
|
||||
|
||||
public String buildHTMLMap( String templateName, ModelMap model ) throws Exception {
|
||||
// template resolver
|
||||
ClassLoaderTemplateResolver pdfTemplateResolver = createPDFTemplateResolver();
|
||||
// template engine
|
||||
TemplateEngine templateEngine = new TemplateEngine();
|
||||
templateEngine.setTemplateResolver( pdfTemplateResolver );
|
||||
templateEngine.addDialect( new CTPDialect() );
|
||||
// context
|
||||
Context ctx = configureContextMap( model );
|
||||
// render the template
|
||||
String renderedHTMLContent = templateEngine.process( templateName, ctx );
|
||||
return convertToXhtml( renderedHTMLContent );
|
||||
}
|
||||
|
||||
private String convertToXhtml( String html ) throws UnsupportedEncodingException {
|
||||
Tidy tidy = new Tidy();
|
||||
tidy.setInputEncoding( UTF_8 );
|
||||
tidy.setOutputEncoding( UTF_8 );
|
||||
tidy.setXHTML( true );
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream( html.getBytes( UTF_8 ) );
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
tidy.parseDOM( inputStream, outputStream );
|
||||
return outputStream.toString( UTF_8 );
|
||||
}
|
||||
|
||||
private ClassLoaderTemplateResolver createPDFTemplateResolver() {
|
||||
ClassLoaderTemplateResolver pdfTemplateResolver = new ClassLoaderTemplateResolver();
|
||||
pdfTemplateResolver.setPrefix( "/templates/" );
|
||||
pdfTemplateResolver.setTemplateMode( TemplateMode.HTML );
|
||||
pdfTemplateResolver.setSuffix( ".html" );
|
||||
pdfTemplateResolver.setCharacterEncoding( UTF_8 );
|
||||
pdfTemplateResolver.setOrder( 1 );
|
||||
return pdfTemplateResolver;
|
||||
}
|
||||
|
||||
private Context configureContext( Model model ) {
|
||||
Context ctx = new Context();
|
||||
// adding model attributes to context
|
||||
for ( Map.Entry<String, Object> entry: model.asMap().entrySet() ) {
|
||||
ctx.setVariable( entry.getKey(), entry.getValue() );
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
private Context configureContextMap( ModelMap model ) {
|
||||
Context ctx = new Context();
|
||||
// adding model attributes to context
|
||||
for ( Map.Entry<String, Object> entry: model.entrySet() ) {
|
||||
ctx.setVariable( entry.getKey(), entry.getValue() );
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
package com.utopiaindustries.util;
|
||||
|
||||
import com.itextpdf.html2pdf.ConverterProperties;
|
||||
import com.itextpdf.html2pdf.HtmlConverter;
|
||||
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
|
||||
import com.itextpdf.kernel.geom.PageSize;
|
||||
import com.itextpdf.kernel.geom.Rectangle;
|
||||
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||
import com.itextpdf.layout.Document;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
@Component
|
||||
public class PDFResponseEntityInputStreamResource {
|
||||
|
||||
/**
|
||||
* prepare pdf document from html string
|
||||
*/
|
||||
private ResponseEntity<InputStreamResource> createPDFResponseEntityInputStreamResource( String htmlStr, String filename, String method ) throws IOException {
|
||||
// output stream
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
// converter properties
|
||||
ConverterProperties properties = new ConverterProperties();
|
||||
properties.setFontProvider( new DefaultFontProvider( false, false, true ) );
|
||||
// pdf document
|
||||
PdfWriter writer = new PdfWriter( outputStream );
|
||||
//temp Code
|
||||
/* PdfDocument temp = new PdfDocument(writer);
|
||||
Rectangle rectangle3x5 = new Rectangle(216, 360);
|
||||
PageSize pageSize =new PageSize( rectangle3x5 );
|
||||
temp.setDefaultPageSize( pageSize);
|
||||
properties.setTagWorkerFactory( new CustomTagWorkerFactory() );*/
|
||||
//temp code end
|
||||
Document document = HtmlConverter.convertToDocument( htmlStr, writer, properties );
|
||||
document.close();
|
||||
// input stream
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
|
||||
// content disposition header
|
||||
String headerContentDispositionStr = String.format( "%s; filename=%s.pdf", method, filename.replaceAll( ",", "-" ) );
|
||||
// return response
|
||||
return ResponseEntity
|
||||
.ok()
|
||||
.header( HttpHeaders.CONTENT_DISPOSITION, headerContentDispositionStr )
|
||||
.contentType( MediaType.APPLICATION_PDF )
|
||||
.body( new InputStreamResource( inputStream ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare pdf document from html string
|
||||
*/
|
||||
private ResponseEntity<InputStreamResource> createPDFResponseEntityInvoiceInputStreamResource( String htmlStr, String filename, String method, long height, long width )
|
||||
throws IOException {
|
||||
// output stream
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
// converter properties
|
||||
ConverterProperties properties = new ConverterProperties();
|
||||
properties.setFontProvider( new DefaultFontProvider( false, true, false ) );
|
||||
// pdf document
|
||||
PdfWriter writer = new PdfWriter( outputStream );
|
||||
//Code for invoice slips
|
||||
PdfDocument temp = new PdfDocument( writer );
|
||||
Rectangle rectangle3x5 = new Rectangle( width, height );
|
||||
PageSize pageSize = new PageSize( rectangle3x5 );
|
||||
temp.setDefaultPageSize( pageSize );
|
||||
properties.setTagWorkerFactory( new CustomTagWorkerFactory() );
|
||||
//temp code end
|
||||
Document document = HtmlConverter.convertToDocument( htmlStr, temp, properties );
|
||||
//document.setFontSize( 200.0f );
|
||||
document.close();
|
||||
// input stream
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
|
||||
// content disposition header
|
||||
String headerContentDispositionStr = String.format( "%s; filename=%s.pdf", method, filename.replaceAll( ",", "-" ) );
|
||||
// return response
|
||||
return ResponseEntity
|
||||
.ok()
|
||||
.header( HttpHeaders.CONTENT_DISPOSITION, headerContentDispositionStr )
|
||||
.contentType( MediaType.APPLICATION_PDF )
|
||||
.body( new InputStreamResource( inputStream ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* with inline as default content disposition "inline"
|
||||
*/
|
||||
public ResponseEntity<InputStreamResource> generatePdf( String htmlStr, String filename ) throws IOException {
|
||||
return this.createPDFResponseEntityInputStreamResource( htmlStr, filename, "inline" );
|
||||
}
|
||||
|
||||
/**
|
||||
* manual content disposition
|
||||
*/
|
||||
public ResponseEntity<InputStreamResource> generatePdf( String htmlStr, String filename, String method ) throws IOException {
|
||||
return this.createPDFResponseEntityInputStreamResource( htmlStr, filename, method );
|
||||
}
|
||||
|
||||
/**
|
||||
* manual content disposition
|
||||
*/
|
||||
public ResponseEntity<InputStreamResource> generateInvoicePdf( String htmlStr, String filename, String method, long height, long width ) throws IOException {
|
||||
return this.createPDFResponseEntityInvoiceInputStreamResource( htmlStr, filename, method, height, width );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.utopiaindustries.util;
|
||||
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class URLUtils {
|
||||
|
||||
public static String getCurrentBaseUrl() {
|
||||
ServletRequestAttributes sra = ( ServletRequestAttributes ) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest req = sra.getRequest();
|
||||
return req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getContextPath();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.utopiaindustries.util;
|
||||
|
||||
import com.itextpdf.html2pdf.attach.ProcessorContext;
|
||||
import com.itextpdf.html2pdf.attach.impl.tags.HtmlTagWorker;
|
||||
import com.itextpdf.layout.Document;
|
||||
import com.itextpdf.styledxmlparser.node.IElementNode;
|
||||
|
||||
public class ZeroMarginHtmlTagWorker extends HtmlTagWorker {
|
||||
public ZeroMarginHtmlTagWorker( IElementNode element, ProcessorContext context) {
|
||||
super(element, context);
|
||||
Document doc = (Document) getElementResult();
|
||||
doc.setMargins(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
*,*:before,*:after{padding:0;margin:0;box-sizing:border-box}body{font-family:"Open Sans",sans-serif;font-size:7pt;font-weight:400;line-height:1.2em;background:#fff !important;color:#111;position:relative;background:rgba(0,0,0,0) !important}body.draft:before,body.draft:after,body.terminated:before,body.terminated:after,body.not-approved:before,body.not-approved:after,body.duplicate:before,body.duplicate:after,body.cancel:before,body.cancel:after{font-size:70pt;font-weight:bold;color:red;text-align:center;display:block;opacity:.6;position:absolute;top:250pt;left:0;transform:rotate(-45deg)}body.duplicate:before,body.duplicate:after{content:"DUPLICATE"}body.cancel:before,body.cancel:after{content:"CANCEL"}body.draft:before,body.draft:after{content:"DRAFT"}body.terminated:before,body.terminated:after{content:"TERMINATED"}body.not-approved:before,body.not-approved:after{content:"NOT APPROVED"}@page{font-family:"Open Sans",sans-serif;font-size:6.65pt;font-style:italic;margin:1.25cm 1.25cm;@bottom-left{content:"Utopia Industries Pvt. Limited"}@bottom-center{content:"Page " counter(page) " of " counter(pages)}@bottom-right{width:126px;height:122px;margin-top:-130px}}h1{font-size:2em}h2{font-size:2.2857142857em}h3{font-size:1.8571428571em}h4{font-size:1.7142857143em}h5{font-size:1.5714285714em}h6{font-size:1.4285714286em}h1,h2,h3,h4,h5,h6{font-family:"Open Sans Condensed",sans-serif;font-weight:700;page-break-after:avoid;page-break-inside:avoid;text-transform:uppercase;margin:1.5em 0 1em}h1.no-margin-top,h2.no-margin-top,h3.no-margin-top,h4.no-margin-top,h5.no-margin-top,h6.no-margin-top{margin-top:0}h1.no-margin-bottom,h2.no-margin-bottom,h3.no-margin-bottom,h4.no-margin-bottom,h5.no-margin-bottom,h6.no-margin-bottom{margin-bottom:0}.text-right{text-align:right}.text-uppercase{text-transform:uppercase}.text-center{text-align:center}.font-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}b{font-weight:700}img{page-break-inside:avoid;page-break-after:avoid}ul,ol,dl{page-break-before:avoid}table{width:100%;border-collapse:collapse;border:none}table td{border:none}table.bordered,table.bordered td{border:1px solid #111}table.borderless,table.borderless td{border:none;padding:0}.tr-footer{text-transform:uppercase}td{padding:.4285714286em .8571428571em;vertical-align:top}td.spacer{padding:1em 0}.tr-header td{font-family:"Open Sans Condensed",sans-serif;font-size:1em;font-weight:bold;text-transform:uppercase;color:#fff;background:#111}td.pd-0{padding:0}ul,ol{padding:0 1.4285714286em;margin:0}ul{list-style-type:disc}.spacer{width:100%;height:1px;margin:2em 0 1em}.row{overflow:hidden;width:100%}.col{float:left}.col.col-half{width:49.96%}.col.col-half.col-padded:first-child{padding-right:3.5pt}.col.col-half.col-padded:last-child{padding-left:3.5pt}.col.col-two-third{width:66.6666%}.col.col-one-third{width:33.3333%}.col.col-one-third.col-padded{padding-left:3.5pt;padding-right:3.5pt}.col.col-one-third.col-padded:first-child{padding-left:0}.col.col-one-third.col-padded:last-child{padding-right:0}.visitor-photo{text-align:center;width:23%;height:77pt;line-height:77pt;margin-left:5pt;border:1px solid #111}.visitor-photo img{display:inline-block;width:90%;height:auto}/*# sourceMappingURL=print.css.map */
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml" xmlns:uind="http://www.w3.org/1999/xhtml">
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.w3.org/1999/xhtml"
|
||||
xmlns:uind="http://www.w3.org/1999/xhtml" xmlns:ctp="http://www.w3.org/1999/xhtml">
|
||||
<head th:replace="_fragments :: head('Job Cards')"></head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
|
@ -60,6 +61,9 @@
|
|||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
</th:block>
|
||||
<a th:href="@{'/job-cards/pdf/' + *{id}}" target="_blank" class="btn btn-sm btn-secondary" title="View PDF">
|
||||
<i class="bi bi-filetype-pdf"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
<?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 >
|
||||
<table class="bordered">
|
||||
<tr class="tr-header">
|
||||
<td colspan="2" th:text="'JOB CARD DETAIL'"></td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 40%; border: 1px solid black;"><i>Job Card ID</i></td>
|
||||
<td style="width: 60%; border: 1px solid black;">
|
||||
<a class="text-reset" target="_blank" th:text="${card.getCode()}"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 40%; border: 1px solid black;"><i>Job Order ID</i></td>
|
||||
<td style="width: 60%; border: 1px solid black;">
|
||||
<a class="text-reset" target="_blank" th:text="${card.getJobOrderId()}"></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-middle" style="border: 1px solid black;"><i>Card Status</i></td>
|
||||
<td style="border: 1px solid black;"><span th:text="${card.getStatus()}"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-middle" style="border: 1px solid black;"><i>Inventory Status</i></td>
|
||||
<td style="border: 1px solid black;"><span th:text="${card.getInventoryStatus()}"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-middle" style="border: 1px solid black;"><i>Customer</i></td>
|
||||
<td style="border: 1px solid black;"><span th:text="${card.getCustomer()}"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-middle" style="border: 1px solid black;"><i>Lot Number</i></td>
|
||||
<td style="border: 1px solid black;"><span th:text="${card.getLotNumber()}"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="align-middle" style="border: 1px solid black;"><i>Purchase Order ID</i></td>
|
||||
<td style="border: 1px solid black;"><span th:text="${card.getPurchaseOrderId()}"></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;">CUTTING DETAILS</h5>
|
||||
<thead >
|
||||
<tr class="tr-header">
|
||||
<td th:text="'Sku'"></td>
|
||||
<td th:text="'Length'"></td>
|
||||
<td th:text="'Width'"></td>
|
||||
<td th:text="'Gsm'"></td>
|
||||
<td th:text="'WT_Ply'"></td>
|
||||
<td th:text="'Ply'"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="cardItem : ${jobCardItems}">
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getSku()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getLength()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getWidth()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getGsm()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getWtPly()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getPly()}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</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;">ITEMS</h5>
|
||||
<thead >
|
||||
<tr class="tr-header">
|
||||
<td th:text="'ID'"></td>
|
||||
<td th:text="'Item ID'"></td>
|
||||
<td th:text="'Sku'"></td>
|
||||
<td th:text="'Expected Production'"></td>
|
||||
<td th:text="'Actual Production'"></td>
|
||||
<td th:text="'Total Production'"></td>
|
||||
<td th:text="'Total Stitching Item'"></td>
|
||||
<td th:text="'Total Finish Item'"></td>
|
||||
<td th:text="'Cut Piece Items'"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- Table Body -->
|
||||
<tbody>
|
||||
<tr th:each="cardItem : ${jobCardItems}">
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getId()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getItemId()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getSku()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getExpectedProduction()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getActualProduction()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cardItem.getTotalProduction()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${totalStitchingItem.get(cardItem.getItemId())}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${totalFinishItem.get(cardItem.getItemId())}"></td>
|
||||
<td style="margin:0px; padding:0px">
|
||||
<table class="bordered">
|
||||
<tbody>
|
||||
<tr th:each="cutPieceItem : ${cutPiece}"
|
||||
th:if="*{cardItem.getId() == cutPieceItem.getJobCardItemId()}">
|
||||
<td style="border: 1px solid black;" th:text="${cutPieceItem.getType()}"></td>
|
||||
<td style="border: 1px solid black;" th:text="${cutPieceItem.getQuantity()}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue