diff --git a/api/src/main/java/org/openmrs/module/billing/util/BillingPdfConstants.java b/api/src/main/java/org/openmrs/module/billing/util/BillingPdfConstants.java new file mode 100644 index 00000000..70832655 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/billing/util/BillingPdfConstants.java @@ -0,0 +1,34 @@ +package org.openmrs.module.billing.util; + +public interface BillingPdfConstants { + + String GP_BILL_LOGO_PATH = "billing.receipt.logoPath"; + + int PAGE_WIDTH_PTS = 288; + + int PAGE_HEIGHT_PTS = 720; + + int FONT_SIZE_NORMAL = 12; + + int FONT_SIZE_SMALL = 10; + + int FONT_SIZE_FOOTER = 8; + + float[] HEADER_COL_WIDTHS = { 2f, 7f }; + + float[] BILL_COL_WIDTHS = { 1f, 5f, 2f, 2f }; + + float[] TOTALS_COL_WIDTHS = { 1f, 5f, 2f, 2f }; + + float[] PAYMENT_COL_WIDTHS = { 1f, 5f, 2f, 2f }; + + int BILLING_RECEIPT_PDF_TOP_MARGIN = 6; + + int BILLING_RECEIPT_PDF_RIGHT_MARGIN = 12; + + int BILLING_RECEIPT_PDF_BOTTOM_MARGIN = 2; + + int BILLING_RECEIPT_PDF_LEFT_MARGIN = 12; + + String DIVIDER = "------------------------------------------------------------------"; +} diff --git a/api/src/main/java/org/openmrs/module/billing/util/ReceiptGenerator.java b/api/src/main/java/org/openmrs/module/billing/util/ReceiptGenerator.java index b0091e1e..7b7cf754 100644 --- a/api/src/main/java/org/openmrs/module/billing/util/ReceiptGenerator.java +++ b/api/src/main/java/org/openmrs/module/billing/util/ReceiptGenerator.java @@ -15,7 +15,6 @@ import com.itextpdf.layout.element.Image; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.element.Table; -import com.itextpdf.layout.element.Text; import com.itextpdf.layout.properties.TextAlignment; import com.itextpdf.layout.properties.UnitValue; import org.apache.commons.lang3.StringUtils; @@ -41,8 +40,6 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; -import java.time.LocalDate; - import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; @@ -51,29 +48,13 @@ public class ReceiptGenerator { private static final Logger LOG = LoggerFactory.getLogger(ReceiptGenerator.class); - private static final String GP_BILL_LOGO_PATH = "billing.receipt.logoPath"; - - //TODO: Try to clean this up more public static byte[] createBillReceipt(Bill bill) { - NumberFormat nf = NumberFormat.getCurrencyInstance(LocaleUtility.getDefaultLocale()); - String currencySymbol = ConfigUtil.getGlobalProperty(CashierModuleConstants.GLOBAL_PROPERTY_BILLING_CURRENCY); - if (StringUtils.isNotBlank(currencySymbol) && nf instanceof DecimalFormat) { - DecimalFormat df = (DecimalFormat) nf; - DecimalFormatSymbols symbols = df.getDecimalFormatSymbols(); - symbols.setCurrencySymbol(currencySymbol.trim()); - df.setDecimalFormatSymbols(symbols); - } + NumberFormat nf = buildNumberFormat(); DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM) .withLocale(LocaleUtility.getDefaultLocale()); - Patient patient = bill.getPatient(); - String fullName = patient.getPersonName().getFullName(); - String gender = patient.getGender() != null ? patient.getGender() : ""; - String dob = ""; - if (patient.getBirthdate() != null) { - LocalDate birthDate = patient.getBirthdate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); - dob = dateFormatter.format(birthDate); - } + ReceiptFonts receiptFonts = loadFonts(); + Image logoImage = loadLogoImage(); /** * https://kb.itextpdf.com/home/it7kb/faq/how-to-set-the-page-size-to-envelope-size-with-landscape-orientation @@ -82,196 +63,240 @@ public static byte[] createBillReceipt(Bill bill) { * doesn't use inches, but user units. By default, 1 user unit = 1 point, and 1 inch = 72 points. * Thermal printer: 4 x 10 inches paper 4 inches = 4 x 72 = 288 5 inches = 10 x 72 = 720 */ - int FONT_SIZE_12 = 12; - Rectangle thermalPrinterPageSize = new Rectangle(288, 720); - - PdfFont timesRoman; - PdfFont courierBold; - PdfFont helvetica; - PdfFont helveticaBold; - try { - timesRoman = PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN); - courierBold = PdfFontFactory.createFont(StandardFonts.COURIER_BOLD); - helvetica = PdfFontFactory.createFont(StandardFonts.HELVETICA); - helveticaBold = PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD); - - } - catch (IOException e) { - throw new RuntimeException(e); - } - - PdfFont headerSectionFont = helveticaBold; - PdfFont billItemSectionFont = helvetica; - PdfFont footerSectionFont = courierBold; - URL logoUrl = null; + Rectangle thermalPrinterPageSize = new Rectangle(BillingPdfConstants.PAGE_WIDTH_PTS, + BillingPdfConstants.PAGE_HEIGHT_PTS); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); - String logoPath = ConfigUtil.getGlobalProperty(GP_BILL_LOGO_PATH); - if (StringUtils.isNotBlank(logoPath)) { - File file = new File(logoPath.trim()); - if (!file.isAbsolute()) { - file = new File(OpenmrsUtil.getApplicationDataDirectory(), logoPath.trim()); - } - - if (file.exists()) { - try { - logoUrl = file.getAbsoluteFile().toURI().toURL(); - } - catch (MalformedURLException e) { - LOG.error("Error Loading file: {}", file.getAbsoluteFile(), e); - } - } + try (PdfDocument pdfDoc = new PdfDocument(new PdfWriter(bos)); + Document doc = new Document(pdfDoc, new PageSize(thermalPrinterPageSize))) { + doc.setMargins(BillingPdfConstants.BILLING_RECEIPT_PDF_TOP_MARGIN, + BillingPdfConstants.BILLING_RECEIPT_PDF_RIGHT_MARGIN, BillingPdfConstants.BILLING_RECEIPT_PDF_BOTTOM_MARGIN, + BillingPdfConstants.BILLING_RECEIPT_PDF_LEFT_MARGIN); + doc.add(buildLogoSection(logoImage, receiptFonts)); + //doc.add(addressSection); + doc.add(buildReceiptHeader(bill, dateFormatter, receiptFonts)); + doc.add(divider()); + doc.add(buildLineItemsTable(bill, nf, receiptFonts)); + doc.add(divider()); + doc.add(buildTotalsSection(bill, nf, receiptFonts)); + doc.add(divider()); + doc.add(buildPaymentSection(bill, nf, receiptFonts)); + doc.add(divider()); + doc.add(buildAmountDueSection(bill, nf, receiptFonts)); + doc.add(divider()); + doc.add(buildFooter(bill, receiptFonts)); } - - if (logoUrl == null) { - logoUrl = OpenmrsClassLoader.getInstance().getResource("img/openmrs-logo.png"); + catch (Exception e) { + LOG.error("Exception caught while writing PDF to stream", e); + return bos.toByteArray(); } - Image logoImage = null; - if (logoUrl != null) { - logoImage = new Image(ImageDataFactory.create(logoUrl)); - logoImage.scaleToFit(80, 80); + return bos.toByteArray(); + } + + private static NumberFormat buildNumberFormat() { + NumberFormat nf = NumberFormat.getCurrencyInstance(LocaleUtility.getDefaultLocale()); + String currencySymbol = ConfigUtil.getGlobalProperty(CashierModuleConstants.GLOBAL_PROPERTY_BILLING_CURRENCY); + if (StringUtils.isNotBlank(currencySymbol) && nf instanceof DecimalFormat) { + DecimalFormat df = (DecimalFormat) nf; + DecimalFormatSymbols symbols = df.getDecimalFormatSymbols(); + symbols.setCurrencySymbol(currencySymbol.trim()); + df.setDecimalFormatSymbols(symbols); } - Paragraph divider = new Paragraph("------------------------------------------------------------------"); - Text billDateLabel = new Text(Utils.getSimpleDateFormat("dd-MMM-yyyy HH:mm:ss").format(bill.getDateCreated())); - + return nf; + } + + private static Paragraph buildLogoSection(Image logoImage, ReceiptFonts receiptFonts) { Paragraph logoSection = null; if (logoImage != null) { logoSection = new Paragraph(); logoSection.setFontSize(14); logoSection.add(logoImage).add("\n"); logoSection.setTextAlignment(TextAlignment.CENTER); - logoSection.setFont(timesRoman).setBold(); + logoSection.setFont(receiptFonts.logoSectionFont).setBold(); } - - float[] headerColWidth = { 2f, 7f }; - Table receiptHeader = new Table(headerColWidth); + return logoSection; + } + + private static Table buildReceiptHeader(Bill bill, DateTimeFormatter dateFormatter, ReceiptFonts receiptFonts) { + Table receiptHeader = new Table(BillingPdfConstants.HEADER_COL_WIDTHS); receiptHeader.setWidth(UnitValue.createPercentValue(100f)); - receiptHeader.addCell(new Paragraph("Date:")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.LEFT) - .setFont(headerSectionFont); - receiptHeader.addCell(new Paragraph(billDateLabel.getText())).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT).setFont(helvetica); - - receiptHeader.addCell(new Paragraph("Receipt No:")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.LEFT) - .setFont(headerSectionFont); - receiptHeader.addCell(new Paragraph(bill.getReceiptNumber())).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT).setFont(helvetica); - - receiptHeader.addCell(new Paragraph("Patient:")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.LEFT) - .setFont(headerSectionFont); - receiptHeader.addCell(new Paragraph(WordUtils.capitalizeFully(fullName))).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT).setFont(helvetica); - - receiptHeader.addCell(new Paragraph("Gender:")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.LEFT) - .setFont(headerSectionFont); - receiptHeader.addCell(new Paragraph(WordUtils.capitalizeFully(gender))).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT).setFont(helvetica); + String billDate = Utils.getSimpleDateFormat("dd-MMM-yyyy HH:mm:ss").format(bill.getDateCreated()); + Patient patient = bill.getPatient(); + String dob = patient.getBirthdate() != null + ? dateFormatter.format(patient.getBirthdate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) + : ""; - receiptHeader.addCell(new Paragraph("Date of Birth:")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.LEFT) - .setFont(headerSectionFont); - receiptHeader.addCell(new Paragraph(WordUtils.capitalizeFully(dob))).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT).setFont(helvetica); + addHeaderRow(receiptHeader, "Date", billDate, receiptFonts); + addHeaderRow(receiptHeader, "Receipt No", bill.getReceiptNumber(), receiptFonts); + addHeaderRow(receiptHeader, "Patient", WordUtils.capitalizeFully(patient.getPersonName().getFullName()), + receiptFonts); + addHeaderRow(receiptHeader, "Gender", WordUtils.capitalizeFully(nullSafe(patient.getGender())), receiptFonts); + addHeaderRow(receiptHeader, "Date of Birth", WordUtils.capitalizeFully(dob), receiptFonts); - float[] columnWidths = { 1f, 5f, 2f, 2f }; - Table billLineItemstable = new Table(columnWidths); - billLineItemstable.setBorder(Border.NO_BORDER); + setInnerCellBorder(receiptHeader, Border.NO_BORDER); + return receiptHeader; + } + + private static Table buildLineItemsTable(Bill bill, NumberFormat nf, ReceiptFonts receiptFonts) { + Table billLineItemstable = new Table(BillingPdfConstants.BILL_COL_WIDTHS); billLineItemstable.setWidth(UnitValue.createPercentValue(100f)); + billLineItemstable.setBorder(Border.NO_BORDER); - billLineItemstable.addCell(new Paragraph("Qty").setTextAlignment(TextAlignment.LEFT)).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT); - billLineItemstable.addCell(new Paragraph("Item").setTextAlignment(TextAlignment.LEFT)).setFontSize(FONT_SIZE_12) - .setTextAlignment(TextAlignment.LEFT); - billLineItemstable.addCell(new Paragraph("Price")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.RIGHT); - billLineItemstable.addCell(new Paragraph("Total")).setFontSize(FONT_SIZE_12).setTextAlignment(TextAlignment.RIGHT); + addFormattedCell(billLineItemstable, "Qty", receiptFonts.billItemSectionFont, TextAlignment.LEFT); + addFormattedCell(billLineItemstable, "Item", receiptFonts.billItemSectionFont, TextAlignment.LEFT); + addFormattedCell(billLineItemstable, "Price", receiptFonts.billItemSectionFont, TextAlignment.RIGHT); + addFormattedCell(billLineItemstable, "Total", receiptFonts.billItemSectionFont, TextAlignment.RIGHT); for (BillLineItem item : bill.getLineItems()) { - if (item.getVoided()) { - continue; + if (!item.getVoided()) { + addBillLineItemRow(billLineItemstable, item, receiptFonts.billItemSectionFont, nf); } - - addBillLineItem(item, billLineItemstable, billItemSectionFont, nf); } - float[] totalColWidth = { 1f, 5f, 2f, 2f }; - Table totalsSection = new Table(totalColWidth); + setInnerCellBorder(billLineItemstable, Border.NO_BORDER); + return billLineItemstable; + } + + private static Table buildTotalsSection(Bill bill, NumberFormat nf, ReceiptFonts receiptFonts) { + Table totalsSection = new Table(BillingPdfConstants.TOTALS_COL_WIDTHS); totalsSection.setWidth(UnitValue.createPercentValue(100f)); - totalsSection.addCell(new Paragraph(" ")); - totalsSection.addCell(new Paragraph(" ")); - totalsSection.addCell(new Paragraph("Total")).setFontSize(10).setTextAlignment(TextAlignment.RIGHT) - .setFont(helvetica).setBold(); - totalsSection.addCell(new Paragraph(nf.format(bill.getTotal()))).setFontSize(10) - .setTextAlignment(TextAlignment.RIGHT).setFont(helvetica).setBold(); - - setInnerCellBorder(receiptHeader, Border.NO_BORDER); - setInnerCellBorder(billLineItemstable, Border.NO_BORDER); + totalsSection.addCell(blankCell()); + totalsSection.addCell(blankCell()); + totalsSection.addCell(new Paragraph("Total").setTextAlignment(TextAlignment.RIGHT)) + .setFontSize(BillingPdfConstants.FONT_SIZE_SMALL).setFont(receiptFonts.billItemSectionFont).setBold(); + totalsSection.addCell(new Paragraph(nf.format(bill.getTotal())).setTextAlignment(TextAlignment.RIGHT)) + .setFontSize(BillingPdfConstants.FONT_SIZE_SMALL).setFont(receiptFonts.billItemSectionFont).setBold(); - float[] paymentColWidth = { 1f, 5f, 2f, 2f }; - Table paymentSection = new Table(paymentColWidth); + setInnerCellBorder(totalsSection, Border.NO_BORDER); + return totalsSection; + } + + private static Table buildPaymentSection(Bill bill, NumberFormat nf, ReceiptFonts receiptFonts) { + Table paymentSection = new Table(BillingPdfConstants.PAYMENT_COL_WIDTHS); paymentSection.setWidth(UnitValue.createPercentValue(100f)); - paymentSection.addCell(new Paragraph(" ")); - paymentSection.addCell(new Paragraph(" ")); + + paymentSection.addCell(blankCell()); + paymentSection.addCell(blankCell()); paymentSection.addCell(new Paragraph("Payment").setTextAlignment(TextAlignment.RIGHT).setBold()); - paymentSection.addCell(new Paragraph("")); - // append payment rows + paymentSection.addCell(blankCell()); + for (Payment payment : bill.getPayments()) { - paymentSection.addCell(new Paragraph(" ")); - paymentSection.addCell(new Paragraph(" ")); + paymentSection.addCell(blankCell()); + paymentSection.addCell(blankCell()); paymentSection.addCell(new Paragraph(payment.getInstanceType().getName()).setTextAlignment(TextAlignment.RIGHT)) - .setFontSize(10).setFont(helvetica); + .setFontSize(BillingPdfConstants.FONT_SIZE_SMALL).setFont(receiptFonts.billItemSectionFont); paymentSection .addCell(new Paragraph(nf.format(payment.getAmountTendered())).setTextAlignment(TextAlignment.RIGHT)) - .setFontSize(10).setFont(helvetica); + .setFontSize(BillingPdfConstants.FONT_SIZE_SMALL).setFont(receiptFonts.billItemSectionFont); } - float[] amountDueColWidth = { 1f, 5f, 2f, 2f }; - Table amountDueSection = new Table(amountDueColWidth); + setInnerCellBorder(paymentSection, Border.NO_BORDER); + return paymentSection; + } + + private static Table buildAmountDueSection(Bill bill, NumberFormat nf, ReceiptFonts receiptFonts) { + Table amountDueSection = new Table(BillingPdfConstants.PAYMENT_COL_WIDTHS); amountDueSection.setWidth(UnitValue.createPercentValue(100f)); - amountDueSection.addCell(new Paragraph(" ")); - amountDueSection.addCell(new Paragraph(" ")); - - amountDueSection.addCell(new Paragraph("Due Amount")).setFontSize(10).setTextAlignment(TextAlignment.RIGHT) - .setFont(helvetica).setBold(); BigDecimal dueAmount = bill.getTotal().subtract(bill.getTotalPayments()); - if (dueAmount.compareTo(BigDecimal.ZERO) > 0) { - amountDueSection.addCell(new Paragraph(nf.format(dueAmount))).setFontSize(10) - .setTextAlignment(TextAlignment.RIGHT).setFont(helvetica).setBold(); - } else { - amountDueSection.addCell(new Paragraph("0.00")).setFontSize(10).setTextAlignment(TextAlignment.RIGHT) - .setFont(helvetica).setBold(); - } - setInnerCellBorder(paymentSection, Border.NO_BORDER); - setInnerCellBorder(amountDueSection, Border.NO_BORDER); - setInnerCellBorder(totalsSection, Border.NO_BORDER); + String dueFormatted = dueAmount.compareTo(BigDecimal.ZERO) > 0 ? nf.format(dueAmount) : "0.00"; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - try (PdfDocument pdfDoc = new PdfDocument(new PdfWriter(bos)); - Document doc = new Document(pdfDoc, new PageSize(thermalPrinterPageSize))) { - doc.setMargins(6, 12, 2, 12); - if (logoSection != null) { - doc.add(logoSection); + amountDueSection.addCell(blankCell()); + amountDueSection.addCell(blankCell()); + amountDueSection.addCell(new Paragraph("Due Amount").setTextAlignment(TextAlignment.RIGHT)) + .setFontSize(BillingPdfConstants.FONT_SIZE_SMALL).setFont(receiptFonts.billItemSectionFont).setBold(); + amountDueSection.addCell(new Paragraph(dueFormatted).setTextAlignment(TextAlignment.RIGHT)) + .setFontSize(BillingPdfConstants.FONT_SIZE_SMALL).setFont(receiptFonts.billItemSectionFont).setBold(); + + setInnerCellBorder(amountDueSection, Border.NO_BORDER); + return amountDueSection; + } + + private static Paragraph buildFooter(Bill bill, ReceiptFonts receiptFonts) { + return new Paragraph("You were served by " + bill.getCashier().getName()).setFont(receiptFonts.footerSectionFont) + .setFontSize(BillingPdfConstants.FONT_SIZE_FOOTER).setTextAlignment(TextAlignment.CENTER); + } + + private static void addHeaderRow(Table receiptHeader, String label, String value, ReceiptFonts receiptFonts) { + receiptHeader.addCell(new Paragraph(label)).setFontSize(BillingPdfConstants.FONT_SIZE_NORMAL) + .setTextAlignment(TextAlignment.LEFT).setFont(receiptFonts.headerSectionFont); + receiptHeader.addCell(new Paragraph(value)).setFontSize(BillingPdfConstants.FONT_SIZE_NORMAL) + .setTextAlignment(TextAlignment.LEFT).setFont(receiptFonts.billItemSectionFont); + } + + private static void addBillLineItemRow(Table billLineItemstable, BillLineItem item, PdfFont billItemSectionFont, + NumberFormat nf) { + String itemName = resolveItemName(item); + addFormattedCell(billLineItemstable, item.getQuantity().toString(), billItemSectionFont, TextAlignment.LEFT); + addFormattedCell(billLineItemstable, itemName, billItemSectionFont, TextAlignment.LEFT); + addFormattedCell(billLineItemstable, nf.format(item.getPrice()), billItemSectionFont, TextAlignment.RIGHT); + addFormattedCell(billLineItemstable, nf.format(item.getTotal()), billItemSectionFont, TextAlignment.RIGHT); + } + + private static Paragraph divider() { + return new Paragraph(BillingPdfConstants.DIVIDER); + } + + private static Paragraph blankCell() { + return new Paragraph(" "); + } + + private static String resolveItemName(BillLineItem item) { + if (item.getItem() != null && item.getItem().getDrug() != null) { + return item.getItem().getDrug().getName(); + } + if (item.getBillableService() != null) { + return item.getBillableService().getName(); + } + return ""; + } + + private static String nullSafe(String value) { + return value != null ? value : ""; + } + + private static Image loadLogoImage() { + URL logoUrl = resolveLogoUrl(); + if (logoUrl == null) { + return null; + } + Image logoImage = new Image(ImageDataFactory.create(logoUrl)); + logoImage.scaleToFit(80, 80); + return logoImage; + } + + private static URL resolveLogoUrl() { + String logoPath = ConfigUtil.getGlobalProperty(BillingPdfConstants.GP_BILL_LOGO_PATH); + if (StringUtils.isNotBlank(logoPath)) { + File file = new File(logoPath.trim()); + if (!file.isAbsolute()) { + file = new File(OpenmrsUtil.getApplicationDataDirectory(), logoPath.trim()); + } + if (file.exists()) { + try { + return file.getAbsoluteFile().toURI().toURL(); + } + catch (MalformedURLException e) { + LOG.error("Invalid logo path '{}': {}", file.getAbsolutePath(), e.getMessage()); + } } - //doc.add(addressSection); - doc.add(receiptHeader); - doc.add(divider); - doc.add(billLineItemstable); - doc.add(divider); - doc.add(totalsSection); - doc.add(divider); - doc.add(paymentSection); - doc.add(divider); - doc.add(amountDueSection); - doc.add(divider); - doc.add(new Paragraph("You were served by " + bill.getCashier().getName()).setFont(footerSectionFont) - .setFontSize(8).setTextAlignment(TextAlignment.CENTER)); } - catch (Exception e) { - LOG.error("Exception caught while writing PDF to stream", e); - return bos.toByteArray(); + return OpenmrsClassLoader.getInstance().getResource("img/openmrs-logo.png"); + } + + private static ReceiptFonts loadFonts() { + try { + return new ReceiptFonts(PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN), + PdfFontFactory.createFont(StandardFonts.HELVETICA_BOLD), + PdfFontFactory.createFont(StandardFonts.HELVETICA), + PdfFontFactory.createFont(StandardFonts.COURIER_BOLD)); + } + catch (IOException e) { + throw new IllegalStateException("Failed to load PDF fonts", e); } - - return bos.toByteArray(); } private static void setInnerCellBorder(Table table, Border border) { @@ -282,21 +307,27 @@ private static void setInnerCellBorder(Table table, Border border) { } } - private static void addBillLineItem(BillLineItem item, Table table, PdfFont font, NumberFormat nf) { - String itemName = ""; - if (item.getItem() != null) { - itemName = item.getItem().getDrug().getName(); - } else if (item.getBillableService() != null) { - itemName = item.getBillableService().getName(); - } - addFormattedCell(table, item.getQuantity().toString(), font, TextAlignment.LEFT); - addFormattedCell(table, itemName, font, TextAlignment.LEFT); - addFormattedCell(table, nf.format(item.getPrice()), font, TextAlignment.RIGHT); - addFormattedCell(table, nf.format(item.getTotal()), font, TextAlignment.RIGHT); - } - private static void addFormattedCell(Table table, String cellValue, PdfFont font, TextAlignment alignment) { table.addCell(new Paragraph(cellValue).setTextAlignment(alignment)).setFontSize(12).setTextAlignment(alignment) .setBorder(Border.NO_BORDER).setFont(font); } + + private static final class ReceiptFonts { + + final PdfFont logoSectionFont; + + final PdfFont headerSectionFont; + + final PdfFont billItemSectionFont; + + final PdfFont footerSectionFont; + + ReceiptFonts(PdfFont logoSectionFont, PdfFont headerSectionFont, PdfFont billItemSectionFont, + PdfFont footerSectionFont) { + this.logoSectionFont = logoSectionFont; + this.headerSectionFont = headerSectionFont; + this.billItemSectionFont = billItemSectionFont; + this.footerSectionFont = footerSectionFont; + } + } }