From 27ecd5e99a502ce89cb0845d50cf3df940c66eb8 Mon Sep 17 00:00:00 2001 From: Adarsh Samani Date: Sat, 1 Feb 2025 21:34:09 +0530 Subject: [PATCH 1/3] Add QR Style Barcode --- .../components/printBarcode/BarcodeContext.js | 6 + .../components/printBarcode/ExistingOrder.js | 11 +- frontend/src/components/printBarcode/Index.js | 52 ++- .../src/components/printBarcode/PrePrint.js | 59 ++- pom.xml | 48 +++ .../barcode/BarcodeLabelMaker.java | 363 ++++++++---------- .../servlet/barcode/LabelMakerServlet.java | 15 + 7 files changed, 336 insertions(+), 218 deletions(-) create mode 100644 frontend/src/components/printBarcode/BarcodeContext.js diff --git a/frontend/src/components/printBarcode/BarcodeContext.js b/frontend/src/components/printBarcode/BarcodeContext.js new file mode 100644 index 0000000000..ab71e40025 --- /dev/null +++ b/frontend/src/components/printBarcode/BarcodeContext.js @@ -0,0 +1,6 @@ +import React from 'react'; + +export const BarcodeContext = React.createContext({ + format: 'barcode', + setFormat: () => {}, +}); \ No newline at end of file diff --git a/frontend/src/components/printBarcode/ExistingOrder.js b/frontend/src/components/printBarcode/ExistingOrder.js index e0d7bf1bef..19f025e9ab 100644 --- a/frontend/src/components/printBarcode/ExistingOrder.js +++ b/frontend/src/components/printBarcode/ExistingOrder.js @@ -19,8 +19,12 @@ import CustomLabNumberInput from "../common/CustomLabNumberInput"; import { NotificationContext } from "../layout/Layout"; import { AlertDialog, NotificationKinds } from "../common/CustomNotification"; import { getFromOpenElisServer } from "../utils/Utils"; +import { BarcodeContext } from './BarcodeContext'; const ExistingOrder = () => { + const { format } = useContext(BarcodeContext); + // console.log(format); + const intl = useIntl(); const componentMounted = useRef(false); const [accessionNumber, setAccessionNumber] = useState(""); @@ -75,21 +79,21 @@ const ExistingOrder = () => { const printLabelSets = () => { setSource( - `/LabelMakerServlet?labNo=${accessionNumber}&type=default&quantity=`, + `/LabelMakerServlet?labNo=${accessionNumber}&type=default&quantity=&format=${format}`, ); setRenderBarcode(true); }; const printOrderLabels = () => { setSource( - `/LabelMakerServlet?labNo=${accessionNumber}&type=order&quantity=${orderLabels}`, + `/LabelMakerServlet?labNo=${accessionNumber}&type=order&quantity=${orderLabels}&format=${format}`, ); setRenderBarcode(true); }; const printSpecimenLabels = (specimenAccessionNumber) => { setSource( - `/LabelMakerServlet?labNo=${specimenAccessionNumber}&type=specimen&quantity=1`, + `/LabelMakerServlet?labNo=${specimenAccessionNumber}&type=specimen&quantity=1&format=${format}`, ); setRenderBarcode(true); }; @@ -279,3 +283,4 @@ const ExistingOrder = () => { ); }; export default injectIntl(ExistingOrder); + diff --git a/frontend/src/components/printBarcode/Index.js b/frontend/src/components/printBarcode/Index.js index 6fa84c39df..1342da6d50 100644 --- a/frontend/src/components/printBarcode/Index.js +++ b/frontend/src/components/printBarcode/Index.js @@ -1,29 +1,49 @@ -import React from "react"; +import React, { useState } from "react"; import { FormattedMessage } from "react-intl"; -import { Column, Grid, Heading, Section } from "@carbon/react"; +import { Column, Grid, Heading, Section, Select, SelectItem } from "@carbon/react"; import ExistingOrder from "./ExistingOrder"; import PrePrint from "./PrePrint"; import PageBreadCrumb from "../common/PageBreadCrumb.js"; +import { BarcodeContext } from './BarcodeContext'; let breadcrumbs = [{ label: "home.label", link: "/" }]; + const PrintBarcode = () => { + const [barcodeFormat, setBarcodeFormat] = useState('barcode'); + return ( -
- - - -
+ +
+ + +
- - - +
+ + + +
-
-
-
- - -
+ + + + + + + + + + + ); }; + export default PrintBarcode; diff --git a/frontend/src/components/printBarcode/PrePrint.js b/frontend/src/components/printBarcode/PrePrint.js index b56929ca89..f91443849e 100644 --- a/frontend/src/components/printBarcode/PrePrint.js +++ b/frontend/src/components/printBarcode/PrePrint.js @@ -1,4 +1,4 @@ -import { React, useState, useEffect, useRef } from "react"; +import { React, useState, useEffect, useRef, useContext } from "react"; import { FormattedMessage, useIntl, injectIntl } from "react-intl"; import { Checkbox, @@ -14,8 +14,12 @@ import { getFromOpenElisServer } from "../utils/Utils"; import { sampleTypeTestsStructure } from "../data/SampleEntryTestsForTypeProvider"; import AutoComplete from "../common/AutoComplete"; import "../Style.css"; +import { BarcodeContext } from './BarcodeContext'; const PrePrint = () => { + const { format } = useContext(BarcodeContext); + // console.log(format); + const intl = useIntl(); const componentMounted = useRef(false); const [sampleTypes, setSampleTypes] = useState([]); @@ -149,11 +153,30 @@ const PrePrint = () => { setSelectedPanels([]); }; - const prePrintLabels = () => { + // const prePrintLabels = () => { + // console.log(selectedPanels); + // const selectedTestIds = selectedTests + // .map((selectedTest) => selectedTest.id) + // .join(","); + // const params = new URLSearchParams({ + // prePrinting: "true", + // numSetsOfLabels: labelSets, + // numOrderLabelsPerSet: orderLabelsPerSet, + // numSpecimenLabelsPerSet: specimenLabelsPerSet, + // facilityName: facilityId, + // testIds: selectedTestIds, + // format: format, + // }); + // setSource(`LabelMakerServlet?${params.toString()}`); + // setRenderBarcode(true); + // }; + + const prePrintLabels = async () => { console.log(selectedPanels); const selectedTestIds = selectedTests .map((selectedTest) => selectedTest.id) .join(","); + const params = new URLSearchParams({ prePrinting: "true", numSetsOfLabels: labelSets, @@ -161,9 +184,36 @@ const PrePrint = () => { numSpecimenLabelsPerSet: specimenLabelsPerSet, facilityName: facilityId, testIds: selectedTestIds, + format: format, }); - setSource(`LabelMakerServlet?${params.toString()}`); - setRenderBarcode(true); + + const url = `LabelMakerServlet?${params.toString()}`; + console.log('Fetching labels from:', url); + + try { + const response = await fetch(url, { + // Add these options to ensure we can see the custom headers + credentials: 'include', + headers: { + 'Accept': '*/*', + } + }); + + // Log the entire headers for debugging + console.log('All response headers:'); + for (const [key, value] of response.headers.entries()) { + console.log(`${key}: ${value}`); + } + + // Log the specific debug header + const debugLog = response.headers.get('X-Debug-Log'); + console.log('Debug Log:', debugLog); + + setSource(url); + setRenderBarcode(true); + } catch (error) { + console.error('Error fetching labels:', error); + } }; useEffect(() => { @@ -387,3 +437,4 @@ const PrePrint = () => { ); }; export default injectIntl(PrePrint); + diff --git a/pom.xml b/pom.xml index 765107f81f..0ce04a2519 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,40 @@ + + + com.itextpdf + itext7-core + 7.2.5 + pom + + + + + com.itextpdf + layout + 7.2.5 + + + + + com.itextpdf + barcodes + 7.2.5 + + + + + com.google.zxing + core + 3.5.2 + + + com.google.zxing + javase + 3.5.2 + + commons-codec commons-codec @@ -573,6 +607,20 @@ + + + + central + Central Repository + https://repo.maven.apache.org/maven2 + + + + + itext + iText Repository - releases + https://repo.itextsupport.com/releases + jaspersoft-third-party https://jaspersoft.jfrog.io/jaspersoft/third-party-ce-artifacts/ diff --git a/src/main/java/org/openelisglobal/barcode/BarcodeLabelMaker.java b/src/main/java/org/openelisglobal/barcode/BarcodeLabelMaker.java index 048facd24e..d363b2a06f 100644 --- a/src/main/java/org/openelisglobal/barcode/BarcodeLabelMaker.java +++ b/src/main/java/org/openelisglobal/barcode/BarcodeLabelMaker.java @@ -1,5 +1,11 @@ package org.openelisglobal.barcode; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.Writer; +import com.google.zxing.qrcode.QRCodeWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.encoder.QRCode; + import com.lowagie.text.BadElementException; import com.lowagie.text.Chunk; import com.lowagie.text.Document; @@ -15,12 +21,18 @@ import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.draw.LineSeparator; + +import java.awt.image.BufferedImage; +import java.awt.Graphics2D; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; + +import javax.imageio.ImageIO; + import org.openelisglobal.barcode.labeltype.BlankLabel; import org.openelisglobal.barcode.labeltype.BlockLabel; import org.openelisglobal.barcode.labeltype.Label; @@ -46,28 +58,18 @@ import org.openelisglobal.spring.util.SpringContext; import org.openelisglobal.test.valueholder.Test; -/** - * Class for taking lists of Label objects and turning them into a printable - * format - * - * @author Caleb - */ public class BarcodeLabelMaker { - // number of columns for label layout grid - private static int NUM_COLUMNS = 20; + public enum BarcodeType { + BARCODE, QR + } - // stores labels between generation and creating pdf + private BarcodeType barcodeType; + private static int NUM_COLUMNS = 20; private ArrayList