Barcode update and add some more Information
parent
0d61494a3f
commit
78c6d7f459
|
@ -6,8 +6,8 @@ public enum BarcodeStickerSize {
|
||||||
SIZE_2_X_3( 3 * 72, 2 * 72, 10, 10, 6, 6, 50, 50, 125, 125, 14, 9, 7),
|
SIZE_2_X_3( 3 * 72, 2 * 72, 10, 10, 6, 6, 50, 50, 125, 125, 14, 9, 7),
|
||||||
SIZE_4_X_4( 4 * 72, 4 * 72, 8, 8, 8, 8, 200, 100, 250, 250, 14, 9, 7),
|
SIZE_4_X_4( 4 * 72, 4 * 72, 8, 8, 8, 8, 200, 100, 250, 250, 14, 9, 7),
|
||||||
SIZE_1_75_X_3_5( 3.5f * 72, 1.75f * 72, 10, 10, 6, 6, 50, 50, 125, 125, 14, 9, 7),
|
SIZE_1_75_X_3_5( 3.5f * 72, 1.75f * 72, 10, 10, 6, 6, 50, 50, 125, 125, 14, 9, 7),
|
||||||
SIZE_4_X_7( 7f * 72, 4f * 72, 10, 10, 6, 6, 50, 50, 125, 125, 14, 9, 7),
|
SIZE_4_X_7( 7f * 72, 4f * 72, 200, 10, 40, 6, 50, 40, 125, 125, 14, 9, 7),
|
||||||
SIZE_1_X_2( 94f, 49f , 20, 10, 48, 6, 42, 42, 125, 125, 4, 9, 7);
|
SIZE_1_X_2( 141.73f, 56.69f , 20, 10, 10, 6, 60, 60, 125, 125, 4, 9, 7);
|
||||||
|
|
||||||
|
|
||||||
private final float width;
|
private final float width;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.utopiaindustries.model.ctp;
|
||||||
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public class FinishedItem implements InventoryArtifact {
|
public class FinishedItem implements InventoryArtifact {
|
||||||
|
@ -141,6 +142,14 @@ public class FinishedItem implements InventoryArtifact {
|
||||||
this.qaStatus = qaStatus;
|
this.qaStatus = qaStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWrapQuantity(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMasterBundleId(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "FinishedItem{" +
|
return "FinishedItem{" +
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.utopiaindustries.model.ctp;
|
package com.utopiaindustries.model.ctp;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public interface InventoryArtifact {
|
public interface InventoryArtifact {
|
||||||
|
|
||||||
long getId();
|
long getId();
|
||||||
|
@ -8,5 +11,8 @@ public interface InventoryArtifact {
|
||||||
String getSku();
|
String getSku();
|
||||||
String getType();
|
String getType();
|
||||||
String getBarcode();
|
String getBarcode();
|
||||||
|
String getCreatedBy();
|
||||||
|
LocalDateTime getCreatedAt();
|
||||||
|
BigDecimal getWrapQuantity();
|
||||||
|
long getMasterBundleId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.utopiaindustries.model.ctp;
|
package com.utopiaindustries.model.ctp;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -94,6 +95,14 @@ public class MasterBundle implements InventoryArtifact{
|
||||||
this.bundles = bundles;
|
this.bundles = bundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWrapQuantity(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMasterBundleId(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public List<FinishedItem> getItems() {
|
public List<FinishedItem> getItems() {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.utopiaindustries.model.ctp;
|
||||||
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public class StitchingOfflineItem implements InventoryArtifact {
|
public class StitchingOfflineItem implements InventoryArtifact {
|
||||||
|
@ -107,6 +108,14 @@ public class StitchingOfflineItem implements InventoryArtifact {
|
||||||
this.qaStatus = qaStatus;
|
this.qaStatus = qaStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getWrapQuantity(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMasterBundleId(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "StitchingOfflineItem{" +
|
return "StitchingOfflineItem{" +
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
package com.utopiaindustries.service;
|
package com.utopiaindustries.service;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.itextpdf.io.font.constants.StandardFonts;
|
||||||
|
import com.itextpdf.kernel.colors.ColorConstants;
|
||||||
|
import com.itextpdf.kernel.font.PdfFontFactory;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfPage;
|
||||||
|
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
|
||||||
|
import com.itextpdf.layout.element.AreaBreak;
|
||||||
|
import com.itextpdf.layout.element.Paragraph;
|
||||||
|
import com.itextpdf.layout.property.TextAlignment;
|
||||||
import com.utopiaindustries.dao.ctp.*;
|
import com.utopiaindustries.dao.ctp.*;
|
||||||
import com.utopiaindustries.model.ctp.*;
|
import com.utopiaindustries.model.ctp.*;
|
||||||
import com.utopiaindustries.util.BarcodeUtils;
|
import com.utopiaindustries.util.BarcodeUtils;
|
||||||
|
@ -12,8 +20,19 @@ import com.zebra.sdk.printer.ZebraPrinter;
|
||||||
import com.zebra.sdk.printer.ZebraPrinterFactory;
|
import com.zebra.sdk.printer.ZebraPrinterFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import com.itextpdf.io.image.ImageDataFactory;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||||
|
import com.itextpdf.kernel.geom.PageSize;
|
||||||
|
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||||
|
import com.itextpdf.layout.Document;
|
||||||
|
import com.itextpdf.layout.element.Image;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
@ -22,6 +41,7 @@ import java.io.*;
|
||||||
|
|
||||||
import java.nio.file.FileSystems;
|
import java.nio.file.FileSystems;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.google.zxing.EncodeHintType;
|
import com.google.zxing.EncodeHintType;
|
||||||
|
@ -48,13 +68,17 @@ public class BarcodeService {
|
||||||
private final MasterBundleDAO masterBundleDAO;
|
private final MasterBundleDAO masterBundleDAO;
|
||||||
private final FinishedItemDAO finishedItemDAO;
|
private final FinishedItemDAO finishedItemDAO;
|
||||||
private final StitchingOfflineItemDAO stitchingOfflineItemDAO;
|
private final StitchingOfflineItemDAO stitchingOfflineItemDAO;
|
||||||
|
private final InventoryAccountDAO inventoryAccountDAO;
|
||||||
|
private final JobCardItemDAO jobCardItemDAO;
|
||||||
|
|
||||||
public BarcodeService(BundleDAO bundleDAO, JobCardDAO jobCardDAO, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO) {
|
public BarcodeService(BundleDAO bundleDAO, JobCardDAO jobCardDAO, MasterBundleDAO masterBundleDAO, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO, InventoryAccountDAO inventoryAccountDAO, JobCardItemDAO jobCardItemDAO) {
|
||||||
this.bundleDAO = bundleDAO;
|
this.bundleDAO = bundleDAO;
|
||||||
this.jobCardDAO = jobCardDAO;
|
this.jobCardDAO = jobCardDAO;
|
||||||
this.masterBundleDAO = masterBundleDAO;
|
this.masterBundleDAO = masterBundleDAO;
|
||||||
this.finishedItemDAO = finishedItemDAO;
|
this.finishedItemDAO = finishedItemDAO;
|
||||||
this.stitchingOfflineItemDAO = stitchingOfflineItemDAO;
|
this.stitchingOfflineItemDAO = stitchingOfflineItemDAO;
|
||||||
|
this.inventoryAccountDAO = inventoryAccountDAO;
|
||||||
|
this.jobCardItemDAO = jobCardItemDAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -80,134 +104,189 @@ public class BarcodeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getBarcodeImages(List<? extends InventoryArtifact> artifacts,
|
public void getBarcodeImages(List<? extends InventoryArtifact> artifacts,
|
||||||
BarcodeStickerSize stickerSize,
|
BarcodeStickerSize stickerSize,
|
||||||
String artifactType) throws Exception {
|
String artifactType) throws Exception {
|
||||||
|
|
||||||
for (InventoryArtifact artifact : artifacts) {
|
|
||||||
// Create a blank BufferedImage (an image with the size of the sticker)
|
int pageWidth = 900; // A4 Width
|
||||||
BufferedImage stickerImage = new BufferedImage((int) stickerSize.getWidth()*2, (int) stickerSize.getHeight()*2, BufferedImage.TYPE_INT_ARGB);
|
int pageHeight = 1200; // A4 Height
|
||||||
Graphics2D g2d = stickerImage.createGraphics();
|
|
||||||
g2d.scale(2,2);
|
int rows = 3;
|
||||||
|
int cols = 2;
|
||||||
|
int totalStickersPerPage = rows * cols;
|
||||||
|
|
||||||
|
int totalPages = (int) Math.ceil((double) artifacts.size() / totalStickersPerPage); // Total required pages
|
||||||
|
|
||||||
|
for (int page = 0; page < totalPages; page++) {
|
||||||
|
// Create a Blank A4 Page Image
|
||||||
|
BufferedImage a4Image = new BufferedImage(pageWidth, pageHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g2d = a4Image.createGraphics();
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
// Set background color (white for the sticker)
|
|
||||||
g2d.setColor(Color.WHITE);
|
g2d.setColor(Color.WHITE);
|
||||||
g2d.fillRect(0, 0, (int) stickerSize.getWidth(), (int) stickerSize.getHeight());
|
g2d.fillRect(0, 0, pageWidth, pageHeight);
|
||||||
|
|
||||||
// Set font for SKU and barcode
|
|
||||||
Font font = new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()+10);
|
|
||||||
g2d.setFont(font);
|
|
||||||
|
|
||||||
// Add SKU to the image
|
|
||||||
String sku = artifact.getSku();
|
|
||||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
|
||||||
int textWidth = fontMetrics.stringWidth(sku);
|
|
||||||
int x = (int) ((stickerSize.getWidth() - textWidth) / 2);
|
|
||||||
g2d.setColor(Color.BLACK);
|
g2d.setColor(Color.BLACK);
|
||||||
g2d.drawString(sku, x, stickerSize.getMarginTop() + fontMetrics.getAscent()+20);
|
|
||||||
|
|
||||||
// Create the barcode image
|
|
||||||
byte[] imgBytes = BarcodeUtils.getBarcodeImageByteArray(artifact.getBarcode(), BarcodeFormat.CODE_128, stickerSize.getImageWidthBarcode()+500, stickerSize.getImageHeightBarcode()+30);
|
|
||||||
BufferedImage barcodeImage = ImageIO.read(new ByteArrayInputStream(imgBytes));
|
|
||||||
|
|
||||||
// Draw the barcode image on the sticker
|
Font barcodeFont = new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()+8);
|
||||||
int barcodeX =(int) (stickerSize.getWidth() - barcodeImage.getWidth()) / 2;
|
Font detailFont = new Font("Helvetica", Font.PLAIN, stickerSize.getTextSize()+3);
|
||||||
int barcodeY = stickerSize.getMarginTop() + fontMetrics.getAscent() + 30; // Add some margin
|
|
||||||
g2d.drawImage(barcodeImage, barcodeX, barcodeY, null);
|
|
||||||
|
|
||||||
// Add the barcode value below the barcode image
|
for (int i = 0; i < totalStickersPerPage; i++) {
|
||||||
g2d.drawString(artifact.getBarcode(), (stickerSize.getWidth() - fontMetrics.stringWidth(artifact.getBarcode())) / 2,
|
int artifactIndex = page * totalStickersPerPage + i;
|
||||||
barcodeY + barcodeImage.getHeight() + fontMetrics.getAscent());
|
if (artifactIndex >= artifacts.size()) break;
|
||||||
|
InventoryArtifact artifact = artifacts.get(artifactIndex);
|
||||||
|
int row = i / cols;
|
||||||
|
int col = i % cols;
|
||||||
|
|
||||||
// If artifactType is Bundle, add additional info
|
int x = col * (pageWidth / cols);
|
||||||
if (artifactType.equalsIgnoreCase(Bundle.class.getSimpleName())) {
|
int y = row * (pageHeight / rows);
|
||||||
String typeText = String.format("%s : %d", artifact.getType(), artifact.getId());
|
|
||||||
g2d.drawString(typeText, (stickerSize.getWidth() - fontMetrics.stringWidth(typeText)) / 2,
|
Font stickerFont = new Font("Helvetica", Font.BOLD, stickerSize.getTextSize() + 10);
|
||||||
barcodeY + barcodeImage.getHeight() + fontMetrics.getAscent() + 45);
|
g2d.setFont(stickerFont);
|
||||||
|
// Draw Sticker Border
|
||||||
|
g2d.drawRect(x, y, pageWidth / cols, pageHeight / rows);
|
||||||
|
|
||||||
|
this.drawCenteredText(g2d, artifactType.equals("Bundle")?"Sub-Bundle":"Master-Bundle", detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop()-20,stickerSize.getMarginLeft()-165);
|
||||||
|
|
||||||
|
// Draw SKU
|
||||||
|
g2d.setFont(barcodeFont);
|
||||||
|
String sku = artifact.getSku();
|
||||||
|
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||||
|
int textWidth = fontMetrics.stringWidth(sku);
|
||||||
|
g2d.drawString(sku, x + ((pageWidth / cols) - textWidth) / 2, y + fontMetrics.getAscent()+ stickerSize.getMarginTop()+10);
|
||||||
|
|
||||||
|
|
||||||
|
// Generate Barcode Image
|
||||||
|
g2d.setFont(barcodeFont);
|
||||||
|
byte[] imgBytes = BarcodeUtils.getBarcodeImageByteArray(
|
||||||
|
artifact.getBarcode(), BarcodeFormat.CODE_128, stickerSize.getImageWidthBarcode(), stickerSize.getImageHeightBarcode());
|
||||||
|
|
||||||
|
BufferedImage barcodeImage = ImageIO.read(new ByteArrayInputStream(imgBytes));
|
||||||
|
int originalBarcodeWidth = barcodeImage.getWidth();
|
||||||
|
int originalBarcodeHeight = barcodeImage.getHeight();
|
||||||
|
|
||||||
|
|
||||||
|
double scaleX = (double)(pageWidth / cols) / originalBarcodeWidth;
|
||||||
|
double scaleY = (double)(pageHeight / rows) / originalBarcodeHeight;
|
||||||
|
double scaleFactor = Math.min(scaleX, scaleY);
|
||||||
|
|
||||||
|
int scaledWidth = (int)(originalBarcodeWidth * scaleFactor) - 30;
|
||||||
|
int scaledHeight = (int)(originalBarcodeHeight * scaleFactor) - 10;
|
||||||
|
|
||||||
|
BufferedImage scaledBarcodeImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g2dBarcode = scaledBarcodeImage.createGraphics();
|
||||||
|
g2dBarcode.drawImage(barcodeImage, 0, 0, scaledWidth, scaledHeight, null);
|
||||||
|
g2dBarcode.dispose();
|
||||||
|
|
||||||
|
int barcodeX = x + ((pageWidth / cols) - scaledBarcodeImage.getWidth()) / 2;
|
||||||
|
int barcodeY = y + fontMetrics.getAscent() + stickerSize.getMarginTop() + 20;
|
||||||
|
g2d.drawImage(scaledBarcodeImage, barcodeX, barcodeY, null);
|
||||||
|
|
||||||
|
//barcode text
|
||||||
|
g2d.setFont(barcodeFont);
|
||||||
|
String barcode = artifact.getBarcode();
|
||||||
|
FontMetrics barcodeFontMatrix = g2d.getFontMetrics();
|
||||||
|
int barcodeText = fontMetrics.stringWidth(barcode);
|
||||||
|
g2d.drawString(barcode, (x + ((pageWidth / cols) - barcodeText) / 2), y + barcodeFontMatrix.getAscent() + stickerSize.getMarginTop() + 120);
|
||||||
|
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm");
|
||||||
|
this.drawCenteredText(g2d, "Item-ID: "+artifact.getItemId(), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 150,stickerSize.getMarginLeft());
|
||||||
|
this.drawCenteredText(g2d, "Created-By: "+artifact.getCreatedBy(), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 170,stickerSize.getMarginLeft());
|
||||||
|
this.drawCenteredText(g2d, "Created-At: "+formatter.format(artifact.getCreatedAt()), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 190,stickerSize.getMarginLeft());
|
||||||
|
|
||||||
|
//draw job-card details
|
||||||
|
JobCard jobCard = jobCardDAO.find(artifact.getJobCardId());
|
||||||
|
|
||||||
|
this.drawCenteredText(g2d, "Job-Card: " + jobCard.getCode(), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 210, stickerSize.getMarginLeft() );
|
||||||
|
this.drawCenteredText(g2d, "Purchase-Order: " + jobCard.getPurchaseOrderId(), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 230, stickerSize.getMarginLeft());
|
||||||
|
this.drawCenteredText(g2d, "Lot-Number: " + jobCard.getLotNumber(), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 250, stickerSize.getMarginLeft());
|
||||||
|
if((artifactType.equals("Bundle"))){
|
||||||
|
JobCardItem jobCardItem = jobCardItemDAO.findByCardId(jobCard.getId()).get(0);
|
||||||
|
InventoryAccount inventoryAccount = inventoryAccountDAO.find(jobCardItem.getAccountId());
|
||||||
|
this.drawCenteredText(g2d, "Pieces: " + artifact.getWrapQuantity(), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 270, stickerSize.getMarginLeft());
|
||||||
|
this.drawCenteredText(g2d, "Cutting-Account: " + inventoryAccount.getTitle() , detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 290, stickerSize.getMarginLeft());
|
||||||
|
}else {
|
||||||
|
List<Bundle> bundles = bundleDAO.findByMasterId(artifact.getId());
|
||||||
|
String concatenatedIds = bundles.stream()
|
||||||
|
.map(bundle -> String.valueOf(bundle.getId()))
|
||||||
|
.collect(Collectors.joining("\\"));
|
||||||
|
|
||||||
|
this.drawCenteredText(g2d, "Sub-Bundles: " + concatenatedIds, detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 290, stickerSize.getMarginLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.drawCenteredText(g2d, String.valueOf(artifact.getId()), detailFont, x, y, pageWidth, cols, stickerSize.getMarginTop() + 330, 0);
|
||||||
|
|
||||||
g2d.setFont(new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()+20));
|
|
||||||
g2d.drawString(String.valueOf(artifactType.toCharArray()[0]), (stickerSize.getWidth() - fontMetrics.stringWidth(String.valueOf(artifactType.toCharArray()[0]))) / 2,
|
|
||||||
barcodeY + barcodeImage.getHeight() + fontMetrics.getAscent() + 77);
|
|
||||||
} else {
|
|
||||||
// Add first character of artifact type
|
|
||||||
String type = String.valueOf(artifactType.charAt(0));
|
|
||||||
g2d.setFont(new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()+10));
|
|
||||||
g2d.drawString(type, (stickerSize.getWidth() - fontMetrics.stringWidth(type)) / 2,
|
|
||||||
barcodeY + barcodeImage.getHeight() + fontMetrics.getAscent() + 45);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize drawing
|
// Finalize Drawing
|
||||||
g2d.dispose();
|
g2d.dispose();
|
||||||
printLabel(stickerImage);
|
|
||||||
|
// Save A4 Page as PNG
|
||||||
|
Path path = FileSystems.getDefault().getPath("./src/main/resources/static/barcode_a4_" + (page + 1) + ".png");
|
||||||
|
File outputFile = path.toFile();
|
||||||
|
ImageIO.write(a4Image, "PNG", outputFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//use for detail heading
|
||||||
|
private void drawCenteredText(Graphics2D g2d, String text, Font font, int x, int y, int pageWidth, int cols, int marginTop, int marginLeft) {
|
||||||
|
g2d.setFont(font);
|
||||||
|
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||||
|
int adjustedX = (x + ((pageWidth / cols) ) / 2) - marginLeft;
|
||||||
|
int adjustedY = y + fontMetrics.getAscent() + marginTop;
|
||||||
|
g2d.drawString(text, adjustedX, adjustedY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void getBarcodeImagesForStitchItems(List<? extends InventoryArtifact> artifacts,
|
public void getBarcodeImagesForStitchItems(List<? extends InventoryArtifact> artifacts,
|
||||||
BarcodeStickerSize stickerSize,
|
BarcodeStickerSize stickerSize,
|
||||||
String artifactType) throws Exception {
|
String artifactType) throws Exception {
|
||||||
|
|
||||||
|
Path pdfPath = FileSystems.getDefault().getPath("./src/main/resources/static/sample_qr_output.pdf");
|
||||||
|
PdfWriter writer = new PdfWriter(pdfPath.toFile());
|
||||||
|
|
||||||
|
PdfDocument pdfDoc = new PdfDocument(writer);
|
||||||
|
Document document = new Document(pdfDoc);
|
||||||
|
|
||||||
|
pdfDoc.setDefaultPageSize(new PageSize(stickerSize.getWidth(), stickerSize.getHeight()));
|
||||||
|
|
||||||
for (InventoryArtifact artifact : artifacts) {
|
for (InventoryArtifact artifact : artifacts) {
|
||||||
JobCard jobCard = jobCardDAO.find(artifact.getJobCardId());
|
JobCard jobCard = jobCardDAO.find(artifact.getJobCardId());
|
||||||
List<Bundle> bundles = bundleDAO.findByItemIdAndCardId( artifact.getItemId( ), jobCard.getId( ));
|
List<Bundle> bundles = bundleDAO.findByItemIdAndCardId(artifact.getItemId(), jobCard.getId());
|
||||||
String concatenatedIds = bundles.stream()
|
String concatenatedIds = bundles.stream()
|
||||||
.map(bundle -> String.valueOf(bundle.getId()))
|
.map(bundle -> String.valueOf(bundle.getId()))
|
||||||
.collect(Collectors.joining("\\"));
|
.collect(Collectors.joining("\\"));
|
||||||
// Set Portrait Mode Dimensions
|
|
||||||
int stickerWidth = (int) stickerSize.getWidth();
|
|
||||||
int stickerHeight = (int) stickerSize.getHeight();
|
|
||||||
|
|
||||||
BufferedImage stickerImage = new BufferedImage(stickerWidth * 2, stickerHeight * 2, BufferedImage.TYPE_INT_ARGB);
|
// **Add New Page for Each Artifact**
|
||||||
Graphics2D g2d = stickerImage.createGraphics();
|
PdfPage page = pdfDoc.addNewPage();
|
||||||
g2d.scale(2, 2);
|
PdfCanvas canvas = new PdfCanvas(page);
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
|
|
||||||
g2d.setColor(Color.WHITE);
|
// **Set Background White**
|
||||||
g2d.fillRect(0, 0, stickerWidth, stickerHeight);
|
canvas.setFillColor(ColorConstants.WHITE);
|
||||||
|
canvas.rectangle(0, 0, stickerSize.getWidth(), stickerSize.getHeight());
|
||||||
|
canvas.fill();
|
||||||
|
|
||||||
// Draw Stitch Line (Dotted Line at the Top)
|
// **Draw QR Code on Left Side**
|
||||||
String stitchLine = "|";
|
|
||||||
Font fontLine = new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()-2);
|
|
||||||
g2d.setFont(fontLine);
|
|
||||||
FontMetrics fontMetricsLine = g2d.getFontMetrics();
|
|
||||||
int textWidthLine = fontMetricsLine.stringWidth(stitchLine);
|
|
||||||
int centerXLine = stickerSize.getMarginLeft();
|
|
||||||
g2d.setColor(Color.BLACK);
|
|
||||||
for(int i=0;i<16;i++){
|
|
||||||
g2d.drawString(stitchLine, centerXLine,5+(i*3));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Draw ID Below Stitch Line
|
|
||||||
String id = String.valueOf(artifact.getId());
|
|
||||||
g2d.setFont(new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()));
|
|
||||||
FontMetrics fontMetricsId = g2d.getFontMetrics();
|
|
||||||
int textHeightId = fontMetricsId.getHeight();
|
|
||||||
int centerXID = stickerSize.getMarginLeft()+7;
|
|
||||||
int centerYID = (stickerHeight / 2) + (textHeightId / 4);
|
|
||||||
AffineTransform originalTransform = g2d.getTransform();
|
|
||||||
g2d.rotate(Math.toRadians(-90), centerXID, centerYID);
|
|
||||||
g2d.drawString(id, centerXID, centerYID);
|
|
||||||
g2d.setTransform(originalTransform);
|
|
||||||
|
|
||||||
// Draw QR Code Below the ID
|
|
||||||
byte[] imgBytes = generateQRCodeImageByteArray(artifact.getBarcode(), stickerSize.getImageWidthBarcode(), stickerSize.getImageHeightBarcode());
|
byte[] imgBytes = generateQRCodeImageByteArray(artifact.getBarcode(), stickerSize.getImageWidthBarcode(), stickerSize.getImageHeightBarcode());
|
||||||
BufferedImage qrCodeImage = ImageIO.read(new ByteArrayInputStream(imgBytes));
|
Image qrCodeImage = new Image(ImageDataFactory.create(imgBytes));
|
||||||
|
|
||||||
int centerXQR = stickerSize.getMarginLeft()-12;
|
float qrX =stickerSize.getMarginLeft() ;
|
||||||
int centerYQR = (stickerHeight / 2) + (textHeightId / 2)+1;
|
float qrY = stickerSize.getMarginTop();
|
||||||
AffineTransform originalTransformQR = g2d.getTransform();
|
|
||||||
g2d.rotate(Math.toRadians(-90), centerXID, centerYID);
|
|
||||||
g2d.drawImage(qrCodeImage, centerXQR, centerYQR, null);
|
|
||||||
g2d.setTransform(originalTransformQR);
|
|
||||||
|
|
||||||
// Prepare Text Lines Below QR Code
|
qrCodeImage.setFixedPosition(qrX + 15, qrY-12);
|
||||||
|
document.add(qrCodeImage);
|
||||||
|
|
||||||
|
|
||||||
|
float textX = stickerSize.getMarginLeft() + 40;
|
||||||
|
float textY = stickerSize.getMarginTop() +40;
|
||||||
|
|
||||||
|
// **Prepare Text Lines**
|
||||||
String sku = artifact.getSku();
|
String sku = artifact.getSku();
|
||||||
String jobCardCode = jobCard.getCode();
|
String jobCardCode = jobCard.getCode();
|
||||||
String combinedText = sku + " \\" + jobCardCode + concatenatedIds;
|
String combinedText = sku + " \\" + jobCardCode + concatenatedIds;
|
||||||
|
|
||||||
int maxLength = 16; // Max characters per line
|
int maxLength = 16;
|
||||||
List<String> lines = new ArrayList<>();
|
List<String> lines = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int start = i * maxLength;
|
int start = i * maxLength;
|
||||||
if (start < combinedText.length()) {
|
if (start < combinedText.length()) {
|
||||||
|
@ -215,35 +294,52 @@ public class BarcodeService {
|
||||||
lines.add(part);
|
lines.add(part);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g2d.rotate(Math.toRadians(-90), stickerWidth / 2, stickerHeight / 2);
|
|
||||||
|
|
||||||
// Draw Rotated Text Below QR Code
|
// **Draw Rotated Text to the Right of QR Code**
|
||||||
g2d.setColor(Color.BLACK);
|
float lineX = textX-30;
|
||||||
g2d.setFont(new Font("Helvetica", Font.BOLD, stickerSize.getTextSize()));
|
for (String line : lines) {
|
||||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
Paragraph rotatedText = new Paragraph(line)
|
||||||
int lineHeight = fontMetrics.getHeight();
|
.setBold()
|
||||||
int centerXSKU = stickerSize.getMarginLeft()+4;
|
.setFontColor(ColorConstants.BLACK) // ✅ Text Color
|
||||||
int centerYSKU = (stickerHeight / 2) + (textHeightId / 4)+20;
|
.setFontSize(stickerSize.getTextSize())
|
||||||
|
.setTextAlignment(TextAlignment.LEFT)
|
||||||
|
.setFixedPosition( lineX, textY+5, 200)
|
||||||
|
.setRotationAngle(-Math.PI / 2); // ✅ -90 Degree Rotate
|
||||||
|
|
||||||
AffineTransform originalTransformSKu = g2d.getTransform();
|
document.add(rotatedText);
|
||||||
g2d.rotate(Math.toRadians(-0.1), centerXSKU, centerYSKU);
|
lineX -= 5; // ✅ Line Gap
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
|
||||||
int lineWidth = fontMetrics.stringWidth(lines.get(i));
|
|
||||||
g2d.drawString(lines.get(i), (stickerWidth - lineWidth) / 2, centerYSKU + (i * lineHeight));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g2d.setTransform(originalTransformSKu);
|
String id = String.valueOf(artifact.getId());
|
||||||
|
document.add(new Paragraph(id)
|
||||||
|
.setFontSize(stickerSize.getTextSize())
|
||||||
|
.setBold()
|
||||||
|
.setRotationAngle(-Math.PI / 2)
|
||||||
|
.setTextAlignment(TextAlignment.LEFT)
|
||||||
|
.setFixedPosition(textX + 30, textY-16, 100));
|
||||||
|
|
||||||
g2d.dispose();
|
float dottedLine = textY - 50;
|
||||||
|
for(int i= 0 ;i<16;i++){
|
||||||
|
document.add(new Paragraph("|")
|
||||||
|
.setFontSize(stickerSize.getTextSize())
|
||||||
|
.setBold()
|
||||||
|
.setTextAlignment(TextAlignment.LEFT)
|
||||||
|
.setFixedPosition(textX + 47, dottedLine, 100));
|
||||||
|
|
||||||
// Save Image
|
dottedLine += 10;
|
||||||
Path path = FileSystems.getDefault().getPath("./src/main/resources/static/sample_qr.png");
|
}
|
||||||
File outputFile = path.toFile();
|
|
||||||
ImageIO.write(stickerImage, "PNG", outputFile);
|
|
||||||
|
|
||||||
|
document.add(new AreaBreak());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public byte[] generateQRCodeImageByteArray(String data, int width, int height) {
|
public byte[] generateQRCodeImageByteArray(String data, int width, int height) {
|
||||||
try {
|
try {
|
||||||
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<item-search
|
<item-search
|
||||||
v-bind:id-field-name="'items[' + index + '].itemId'"
|
v-bind:id-field-name="'items[' + index + '].itemId'"
|
||||||
v-bind:id="item.itemId"
|
v-bind:id="item.itemId"
|
||||||
v-bind:title="item.title"
|
v-bind:type="item.type"
|
||||||
v-bind:show-label="false"
|
v-bind:show-label="false"
|
||||||
v-bind:disabled="true"></item-search>
|
v-bind:disabled="true"></item-search>
|
||||||
</td>
|
</td>
|
||||||
|
@ -64,12 +64,12 @@
|
||||||
<select style="width: 150px;" class="form-control" v-bind:name="'pieces[' + index +'].type'" v-model="piece.type" disabled>
|
<select style="width: 150px;" class="form-control" v-bind:name="'pieces[' + index +'].type'" v-model="piece.type" disabled>
|
||||||
<option value="">Please Select</option>
|
<option value="">Please Select</option>
|
||||||
<option v-for="(type,index) in $types"
|
<option v-for="(type,index) in $types"
|
||||||
v-bind:selected="type.title === piece.type"
|
v-bind:selected="type.type === piece.type"
|
||||||
v-bind:value="type.title">{{type.title}}</option>
|
v-bind:value="type.type">{{type.type}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6" style="padding-left: 40px;">
|
<div class="col-md-6" style="padding-left: 40px;">
|
||||||
<input class="form-control" type="number" v-bind:name="'items[' + pIndex + '].pieces[' + index +'].quantity'" v-model="piece.quantity" required/>
|
<input class="form-control" type="number" v-bind:name="'items[' + pIndex + '].pieces[' + index +'].quantity'" v-model="piece.quantity" min="0" required/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
<select name="type" class="form-control">
|
<select name="type" class="form-control">
|
||||||
<option value="">Please select</option>
|
<option value="">Please select</option>
|
||||||
<option th:each="type: ${types}"
|
<option th:each="type: ${types}"
|
||||||
th:value="${type.title}"
|
th:value="${type.type}"
|
||||||
th:text="${type.title}"
|
th:text="${type.type}"
|
||||||
th:selected="${#strings.equals(param['type'], #strings.toString(type.title))}"
|
th:selected="${#strings.equals(param['type'], #strings.toString(type.type))}"
|
||||||
></option>
|
></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue