diff --git a/.vscode/settings.json b/.vscode/settings.json index a760fd6..9bd06c2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { - "java.configuration.updateBuildConfiguration": "interactive", + "java.configuration.updateBuildConfiguration": "automatic", "java.debug.settings.onBuildFailureProceed": true } \ No newline at end of file diff --git a/config/config.properties b/config/config.properties index 3712df6..70d52d0 100644 --- a/config/config.properties +++ b/config/config.properties @@ -9,3 +9,4 @@ server.address=127.0.0.1 server.port=1999 storage.checkup_media_base_dir=src/main/resources/image/checkup_media storage.image_db_path=img_db +app.project_path=D:/Github Clones/BSK-All-in-One-Clinic-Management-System \ No newline at end of file diff --git a/medical_invoice.pdf b/medical_invoice.pdf index 95baf0a..027b59e 100644 Binary files a/medical_invoice.pdf and b/medical_invoice.pdf differ diff --git a/pom.xml b/pom.xml index b61a1f8..374ffc8 100644 --- a/pom.xml +++ b/pom.xml @@ -316,5 +316,10 @@ poi-ooxml 5.2.5 + + com.zaxxer + HikariCP + 5.1.0 + diff --git a/src/main/java/BsK/client/Client.java b/src/main/java/BsK/client/Client.java index 6413cad..e213a50 100644 --- a/src/main/java/BsK/client/Client.java +++ b/src/main/java/BsK/client/Client.java @@ -136,6 +136,15 @@ public class Client { log.info("Using default auto change status: {}", LocalStorage.autoChangeStatusToFinished); } + //load projectPath + String projectPath = config.getProperty("app.project_path"); + if (projectPath != null && !projectPath.trim().isEmpty()) { + LocalStorage.pathToProject = projectPath.trim(); + log.info("Using configured project path: {}", projectPath); + } else { + log.info("Using default project path: {}", LocalStorage.pathToProject); + } + // Use defaults if not configured if (portStr != null) { int port = Integer.parseInt(portStr); diff --git a/src/main/java/BsK/client/LocalStorage.java b/src/main/java/BsK/client/LocalStorage.java index 014eb84..f0c8420 100644 --- a/src/main/java/BsK/client/LocalStorage.java +++ b/src/main/java/BsK/client/LocalStorage.java @@ -22,8 +22,11 @@ public class LocalStorage { public static String ClinicName = "Phòng khám BSK"; public static String ClinicAddress = "Số ABC, Đường XYZ, Quận 1, TP.HCM"; public static String ClinicPhone = "0123456789"; + public static String ClinicPrefix = "BSK"; + public static List chatHistory = new ArrayList<>(); - + public static String pathToProject = ""; + public static String dataDialogSearchTerm = ""; public static Date dataDialogFromDate = new Date(); // Default to today public static Date dataDialogToDate = new Date(); // Default to today diff --git a/src/main/java/BsK/client/network/handler/ClientHandler.java b/src/main/java/BsK/client/network/handler/ClientHandler.java index dcce267..d6c9c3b 100644 --- a/src/main/java/BsK/client/network/handler/ClientHandler.java +++ b/src/main/java/BsK/client/network/handler/ClientHandler.java @@ -66,6 +66,7 @@ public class ClientHandler extends SimpleChannelInboundHandler generatePdfBytesAsync() { return CompletableFuture.supplyAsync(() -> { @@ -62,105 +62,9 @@ public class MedicineInvoice{ }); } - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - JFrame frame = new JFrame("Medicine Invoice Test"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(600, 400); - frame.setLayout(new GridLayout(3, 2, 10, 10)); - - // Test Case 1: Only Medicines - JButton medicineOnlyButton = new JButton("Only Medicines"); - medicineOnlyButton.addActionListener(e -> new MedicineInvoice("1001", "Nguyễn Văn A", "01/01/1990", "0123456789", - "Nam", "123 Đường ABC, Quận XYZ, TP HCM", "Bác sĩ XYZ", "Sốt cao", - "Nghỉ ngơi nhiều, uống nhiều nước", "https://example.com/drive1", - new String[][]{ - {"1", "Paracetamol", "2 viên", "viên", "1", "2", "1", "5000", "10000", "Uống sau ăn"} - }, - new String[][]{}, // No services - new String[][]{} // No supplements - ).createDialog(frame)); - - // Test Case 2: Only Services - JButton serviceOnlyButton = new JButton("Only Services"); - serviceOnlyButton.addActionListener(e -> new MedicineInvoice("1002", "Trần Thị B", "15/05/1985", "0987654321", - "Nữ", "456 Đường DEF, Quận ABC, TP HCM", "Bác sĩ ABC", "Khám tổng quát", - "Theo dõi định kỳ", "https://example.com/drive2", - new String[][]{}, // No medicines - new String[][] { - {"1", "Khám tổng quát", "1", "150000", "150000", "Kiểm tra sức khỏe tổng quát"}, - {"2", "Xét nghiệm máu", "1", "80000", "80000", "Xét nghiệm công thức máu"} - }, - new String[][]{} // No supplements - ).createDialog(frame)); - - // Test Case 3: Only Supplements - JButton supplementOnlyButton = new JButton("Only Supplements"); - supplementOnlyButton.addActionListener(e -> new MedicineInvoice("1003", "Lê Văn C", "20/12/1992", "0456789123", - "Nam", "789 Đường GHI, Quận DEF, TP HCM", "Bác sĩ DEF", "Tư vấn dinh dưỡng", - "Bổ sung vitamin và khoáng chất", "https://example.com/drive3", - new String[][]{}, // No medicines - new String[][]{}, // No services - new String[][] { - {"1", "Vitamin D3", "1", "viên", "1 viên/ngày sau ăn sáng", "30 viên", "2000", "60000", "Bổ sung vitamin D"}, - {"2", "Omega 3", "2", "viên", "2 viên/ngày sau ăn", "60 viên", "1500", "90000", "Bổ sung dầu cá"} - } - ).createDialog(frame)); - - // Test Case 4: Medicines + Services (No Supplements) - JButton medServiceButton = new JButton("Medicines + Services"); - medServiceButton.addActionListener(e -> new MedicineInvoice("1004", "Phạm Thị D", "10/03/1988", "0789123456", - "Nữ", "321 Đường JKL, Quận GHI, TP HCM", "Bác sĩ GHI", "Viêm họng", - "Điều trị kháng sinh và theo dõi", "https://example.com/drive4", - new String[][]{ - {"1", "Amoxicillin", "1 vỉ", "viên", "1", "1", "0", "20000", "20000", "Uống trước ăn 30 phút"} - }, - new String[][] { - {"1", "Khám tai mũi họng", "1", "100000", "100000", "Khám chuyên khoa"} - }, - new String[][]{} // No supplements - ).createDialog(frame)); - - // Test Case 5: All Three Categories - JButton allCategoriesButton = new JButton("All Categories"); - allCategoriesButton.addActionListener(e -> new MedicineInvoice("1005", "Hoàng Văn E", "25/07/1990", "0654321987", - "Nam", "654 Đường MNO, Quận JKL, TP HCM", "Bác sĩ JKL", "Kiểm tra sức khỏe định kỳ", - "Tổng quát + bổ sung dinh dưỡng", "https://example.com/drive5", - new String[][]{ - {"1", "Vitamin C", "1 hộp", "viên", "1", "0", "0", "10000", "10000", "Uống buổi sáng"} - }, - new String[][] { - {"1", "Khám tổng quát", "1", "150000", "150000", "Kiểm tra sức khỏe tổng quát"} - }, - new String[][] { - {"1", "Calcium 500mg", "1 lọ", "viên", "1 viên/ngày sau ăn tối", "30 viên", "2500", "75000", "Bổ sung canxi"} - } - ).createDialog(frame)); - - // Test Case 6: Empty Invoice (No data) - JButton emptyButton = new JButton("Empty Invoice"); - emptyButton.addActionListener(e -> new MedicineInvoice("1006", "Võ Thị F", "05/11/1995", "0321654987", - "Nữ", "987 Đường PQR, Quận MNO, TP HCM", "Bác sĩ MNO", "Tư vấn y tế", - "Chỉ tư vấn, không kê đơn", null, - new String[][]{}, // No medicines - new String[][]{}, // No services - new String[][]{} // No supplements - ).createDialog(frame)); - - frame.add(medicineOnlyButton); - frame.add(serviceOnlyButton); - frame.add(supplementOnlyButton); - frame.add(medServiceButton); - frame.add(allCategoriesButton); - frame.add(emptyButton); - - frame.setVisible(true); - }); - } - public MedicineInvoice(String id, String patientName, String patientDOB, String patientPhone, - String patientGender, String patientAddress, String doctorName, String diagnosis, - String notes, String driveURL, String[][] med, String[][] services, String[][] supplements) { + String patientGender, String patientAddress, String doctorName, String diagnosis, + String notes, String driveURL, String[][] med, String[][] services, String[][] supplements) { this.id = id; this.patientName = patientName; this.patientDOB = patientDOB; @@ -185,13 +89,15 @@ public class MedicineInvoice{ } + private JasperPrint jasperPrint; // Store JasperPrint for reuse + /** * Shows the invoice directly in JasperViewer without creating a custom dialog */ public void showDirectJasperViewer() { try { - String pdfPath = "medical_invoice.pdf"; - generatePdf(pdfPath); + // This method now only fills the report and shows the viewer + fillJasperPrint(); // Use the constructor to prevent the application from closing JasperViewer viewer = new JasperViewer(jasperPrint, false); viewer.setVisible(true); @@ -241,7 +147,7 @@ public class MedicineInvoice{ dialog.add(scrollPane, BorderLayout.CENTER); dialog.add(buttonPanel, BorderLayout.SOUTH); - String pdfPath = "medical_invoice.pdf"; + String pdfPath = "temp_medical_invoice.pdf"; // Use a temporary file name try { generatePdf(pdfPath); displayPdfInLabel(pdfPath, pdfViewer); @@ -255,21 +161,20 @@ public class MedicineInvoice{ try { JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle("Save PDF As"); - fileChooser.setSelectedFile(new File("medical_invoice.pdf")); + // Suggest a file name based on patient name and date + fileChooser.setSelectedFile(new File(patientName.replace(" ", "_") + "_invoice_" + date.replace("/", "-") + ".pdf")); int userSelection = fileChooser.showSaveDialog(dialog); if (userSelection == JFileChooser.APPROVE_OPTION) { File fileToSave = fileChooser.getSelectedFile(); - File generatedFile = new File(pdfPath); - try (InputStream in = new FileInputStream(generatedFile); - OutputStream out = new FileOutputStream(fileToSave)) { - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) { - out.write(buffer, 0, bytesRead); - } - JOptionPane.showMessageDialog(dialog, "PDF saved: " + fileToSave.getAbsolutePath()); + // Ensure the file has a .pdf extension + if (!fileToSave.getName().toLowerCase().endsWith(".pdf")) { + fileToSave = new File(fileToSave.getAbsolutePath() + ".pdf"); } + + // Export the already generated JasperPrint object to the chosen file + JasperExportManager.exportReportToPdfFile(jasperPrint, fileToSave.getAbsolutePath()); + JOptionPane.showMessageDialog(dialog, "PDF saved: " + fileToSave.getAbsolutePath()); } } catch (Exception ex) { ex.printStackTrace(); @@ -300,8 +205,6 @@ public class MedicineInvoice{ dialog.setVisible(true); } - private JasperPrint jasperPrint; // Store JasperPrint for reuse - private byte[] generatePdfBytes() throws Exception { try { // This method is almost identical to generatePdf, but exports to a byte array @@ -329,181 +232,129 @@ public class MedicineInvoice{ * Common method to fill the JasperPrint object with data and parameters. * This avoids code duplication between generating a file and a byte array. */ - private void fillJasperPrint() throws JRException, FileNotFoundException { - // Only fill if it hasn't been filled already + private void fillJasperPrint() throws JRException, IOException { if (jasperPrint != null) { return; } - // 1. Create data sources for medicines, services, and supplements - java.util.List medicines = new ArrayList<>(); - java.util.List serviceItems = new ArrayList<>(); - java.util.List supplementItems = new ArrayList<>(); - // Convert medicine data to InvoiceItem objects + java.util.List medicineItems = new ArrayList<>(); + java.util.List serviceItems = new ArrayList<>(); + java.util.List supplementItems = new ArrayList<>(); + if (med != null) { for (String[] medicine : med) { - if (medicine != null && medicine.length >= 10) { - try { - String dosageInfo = String.format("S: %s, T: %s, C: %s", - medicine[4] != null ? medicine[4] : "0", - medicine[5] != null ? medicine[5] : "0", - medicine[6] != null ? medicine[6] : "0"); - String amount = medicine[2] + " " + medicine[3]; - - medicines.add(InvoiceItem.createMedicine( - medicine[1] != null ? medicine[1] : "", // medName - dosageInfo, // dosage - amount // amount - )); - } catch (NumberFormatException e) { - System.err.println("Error parsing medicine data: " + e.getMessage()); - } + if (medicine != null && medicine.length >= 12) { + try { + String medName = medicine[1]; + String amount = medicine[2] + " " + medicine[3]; + String dosageInfo = String.format("S: %s, T: %s, C: %s", medicine[4], medicine[5], medicine[6]); + String note = medicine[9]; + String route = medicine[11]; + + // Call signature: (Tên, Ghi chú, Liều dùng, Đường dùng, Số lượng) + medicineItems.add(InvoiceItem.createMedicine(medName, note, dosageInfo, route, amount)); + } catch (Exception e) { + System.err.println("Error parsing medicine data row: " + java.util.Arrays.toString(medicine) + " | Error: " + e.getMessage()); } } } + } - // Convert service data to InvoiceItem objects - if (services != null) { + if (services != null) { for (String[] service : services) { - if (service != null && service.length >= 5) { - try { - serviceItems.add(InvoiceItem.createService( - service[1] != null ? service[1] : "", // serName - service.length > 5 && service[5] != null ? service[5] : "", // serNote - service[2] != null ? Integer.parseInt(service[2]) : 0, // serAmount - service[3] != null ? Double.parseDouble(service[3]) : 0.0 // serUnitPrice - )); - } catch (NumberFormatException e) { - System.err.println("Error parsing service data: " + e.getMessage()); - } + if (service != null && service.length >= 5) { + try { + serviceItems.add(InvoiceItem.createService( + service[1], + service.length > 5 ? service[5] : "", + Integer.parseInt(service[2]), + Double.parseDouble(service[3]) + )); + } catch (NumberFormatException e) { + System.err.println("Error parsing service data: " + e.getMessage()); } } } + } - // Convert supplement data to InvoiceItem objects - if (supplements != null) { - for (String[] supplement : supplements) { - if (supplement != null && supplement.length >= 10) { - try { - String dosageInfo = String.format("S: %s, T: %s, C: %s", - supplement[4] != null ? supplement[4] : "0", - supplement[5] != null ? supplement[5] : "0", - supplement[6] != null ? supplement[6] : "0"); - - String amount = supplement[2] + " " + supplement[3]; // Quantity + Unit - - supplementItems.add(InvoiceItem.createSupplement( - supplement[1] != null ? supplement[1] : "", // supName - supplement[9] != null ? supplement[9] : "", // supNote - dosageInfo, // supDosage - amount, // supAmount - 0.0 // supUnitPrice, since it's not displayed for supplements - )); - } catch (Exception e) { - System.err.println("Error parsing supplement data: " + e.getMessage()); - } + if (supplements != null) { + for (String[] supplement : supplements) { + if (supplement != null && supplement.length >= 12) { + try { + String supName = supplement[1]; + String amount = supplement[2] + " " + supplement[3]; + String dosageInfo = String.format("S: %s, T: %s, C: %s", supplement[4], supplement[5], supplement[6]); + String supNote = supplement[9]; + String supRoute = supplement[11]; + + // --- CORRECTED THIS LINE --- + // Swapped 'amount' and 'supRoute' to match the method signature in InvoiceItem.java + // Call signature: (Tên, Ghi chú, Liều dùng, Số lượng, Đường dùng) + supplementItems.add(InvoiceItem.createSupplement(supName, supNote, dosageInfo, amount, supRoute)); + + } catch (Exception e) { + System.err.println("Error parsing supplement data row: " + java.util.Arrays.toString(supplement) + " | Error: " + e.getMessage()); } } } + } - // Create data sources - JRBeanCollectionDataSource medicineDS = new JRBeanCollectionDataSource(medicines); - JRBeanCollectionDataSource serviceDS = new JRBeanCollectionDataSource(serviceItems); - JRBeanCollectionDataSource supplementDS = new JRBeanCollectionDataSource(supplementItems); + JRBeanCollectionDataSource medicineDS = new JRBeanCollectionDataSource(medicineItems); + JRBeanCollectionDataSource serviceDS = new JRBeanCollectionDataSource(serviceItems); + JRBeanCollectionDataSource supplementDS = new JRBeanCollectionDataSource(supplementItems); - // 2. Create parameters map - java.util.Map parameters = new java.util.HashMap<>(); - - // Data sources - parameters.put("medicineDS", medicineDS); - parameters.put("serviceDS", serviceDS); - parameters.put("supplementDS", supplementDS); + java.util.Map parameters = new java.util.HashMap<>(); + + parameters.put("medicineDS", medicineDS); + parameters.put("serviceDS", serviceDS); + parameters.put("supplementDS", supplementDS); + parameters.put(JRParameter.REPORT_LOCALE, new java.util.Locale("vi", "VN")); + parameters.put("patientName", patientName != null ? patientName : ""); + parameters.put("patientDOB", patientDOB != null ? patientDOB : ""); + parameters.put("patientGender", patientGender != null ? patientGender : ""); + parameters.put("patientAddress", patientAddress != null ? patientAddress : ""); + parameters.put("clinicPrefix", LocalStorage.ClinicPrefix != null ? LocalStorage.ClinicPrefix : ""); + parameters.put("clinicName", LocalStorage.ClinicName != null ? LocalStorage.ClinicName : ""); + parameters.put("clinicPhone", LocalStorage.ClinicPhone != null ? LocalStorage.ClinicPhone : ""); + parameters.put("clinicAddress", LocalStorage.ClinicAddress != null ? LocalStorage.ClinicAddress : ""); + parameters.put("doctorName", doctorName != null ? doctorName : ""); + parameters.put("checkupDate", date != null ? date : ""); + parameters.put("patientDiagnos", diagnosis != null ? diagnosis : ""); + parameters.put("checkupNote", notes != null ? notes : ""); + parameters.put("barcodeNumber", id != null ? id : ""); + parameters.put("driveURL", driveURL != null ? driveURL : ""); + parameters.put("logoImage", LocalStorage.pathToProject + "/src/main/java/BsK/client/ui/assets/icon/logo.jpg"); + parameters.put("hasMedicines", !medicineItems.isEmpty()); + parameters.put("hasServices", !serviceItems.isEmpty()); + parameters.put("hasSupplements", !supplementItems.isEmpty()); - // Set locale for Vietnamese formatting - parameters.put(JRParameter.REPORT_LOCALE, new java.util.Locale("vi", "VN")); - - // Patient information - parameters.put("patientName", patientName != null ? patientName : ""); - parameters.put("patientDOB", patientDOB != null ? patientDOB : ""); - parameters.put("patientGender", patientGender != null ? patientGender : ""); - parameters.put("patientAddress", patientAddress != null ? patientAddress : ""); - - // Clinic information - parameters.put("clinicName", LocalStorage.ClinicName != null ? LocalStorage.ClinicName : ""); - parameters.put("clinicPhone", LocalStorage.ClinicPhone != null ? LocalStorage.ClinicPhone : ""); - parameters.put("clinicAddress", LocalStorage.ClinicAddress != null ? LocalStorage.ClinicAddress : ""); - - // Doctor and medical information - parameters.put("doctorName", doctorName != null ? doctorName : ""); - parameters.put("checkupDate", date != null ? date : ""); - parameters.put("patientDiagnos", diagnosis != null ? diagnosis : ""); - parameters.put("checkupNote", notes != null ? notes : ""); - - // Barcode - parameters.put("barcodeNumber", id != null ? id : ""); - - // Drive URL for QR Code - parameters.put("driveURL", driveURL != null ? driveURL : ""); - - // Logo image path - String logoPath = System.getProperty("user.dir") + "/src/main/java/BsK/client/ui/assets/icon/logo.jpg"; - parameters.put("logoImage", logoPath); - - // Add conditional parameters to check if data sources have data - parameters.put("hasMedicines", medicines != null && !medicines.isEmpty()); - parameters.put("hasServices", serviceItems != null && !serviceItems.isEmpty()); - parameters.put("hasSupplements", supplementItems != null && !supplementItems.isEmpty()); - - // 3. Load and compile the JRXML template - String jrxmlPath = System.getProperty("user.dir") + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/medserinvoice.jrxml"; - java.io.InputStream inputStream = new java.io.FileInputStream(new java.io.File(jrxmlPath)); + String resourcePath = "/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/medserinvoice.jrxml"; + try (InputStream inputStream = MedicineInvoice.class.getResourceAsStream(resourcePath)) { + if (inputStream == null) { + throw new FileNotFoundException("Không thể tìm thấy tệp mẫu Jasper report trong classpath: " + resourcePath); + } JasperDesign jasperDesign = JRXmlLoader.load(inputStream); JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign); - - // 4. Fill the report with data jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource()); + } } private void displayPdfInLabel(String pdfPath, JPanel pdfPanel) throws Exception { PDDocument document = PDDocument.load(new File(pdfPath)); PDFRenderer pdfRenderer = new PDFRenderer(document); - // Create a panel to hold all pages - pdfPanel.setLayout(new BoxLayout(pdfPanel, BoxLayout.Y_AXIS)); // Stack pages vertically + pdfPanel.setLayout(new BoxLayout(pdfPanel, BoxLayout.Y_AXIS)); - // Render each page and add it to the pdfPanel for (int i = 0; i < document.getNumberOfPages(); i++) { - BufferedImage image = pdfRenderer.renderImageWithDPI(i, 150); // Adjust DPI as needed - - // Scale the image to a smaller size (e.g., 50% of the original size) - int scaledWidth = image.getWidth() / 2; // Make it half of the original width - int scaledHeight = image.getHeight() / 2; // Make it half of the original height - - // Scale the image using getScaledInstance - java.awt.Image scaledImage = image.getScaledInstance(scaledWidth, scaledHeight, java.awt.Image.SCALE_SMOOTH); - - // Create an ImageIcon from the scaled image - ImageIcon icon = new ImageIcon(scaledImage); - - // Create a label for the image and add it to the panel + BufferedImage image = pdfRenderer.renderImageWithDPI(i, 150); + ImageIcon icon = new ImageIcon(image); JLabel pageLabel = new JLabel(icon); pdfPanel.add(pageLabel); } document.close(); - // Put the panel inside a JScrollPane to make it scrollable - JScrollPane scrollPane = new JScrollPane(pdfPanel); - scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); // Added for horizontal scroll if needed - - // Increase scroll sensitivity - JScrollBar verticalScrollBar = scrollPane.getVerticalScrollBar(); - verticalScrollBar.setUnitIncrement(20); // Increase for finer control, adjust as needed - verticalScrollBar.setBlockIncrement(100); // Increase for page-like scrolling, adjust as needed - - // Assuming `dialog` is the parent component - dialog.add(scrollPane, BorderLayout.CENTER); - dialog.validate(); + + dialog.revalidate(); dialog.repaint(); } @@ -514,39 +365,31 @@ public class MedicineInvoice{ printerJob.setJobName("Print Medicine Invoice"); if (printerJob.printDialog()) { - printerJob.setPrintable(new Printable() { - @Override - public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { - if (pageIndex >= document.getNumberOfPages()) { - return NO_SUCH_PAGE; - } - - Graphics2D g2 = (Graphics2D) graphics; - g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); - - try { - PDFRenderer pdfRenderer = new PDFRenderer(document); - BufferedImage pageImage = pdfRenderer.renderImageWithDPI(pageIndex, 300); // Render at 300 DPI - - double pageWidth = pageImage.getWidth(); - double pageHeight = pageImage.getHeight(); - - double scaleX = pageFormat.getImageableWidth() / pageWidth; - double scaleY = pageFormat.getImageableHeight() / pageHeight; - double scale = Math.min(scaleX, scaleY); - - g2.scale(scale, scale); - g2.drawImage(pageImage, 0, 0, null); - - } catch (IOException e) { - e.printStackTrace(); - return NO_SUCH_PAGE; - } - - return PAGE_EXISTS; + printerJob.setPrintable((graphics, pageFormat, pageIndex) -> { + if (pageIndex >= document.getNumberOfPages()) { + return Printable.NO_SUCH_PAGE; } - }); + Graphics2D g2 = (Graphics2D) graphics; + g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); + + try { + PDFRenderer pdfRenderer = new PDFRenderer(document); + BufferedImage pageImage = pdfRenderer.renderImageWithDPI(pageIndex, 300); + + double scale = Math.min(pageFormat.getImageableWidth() / pageImage.getWidth(), + pageFormat.getImageableHeight() / pageImage.getHeight()); + + g2.scale(scale, scale); + g2.drawImage(pageImage, 0, 0, null); + + } catch (IOException e) { + e.printStackTrace(); + return Printable.NO_SUCH_PAGE; + } + + return Printable.PAGE_EXISTS; + }); printerJob.print(); System.out.println("Printing completed."); @@ -559,4 +402,4 @@ public class MedicineInvoice{ } } -} +} \ No newline at end of file diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java index 59a263d..d29d4c2 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java @@ -173,9 +173,9 @@ public class UltrasoundResult { public JasperPrint createJasperPrint() throws JRException, IOException { String jrxmlPath; if ("Dọc".equalsIgnoreCase(this.printType)) { - jrxmlPath = System.getProperty("user.dir") + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult_potrait.jrxml"; + jrxmlPath = LocalStorage.pathToProject + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult_potrait.jrxml"; } else { - jrxmlPath = System.getProperty("user.dir") + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml"; + jrxmlPath =LocalStorage.pathToProject + "/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml"; } log.info("Using JRXML template: {}", jrxmlPath); @@ -187,6 +187,7 @@ public class UltrasoundResult { parameters.put(JRParameter.REPORT_LOCALE, new Locale("vi", "VN")); // Populate all the string parameters + parameters.put("clinicPrefix", LocalStorage.ClinicPrefix != null ? LocalStorage.ClinicPrefix : ""); parameters.put("clinicName", convertNullToEmpty(LocalStorage.ClinicName, "Phòng khám BSK")); parameters.put("clinicAddress", convertNullToEmpty(LocalStorage.ClinicAddress, "Địa chỉ phòng khám")); parameters.put("clinicPhone", convertNullToEmpty(LocalStorage.ClinicPhone, "SĐT phòng khám")); @@ -200,16 +201,16 @@ public class UltrasoundResult { parameters.put("barcodeNumber", this.checkupId); // RTF and plain text content - parameters.put("checkupNote", this.rtfContent); - parameters.put("checkupConclusion", this.conclusion); - parameters.put("checkupSuggestion", this.suggestion); - parameters.put("reCheckupDate", this.recheckupDate); + parameters.put("checkupNote", this.rtfContent != null ? this.rtfContent : ""); + parameters.put("checkupConclusion", this.conclusion != null ? this.conclusion : ""); + parameters.put("checkupSuggestion", this.suggestion != null ? this.suggestion : ""); + parameters.put("reCheckupDate", this.recheckupDate != null ? this.recheckupDate : ""); // Vitals data - parameters.put("checkupHeight", this.customerHeight); - parameters.put("checkupWeight", this.customerWeight); - parameters.put("checkupHeartBeat", this.heartRate); - parameters.put("checkupBloodPressure", this.bloodPressure); + parameters.put("checkupHeight", this.customerHeight != null ? this.customerHeight : ""); + parameters.put("checkupWeight", this.customerWeight != null ? this.customerWeight : ""); + parameters.put("checkupHeartBeat", this.heartRate != null ? this.heartRate : ""); + parameters.put("checkupBloodPressure", this.bloodPressure != null ? this.bloodPressure : ""); // Template title parameters.put("templateTitle", this.templateTitle); @@ -226,7 +227,7 @@ public class UltrasoundResult { int numberOfImages = this.selectedImages.size(); parameters.put("numberImage", numberOfImages); - String projectDir = System.getProperty("user.dir"); + String projectDir = LocalStorage.pathToProject; parameters.put("logoImage", projectDir + "/src/main/java/BsK/client/ui/assets/icon/logo.jpg"); for (int i = 0; i < 6; i++) { @@ -362,7 +363,7 @@ public class UltrasoundResult { } Paragraph clinicInfo = new Paragraph() - .add(new Text(LocalStorage.ClinicName + "\n").setFont(boldFont).setFontSize(10)) + .add(new Text(LocalStorage.ClinicPrefix + " " + LocalStorage.ClinicName + "\n").setFont(boldFont).setFontSize(10)) .add(new Text("Địa chỉ: " + LocalStorage.ClinicAddress + "\n").setFontSize(8)) .add(new Text("Điện thoại: " + LocalStorage.ClinicPhone).setFontSize(8)) .setFont(font); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/InvoiceItem.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/InvoiceItem.java index bdc973b..7779fd8 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/InvoiceItem.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/InvoiceItem.java @@ -13,6 +13,7 @@ public class InvoiceItem { private String dosage; private String amount; private Double unitPrice; + private String medRoute; private String medNote; // --- Service Fields --- @@ -26,21 +27,21 @@ public class InvoiceItem { private String supNote; private String supDosage; private String supAmount; - private Double supUnitPrice; - + private String supRoute; // Private constructor to be used by factory methods private InvoiceItem() {} // --- Factory Methods --- - public static InvoiceItem createMedicine(String medName, String dosage, String amount) { + public static InvoiceItem createMedicine(String medName, String medNote, String dosage, String route, String amount) { InvoiceItem item = new InvoiceItem(); item.type = "MED"; item.medName = medName; item.dosage = dosage; + item.medRoute = route; item.amount = amount; item.unitPrice = 0.0; - item.medNote = ""; + item.medNote = medNote; return item; } @@ -54,14 +55,14 @@ public class InvoiceItem { return item; } - public static InvoiceItem createSupplement(String supName, String supNote, String supDosage, String supAmount, Double supUnitPrice) { + public static InvoiceItem createSupplement(String supName, String supNote, String supDosage, String supAmount, String supRoute) { InvoiceItem item = new InvoiceItem(); item.type = "SUP"; item.supName = supName; item.supNote = supNote; item.supDosage = supDosage; item.supAmount = supAmount; - item.supUnitPrice = supUnitPrice; + item.supRoute = supRoute; return item; } @@ -71,6 +72,7 @@ public class InvoiceItem { public String getType() { return type; } public String getMedName() { return medName; } public String getDosage() { return dosage; } + public String getMedRoute() { return medRoute; } public String getAmount() { return amount; } public Double getUnitPrice() { return unitPrice; } public String getMedNote() { return medNote; } @@ -82,5 +84,5 @@ public class InvoiceItem { public String getSupNote() { return supNote; } public String getSupDosage() { return supDosage; } public String getSupAmount() { return supAmount; } - public Double getSupUnitPrice() { return supUnitPrice; } + public String getSupRoute() { return supRoute; } } \ No newline at end of file diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/medserinvoice.jrxml b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/medserinvoice.jrxml index 48a416b..09e4932 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/medserinvoice.jrxml +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/medserinvoice.jrxml @@ -27,7 +27,8 @@ - + + @@ -68,6 +69,7 @@ + @@ -86,12 +88,12 @@ - + - + - + @@ -110,7 +112,7 @@ - + @@ -119,7 +121,7 @@ - + @@ -138,6 +140,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -173,7 +195,7 @@ - + @@ -188,17 +210,17 @@ - - + + - - - + + + - + - - + + @@ -216,7 +238,7 @@ - + @@ -225,7 +247,7 @@ - + @@ -244,9 +266,29 @@ - + + + + + + + + + + + + + + + + + + + + + - + @@ -263,7 +305,7 @@ - + @@ -279,7 +321,7 @@ - + @@ -292,13 +334,13 @@ - + - + - + @@ -329,8 +371,8 @@ - - + + @@ -339,7 +381,7 @@ - + @@ -383,8 +425,8 @@ - - + + @@ -434,8 +476,8 @@ - - + + @@ -473,7 +515,7 @@ - + @@ -489,8 +531,8 @@ - - + + @@ -521,84 +563,88 @@ - + <title height="96" splitType="Stretch"> <element kind="image" uuid="c596ac6f-18d9-4cfe-a74e-58b1f7d11ecc" x="-10" y="-4" width="90" height="83"> <expression><![CDATA[$P{logoImage}]]></expression> </element> - <element kind="textField" uuid="48bf4793-8d8d-427d-b739-8f34f051192f" x="80" y="-4" width="350" height="25" fontName="Times New Roman" fontSize="18.0" bold="true"> - <expression><![CDATA[$P{clinicName}]]></expression> + <element kind="textField" uuid="48bf4793-8d8d-427d-b739-8f34f051192f" x="80" y="-4" width="359" height="25" forecolor="#FF0905" fontName="Times New Roman" fontSize="18.0" bold="true" hTextAlign="Center"> + <expression><![CDATA[$P{clinicPrefix}]]></expression> </element> - <element kind="staticText" uuid="d8e95ce7-3ac0-44a7-ac8f-65821b7f373c" x="80" y="20" width="150" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="d8e95ce7-3ac0-44a7-ac8f-65821b7f373c" x="80" y="47" width="150" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Địa chỉ: ]]></text> </element> - <element kind="textField" uuid="9883203e-fd4b-4110-a4b9-2c8c257ce5fa" x="126" y="20" width="314" height="15" fontName="Times New Roman" fontSize="12.0"> + <element kind="textField" uuid="9883203e-fd4b-4110-a4b9-2c8c257ce5fa" x="126" y="47" width="314" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{clinicAddress}]]></expression> </element> - <element kind="staticText" uuid="f00706ca-903c-4089-b3a1-33be68f6112b" x="80" y="36" width="150" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="f00706ca-903c-4089-b3a1-33be68f6112b" x="80" y="62" width="150" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[SĐT:]]></text> </element> - <element kind="textField" uuid="2af00e22-702e-42cb-a6fb-19d401a58170" x="110" y="36" width="330" height="15" fontName="Times New Roman" fontSize="12.0"> + <element kind="textField" uuid="2af00e22-702e-42cb-a6fb-19d401a58170" x="110" y="62" width="330" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{clinicPhone}]]></expression> </element> - <element kind="component" uuid="35037abf-0984-4b9e-8a05-f8fae38d7dcc" x="440" y="8" width="65" height="43"> + <element kind="component" uuid="35037abf-0984-4b9e-8a05-f8fae38d7dcc" x="490" y="0" width="65" height="43"> <component kind="barcode4j:Code128"> <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> </component> </element> - <element kind="staticText" uuid="de38fb46-49af-4f48-8c33-f97680bcc7fa" x="135" y="52" width="284" height="25" fontName="Times New Roman" fontSize="18.0" bold="true" hTextAlign="Center"> + <element kind="staticText" uuid="de38fb46-49af-4f48-8c33-f97680bcc7fa" x="135" y="71" width="284" height="21" fontName="Times New Roman" fontSize="18.0" bold="true" hTextAlign="Center"> <text><![CDATA[TOA THUỐC & DỊCH VỤ]]></text> + <property name="com.jaspersoft.studio.unit.height" value="pixel"/> </element> - <element kind="component" uuid="b8dc3582-162b-47d9-9501-fbf3bfc63fbd" x="505" y="3" width="50" height="43"> + <element kind="component" uuid="b8dc3582-162b-47d9-9501-fbf3bfc63fbd" x="440" y="0" width="46" height="39"> <component kind="barcode4j:QRCode"> <codeExpression><![CDATA[$P{driveURL}]]></codeExpression> </component> </element> - <element kind="staticText" uuid="53b28743-6b3c-4700-b84d-a96a93371dbf" x="500" y="46" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> + <element kind="staticText" uuid="53b28743-6b3c-4700-b84d-a96a93371dbf" x="434" y="43" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> <printWhenExpression><![CDATA[$P{driveURL} != null && !$P{driveURL}.trim().isEmpty()]]></printWhenExpression> <text><![CDATA[Xem KQ online]]></text> </element> + <element kind="textField" uuid="9dcab6b1-a9ce-4aa9-9df9-232869b3ab24" x="80" y="21" width="359" height="25" forecolor="#FF0905" fontName="Times New Roman" fontSize="18.0" bold="true" hTextAlign="Center"> + <expression><![CDATA[$P{clinicName}]]></expression> + </element> - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml index b581bb4..2cc8225 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml @@ -38,24 +38,25 @@ + <pageHeader splitType="Stretch"/> <columnHeader splitType="Stretch"/> <detail> - <band height="540" splitType="Stretch"> - <element kind="frame" uuid="2b7ec588-953c-4145-87b7-1d861c272fe0" x="0" y="0" width="400" height="539"> + <band height="538" splitType="Stretch"> + <element kind="frame" uuid="2b7ec588-953c-4145-87b7-1d861c272fe0" x="0" y="0" width="399" height="538"> <element kind="image" uuid="fd80ab38-4cae-409b-84b9-356220d2b1e5" x="0" y="1" width="60" height="60"> <expression><![CDATA[$P{logoImage}]]></expression> </element> - <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="60" y="0" width="290" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <expression><![CDATA[$P{clinicName}]]></expression> + <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="60" y="0" width="260" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> + <expression><![CDATA[$P{clinicPrefix}]]></expression> </element> - <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="60" y="20" width="235" height="25" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="63" y="30" width="229" height="20" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{clinicAddress}]]></expression> </element> - <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="60" y="45" width="162" height="12" fontName="Times New Roman" fontSize="8.0"> + <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="63" y="42" width="162" height="12" fontName="Times New Roman" fontSize="8.0"> <expression><![CDATA["SDT: " + $P{clinicPhone}]]></expression> </element> <element kind="staticText" uuid="6f89a93f-2d10-4506-baa5-226bdd047b17" x="0" y="65" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> @@ -88,28 +89,28 @@ <element kind="textField" uuid="f4df20b4-920c-491e-882b-6e0733cb4866" x="184" y="94" width="36" height="15" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{patientGender}]]></expression> </element> - <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="39" y="109" width="361" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="39" y="109" width="359" height="15" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{patientAddress}]]></expression> </element> - <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="290" y="80" width="110" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="290" y="80" width="108" height="15" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{doctorName}]]></expression> </element> - <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="276" y="94" width="124" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="276" y="94" width="122" height="15" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupDate}]]></expression> </element> <element kind="staticText" uuid="9f7de81c-4c38-41a2-9fea-a165eff19431" x="1" y="124" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> <text><![CDATA[Chuẩn đoán:]]></text> </element> - <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="60" y="124" width="340" height="26" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="60" y="124" width="338" height="26" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{patientDiagnos}]]></expression> </element> <element kind="staticText" uuid="b1fa845a-48da-4e45-82b8-8b9d972650f6" x="0" y="162" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> <text><![CDATA[II.Nội dung]]></text> </element> - <element kind="textField" uuid="6d652a25-b701-45bd-91ba-750842650004" x="0" y="177" width="398" height="362" markup="rtf" fontName="Times New Roman" fontSize="14.0"> + <element kind="textField" uuid="6d652a25-b701-45bd-91ba-750842650004" x="0" y="177" width="398" height="360" markup="rtf" fontName="Times New Roman" fontSize="16.0"> <expression><![CDATA[$P{checkupNote}]]></expression> </element> - <element kind="staticText" uuid="8f720f6a-0257-4556-b3bc-3b81ad4f8099" x="1" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="8f720f6a-0257-4556-b3bc-3b81ad4f8099" x="290" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> <text><![CDATA[Chiều cao:]]></text> </element> <element kind="staticText" uuid="a57e7a9d-4ac7-4219-b268-cd08ce943327" x="100" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> @@ -118,10 +119,10 @@ <element kind="staticText" uuid="2b9cfd9d-ec8f-4036-9c96-039fd7855e24" x="200" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> <text><![CDATA[Nhịp tim:]]></text> </element> - <element kind="staticText" uuid="c1356370-11ce-4b68-97d6-ce6e18e306c5" x="290" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="c1356370-11ce-4b68-97d6-ce6e18e306c5" x="0" y="150" width="51" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> <text><![CDATA[Huyết áp:]]></text> </element> - <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="50" y="150" width="50" height="16" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="340" y="150" width="58" height="16" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupWeight} +" cm"]]></expression> </element> <element kind="textField" uuid="fb080012-3196-4535-bcd2-e87274c66fa5" x="147" y="150" width="53" height="16" fontName="Times New Roman" fontSize="10.0"> @@ -130,20 +131,23 @@ <element kind="textField" uuid="e4185ffe-8712-41e3-a9ff-2be6569dff15" x="243" y="150" width="47" height="16" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupHeartBeat} + " l/p"]]></expression> </element> - <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="335" y="150" width="63" height="16" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="45" y="150" width="55" height="16" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupBloodPressure} +" mmHg"]]></expression> </element> - <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="362" y="19" width="38" height="35"> + <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="354" y="1" width="44" height="37"> <component kind="barcode4j:QRCode"> <codeExpression><![CDATA[$P{driveURL}]]></codeExpression> </component> </element> - <element kind="textField" uuid="9763a634-05c2-4f64-a903-c914455b7ee6" x="70" y="57" width="282" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> + <element kind="textField" uuid="9763a634-05c2-4f64-a903-c914455b7ee6" x="70" y="60" width="282" height="22" forecolor="#FF0905" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> <printWhenExpression><![CDATA[$P{templateTitle} != null && !$P{templateTitle}.trim().isEmpty()]]></printWhenExpression> <expression><![CDATA["PHIẾU " + $P{templateTitle}]]></expression> </element> + <element kind="textField" uuid="40902efd-728a-46df-8432-f4a5798a4ee3" x="60" y="13" width="260" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> + <expression><![CDATA[$P{clinicName}]]></expression> + </element> </element> - <element kind="frame" uuid="a72ffc70-007e-43af-a566-b34e6e07b312" x="400" y="0" width="400" height="540"> + <element kind="frame" uuid="a72ffc70-007e-43af-a566-b34e6e07b312" x="400" y="0" width="400" height="538"> <element kind="staticText" uuid="246a04b0-2565-4987-b7f3-dd369703035c" x="0" y="340" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> <text><![CDATA[III.Kết luận]]></text> </element> @@ -153,19 +157,19 @@ <element kind="staticText" uuid="a38b1187-ddb8-4410-9b52-dc041f894b7b" x="250" y="440" width="96" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> <text><![CDATA[Bác sĩ siêu âm]]></text> </element> - <element kind="textField" uuid="b548d99d-bedf-4e90-b13b-bdbc763aa974" x="200" y="513" width="200" height="21" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> + <element kind="textField" uuid="b548d99d-bedf-4e90-b13b-bdbc763aa974" x="199" y="512" width="200" height="21" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> <expression><![CDATA[$P{ultrasoundDoctorName}]]></expression> </element> - <element kind="textField" uuid="8bca58ab-0958-40fe-8e51-2a39a9d379a5" x="200" y="521" width="200" height="19" fontName="Times New Roman" pattern="MMMMM dd, yyyy" hTextAlign="Center" vTextAlign="Bottom"> + <element kind="textField" uuid="8bca58ab-0958-40fe-8e51-2a39a9d379a5" x="199" y="518" width="200" height="19" fontName="Times New Roman" pattern="MMMMM dd, yyyy" hTextAlign="Center" vTextAlign="Bottom"> <expression><![CDATA[new java.text.SimpleDateFormat("'Đức Hoà, ngày ' dd ' tháng ' MM ' năm ' yyyy", new java.util.Locale("vi", "VN")).format(new java.util.Date())]]></expression> </element> - <element kind="staticText" uuid="c062ce0e-80cb-4e67-a5d9-d85e769c6c4e" x="0" y="525" width="110" height="14" forecolor="#FF0905" fontName="Times New Roman" fontSize="10.0" bold="true"> + <element kind="staticText" uuid="c062ce0e-80cb-4e67-a5d9-d85e769c6c4e" x="0" y="523" width="110" height="14" forecolor="#FF0905" fontName="Times New Roman" fontSize="10.0" bold="true"> <text><![CDATA[Tái khám:]]></text> </element> - <element kind="textField" uuid="e90ad772-4425-482d-9e75-f2bc66b9084d" x="0" y="358" width="400" height="70" fontName="Times New Roman" fontSize="12.0"> + <element kind="textField" uuid="e90ad772-4425-482d-9e75-f2bc66b9084d" x="0" y="358" width="400" height="70" fontName="Times New Roman" fontSize="12.0" bold="true"> <expression><![CDATA[$P{checkupConclusion}]]></expression> </element> - <element kind="component" uuid="cb28d811-1328-45dc-9461-cfbb88b7eeae" x="-105" y="19" width="64" height="40"> + <element kind="component" uuid="cb28d811-1328-45dc-9461-cfbb88b7eeae" x="-105" y="30" width="59" height="32"> <component kind="barcode4j:Code128"> <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> </component> @@ -173,7 +177,7 @@ <element kind="textField" uuid="d63165c2-19e2-43ad-8a3f-004e00bffdfe" x="0" y="450" width="240" height="66" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{checkupSuggestion}]]></expression> </element> - <element kind="textField" uuid="cece8e5b-67db-4019-b52a-bf73abae535e" x="48" y="525" width="150" height="15" fontName="Times New Roman" fontSize="12.0"> + <element kind="textField" uuid="cece8e5b-67db-4019-b52a-bf73abae535e" x="48" y="522" width="150" height="15" fontName="Times New Roman" fontSize="12.0" bold="true"> <expression><![CDATA[$P{reCheckupDate}]]></expression> </element> <element kind="frame" uuid="2f301804-acfa-4b6f-9f52-236c04fd1197" x="0" y="0" width="400" height="344"> @@ -260,11 +264,17 @@ <expression><![CDATA[$P{image1}]]></expression> </element> </element> - <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="-55" y="53" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> + <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="-46" y="39" width="44" height="21" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> <printWhenExpression><![CDATA[$P{driveURL} != null && !$P{driveURL}.trim().isEmpty()]]></printWhenExpression> <text><![CDATA[Xem KQ online]]></text> </element> </element> </band> </detail> + <pageFooter height="17"> + <element kind="textField" uuid="cd8229a4-b862-407a-88e2-807ab7c61699" x="548" y="2" width="252" height="12" fontName="Times New Roman" pattern="MMMMM dd, yyyy" hTextAlign="Right" vTextAlign="Bottom"> + <expression><![CDATA[new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm").format(new java.util.Date()) + " | Trang " + $V{PAGE_NUMBER}]]></expression> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </element> + </pageFooter> </jasperReport> diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult_potrait.jrxml b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult_potrait.jrxml index f6082c0..b4f531b 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult_potrait.jrxml +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult_potrait.jrxml @@ -38,6 +38,7 @@ <parameter name="templateTitle" class="java.lang.String"/> <parameter name="driveURL" class="java.lang.String"/> <parameter name="ultrasoundDoctorName" class="java.lang.String"/> + <parameter name="clinicPrefix" class="java.lang.String"/> <query language="sql"><![CDATA[]]></query> <background splitType="Stretch"/> <title splitType="Stretch"/> @@ -49,58 +50,58 @@ <element kind="image" uuid="fd80ab38-4cae-409b-84b9-356220d2b1e5" x="0" y="-5" width="70" height="64"> <expression><![CDATA[$P{logoImage}]]></expression> </element> - <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="70" y="0" width="323" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <expression><![CDATA[$P{clinicName}]]></expression> + <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="70" y="-5" width="358" height="22" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> + <expression><![CDATA[$P{clinicPrefix}]]></expression> </element> - <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="70" y="20" width="323" height="22" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="70" y="29" width="358" height="20" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{clinicAddress}]]></expression> </element> - <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="70" y="42" width="276" height="15" fontName="Times New Roman" fontSize="8.0"> + <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="70" y="41" width="276" height="15" fontName="Times New Roman" fontSize="8.0"> <expression><![CDATA[$P{clinicPhone}]]></expression> </element> <element kind="staticText" uuid="6f89a93f-2d10-4506-baa5-226bdd047b17" x="0" y="65" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> <text><![CDATA[I.Thông tin]]></text> </element> - <element kind="staticText" uuid="b8dfca43-cf97-49e5-b58d-4667143dba62" x="0" y="79" width="50" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="b8dfca43-cf97-49e5-b58d-4667143dba62" x="0" y="79" width="59" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Họ và tên:]]></text> </element> - <element kind="staticText" uuid="0a9ca0c8-f2bd-4ade-a025-a6d79c13613f" x="1" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="0a9ca0c8-f2bd-4ade-a025-a6d79c13613f" x="1" y="94" width="80" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Ngày sinh:]]></text> </element> - <element kind="staticText" uuid="21917ab8-ae07-44c8-ba4e-bc6c4c54b440" x="140" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="21917ab8-ae07-44c8-ba4e-bc6c4c54b440" x="130" y="95" width="80" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Giới tính:]]></text> </element> - <element kind="staticText" uuid="bcbb614e-7a4d-48a3-83c2-198e4fb62c5f" x="1" y="109" width="49" height="15" fontName="Times New Roman" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="bcbb614e-7a4d-48a3-83c2-198e4fb62c5f" x="1" y="109" width="49" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Địa chỉ:]]></text> </element> - <element kind="staticText" uuid="45fe4be1-9e21-459b-aeee-2efc8354f372" x="221" y="80" width="68" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="45fe4be1-9e21-459b-aeee-2efc8354f372" x="221" y="80" width="89" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Bác sĩ chỉ định:]]></text> </element> - <element kind="staticText" uuid="f2ff4b17-63cc-4e8c-a3b0-2523f534f21a" x="221" y="94" width="60" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="f2ff4b17-63cc-4e8c-a3b0-2523f534f21a" x="221" y="94" width="69" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Ngày khám:]]></text> </element> - <element kind="textField" uuid="1511f53a-b282-41b1-b233-612b6106c07a" x="48" y="79" width="172" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="1511f53a-b282-41b1-b233-612b6106c07a" x="56" y="79" width="165" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{patientName}]]></expression> </element> - <element kind="textField" uuid="5bdac267-523d-4931-926b-76233ce9b84d" x="50" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="5bdac267-523d-4931-926b-76233ce9b84d" x="60" y="93" width="70" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{patientDOB}]]></expression> </element> - <element kind="textField" uuid="f4df20b4-920c-491e-882b-6e0733cb4866" x="184" y="94" width="36" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="f4df20b4-920c-491e-882b-6e0733cb4866" x="185" y="95" width="36" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{patientGender}]]></expression> </element> - <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="39" y="109" width="361" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="50" y="109" width="350" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{patientAddress}]]></expression> </element> - <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="290" y="80" width="110" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="300" y="80" width="110" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{doctorName}]]></expression> </element> - <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="276" y="94" width="124" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="290" y="94" width="110" height="15" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{checkupDate}]]></expression> </element> - <element kind="staticText" uuid="9f7de81c-4c38-41a2-9fea-a165eff19431" x="1" y="124" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="9f7de81c-4c38-41a2-9fea-a165eff19431" x="1" y="124" width="69" height="16" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Chuẩn đoán:]]></text> </element> - <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="60" y="124" width="340" height="26" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="70" y="124" width="329" height="26" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{patientDiagnos}]]></expression> </element> <element kind="staticText" uuid="b1fa845a-48da-4e45-82b8-8b9d972650f6" x="0" y="162" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> @@ -109,44 +110,44 @@ <element kind="textField" uuid="6d652a25-b701-45bd-91ba-750842650004" x="0" y="177" width="400" height="421" markup="rtf" fontName="Times New Roman" fontSize="16.0"> <expression><![CDATA[$P{checkupNote}]]></expression> </element> - <element kind="staticText" uuid="8f720f6a-0257-4556-b3bc-3b81ad4f8099" x="1" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="8f720f6a-0257-4556-b3bc-3b81ad4f8099" x="300" y="150" width="59" height="16" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Chiều cao:]]></text> </element> - <element kind="staticText" uuid="a57e7a9d-4ac7-4219-b268-cd08ce943327" x="100" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="a57e7a9d-4ac7-4219-b268-cd08ce943327" x="110" y="150" width="59" height="16" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Cân nặng:]]></text> </element> - <element kind="staticText" uuid="2b9cfd9d-ec8f-4036-9c96-039fd7855e24" x="200" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="2b9cfd9d-ec8f-4036-9c96-039fd7855e24" x="210" y="150" width="59" height="16" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Nhịp tim:]]></text> </element> - <element kind="staticText" uuid="c1356370-11ce-4b68-97d6-ce6e18e306c5" x="290" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> + <element kind="staticText" uuid="c1356370-11ce-4b68-97d6-ce6e18e306c5" x="0" y="150" width="59" height="16" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Left"> <text><![CDATA[Huyết áp:]]></text> </element> - <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="50" y="150" width="50" height="16" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="356" y="150" width="44" height="16" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{checkupWeight} +" cm"]]></expression> </element> - <element kind="textField" uuid="fb080012-3196-4535-bcd2-e87274c66fa5" x="147" y="150" width="53" height="16" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="fb080012-3196-4535-bcd2-e87274c66fa5" x="165" y="150" width="45" height="16" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{checkupWeight} + " kg"]]></expression> </element> - <element kind="textField" uuid="e4185ffe-8712-41e3-a9ff-2be6569dff15" x="243" y="150" width="47" height="16" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="e4185ffe-8712-41e3-a9ff-2be6569dff15" x="261" y="150" width="39" height="16" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{checkupHeartBeat} + " l/p"]]></expression> </element> - <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="335" y="150" width="65" height="16" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="52" y="150" width="58" height="16" fontName="Times New Roman" fontSize="12.0"> <expression><![CDATA[$P{checkupBloodPressure} +" mmHg"]]></expression> </element> - <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="486" y="16" width="53" height="49"> + <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="499" y="17" width="52" height="48"> <component kind="barcode4j:QRCode"> <codeExpression><![CDATA[$P{driveURL}]]></codeExpression> </component> </element> - <element kind="textField" uuid="9763a634-05c2-4f64-a903-c914455b7ee6" x="70" y="57" width="282" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> + <element kind="textField" uuid="9763a634-05c2-4f64-a903-c914455b7ee6" x="70" y="61" width="282" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> <printWhenExpression><![CDATA[$P{templateTitle} != null && !$P{templateTitle}.trim().isEmpty()]]></printWhenExpression> <expression><![CDATA["PHIẾU " + $P{templateTitle}]]></expression> </element> - <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="484" y="65" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> + <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="495" y="64" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> <printWhenExpression><![CDATA[$P{driveURL} != null && !$P{driveURL}.trim().isEmpty()]]></printWhenExpression> <text><![CDATA[Xem KQ online]]></text> </element> - <element kind="component" uuid="73f562ce-2891-4577-aec2-7284203c8430" x="394" y="21" width="70" height="49"> + <element kind="component" uuid="73f562ce-2891-4577-aec2-7284203c8430" x="429" y="15" width="70" height="49"> <component kind="barcode4j:Code128"> <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> </component> @@ -160,12 +161,21 @@ <element kind="image" uuid="2902cf3c-31dd-4b96-be87-fa8a13ba88ae" x="400" y="342" width="151" height="124"> <expression><![CDATA[$P{image3}]]></expression> </element> - <element kind="image" uuid="129e6c61-d572-48a9-925e-1ab2e4e573e2" x="400" y="468" width="151" height="129"> + <element kind="image" uuid="129e6c61-d572-48a9-925e-1ab2e4e573e2" x="400" y="466" width="151" height="124"> <expression><![CDATA[$P{image4}]]></expression> </element> + <element kind="textField" uuid="5fde8538-8d26-4761-9a19-dd716a74749a" x="70" y="12" width="358" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> + <expression><![CDATA[$P{clinicName}]]></expression> + </element> </element> </band> </detail> + <pageFooter height="20"> + <element kind="textField" uuid="e94aab84-4f90-4496-bc35-17547a2fa18a" x="300" y="0" width="252" height="17" fontName="Times New Roman" pattern="MMMMM dd, yyyy" hTextAlign="Right" vTextAlign="Bottom"> + <expression><![CDATA[new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm").format(new java.util.Date()) + " | Trang " + $V{PAGE_NUMBER}]]></expression> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </element> + </pageFooter> <summary height="179"> <element kind="staticText" uuid="b6ee4329-aeb1-4ddf-99e8-41ebebaff12b" x="0" y="0" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> <text><![CDATA[III.Kết luận]]></text> diff --git a/src/main/java/BsK/client/ui/component/DataDialog/DataDialog.java b/src/main/java/BsK/client/ui/component/DataDialog/DataDialog.java index 24df594..d3c473c 100644 --- a/src/main/java/BsK/client/ui/component/DataDialog/DataDialog.java +++ b/src/main/java/BsK/client/ui/component/DataDialog/DataDialog.java @@ -530,9 +530,9 @@ public class DataDialog extends JDialog { public ActionButtonRenderer() { setLayout(new FlowLayout(FlowLayout.CENTER, 2, 2)); - ImageIcon editIcon = createIcon("/BsK/client/ui/assets/icon/edit.png", 16, 16); + ImageIcon editIcon = createIcon("src/main/java/BsK/client/ui/assets/icon/edit.png", 16, 16); editButton = new JButton(editIcon); - ImageIcon deleteIcon = createIcon("/BsK/client/ui/assets/icon/delete.png", 16, 16); + ImageIcon deleteIcon = createIcon("src/main/java/BsK/client/ui/assets/icon/delete.png", 16, 16); deleteButton = new JButton(deleteIcon); editButton.setPreferredSize(new Dimension(30, 25)); @@ -564,9 +564,9 @@ public class DataDialog extends JDialog { super(new JCheckBox()); panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2)); - ImageIcon editIcon = createIcon("/BsK/client/ui/assets/icon/edit.png", 16, 16); + ImageIcon editIcon = createIcon("src/main/java/BsK/client/ui/assets/icon/edit.png", 16, 16); editButton = new JButton(editIcon); - ImageIcon deleteIcon = createIcon("/BsK/client/ui/assets/icon/delete.png", 16, 16); + ImageIcon deleteIcon = createIcon("src/main/java/BsK/client/ui/assets/icon/delete.png", 16, 16); deleteButton = new JButton(deleteIcon); editButton.setPreferredSize(new Dimension(30, 25)); diff --git a/src/main/java/BsK/client/ui/component/DataDialog/MedicineManagementPanel.java b/src/main/java/BsK/client/ui/component/DataDialog/MedicineManagementPanel.java index 42dbcfd..9f4ee49 100644 --- a/src/main/java/BsK/client/ui/component/DataDialog/MedicineManagementPanel.java +++ b/src/main/java/BsK/client/ui/component/DataDialog/MedicineManagementPanel.java @@ -37,12 +37,13 @@ public class MedicineManagementPanel extends JPanel { private JTextField medicineNameField; private JTextField medicineCompanyField; private JTextArea medicineDescriptionField; + private JTextField routeField; // --- ADDED --- Field for Route of Administration private JTextField medicineUnitField; private JTextField medicinePriceField; private JSpinner morningSpinner, noonSpinner, eveningSpinner; private JTextArea noteField; - private JCheckBox chkIsDeleted; // Checkbox for soft delete - private JCheckBox chkIsSupplement; // Checkbox for supplement status + private JCheckBox chkIsDeleted; // Checkbox for soft delete + private JCheckBox chkIsSupplement; // Checkbox for supplement status // --- Action Buttons --- private JButton btnAdd, btnEdit, btnClear; @@ -151,6 +152,22 @@ public class MedicineManagementPanel extends JPanel { medicineInfoPanel.add(descriptionScrollPane, gbc); gbc.weightx = 0.0; + // --- ADDED: Route of Administration Field --- + gbc.gridy++; + gbc.gridx = 0; + JLabel routeLabel = new JLabel("Đường dùng:"); + routeLabel.setFont(labelFont); + medicineInfoPanel.add(routeLabel, gbc); + + gbc.gridx = 1; + gbc.weightx = 1.0; + routeField = new JTextField(20); + routeField.setFont(textFont); + routeField.setPreferredSize(textFieldSize); + medicineInfoPanel.add(routeField, gbc); + gbc.weightx = 0.0; + // --- END ADDED --- + mainGbc.gridx = 0; mainGbc.gridy = 0; mainInputPanel.add(medicineInfoPanel, mainGbc); @@ -331,6 +348,7 @@ public class MedicineManagementPanel extends JPanel { // 2. Gather data from all other fields String company = medicineCompanyField.getText().trim(); String description = medicineDescriptionField.getText().trim(); + String route = routeField.getText().trim(); // --- ADDED --- String unit = medicineUnitField.getText().trim(); Boolean isSupplement = chkIsSupplement.isSelected(); Boolean isDeleted = false; // New medicines are active by default @@ -352,13 +370,13 @@ public class MedicineManagementPanel extends JPanel { // 4. Construct the special 'preferredNote' string String preferredNote = morningSpinner.getValue().toString() + "," - + noonSpinner.getValue().toString() + "," - + eveningSpinner.getValue().toString() + "," - + noteField.getText().trim(); + + noonSpinner.getValue().toString() + "," + + eveningSpinner.getValue().toString() + "," + + noteField.getText().trim(); // 5. Create the request packet and send it to the server - // IMPORTANT: Assumes your AddMedicineRequest packet is updated to include 'supplement' - AddMedicineRequest request = new AddMedicineRequest(name, company, description, unit, price, preferredNote, isSupplement, isDeleted); + // --- UPDATED ---: Added 'route' to the request constructor + AddMedicineRequest request = new AddMedicineRequest(name, company, description, unit, price, preferredNote, isSupplement, isDeleted, route); NetworkUtil.sendPacket(ClientHandler.ctx.channel(), request); // 6. Provide feedback and reset the form @@ -393,6 +411,7 @@ public class MedicineManagementPanel extends JPanel { String id = selectedMedicineId; String company = medicineCompanyField.getText().trim(); String description = medicineDescriptionField.getText().trim(); + String route = routeField.getText().trim(); // --- ADDED --- String unit = medicineUnitField.getText().trim(); Boolean isSupplement = chkIsSupplement.isSelected(); Boolean isDeleted = chkIsDeleted.isSelected(); @@ -414,13 +433,13 @@ public class MedicineManagementPanel extends JPanel { // 5. Construct the 'preferredNote' string String preferredNote = morningSpinner.getValue().toString() + "," - + noonSpinner.getValue().toString() + "," - + eveningSpinner.getValue().toString() + "," - + noteField.getText().trim(); + + noonSpinner.getValue().toString() + "," + + eveningSpinner.getValue().toString() + "," + + noteField.getText().trim(); // 6. Create the request packet and send it - // IMPORTANT: Assumes your EditMedicineRequest packet is updated to include 'supplement' - EditMedicineRequest request = new EditMedicineRequest(id, name, company, description, unit, price, preferredNote, isSupplement, isDeleted); + // --- UPDATED ---: Added 'route' to the request constructor + EditMedicineRequest request = new EditMedicineRequest(id, name, company, description, unit, price, preferredNote, isSupplement, isDeleted, route); NetworkUtil.sendPacket(ClientHandler.ctx.channel(), request); // 7. Provide user feedback and clear the form @@ -507,6 +526,7 @@ public class MedicineManagementPanel extends JPanel { medicineNameField.setText(med.getName()); medicineCompanyField.setText(med.getCompany()); medicineDescriptionField.setText(med.getDescription()); + routeField.setText(med.getRoute()); // --- ADDED --- medicineUnitField.setText(med.getUnit()); medicinePriceField.setText(med.getSellingPrice()); @@ -552,6 +572,7 @@ public class MedicineManagementPanel extends JPanel { medicineNameField.setText(""); medicineCompanyField.setText(""); medicineDescriptionField.setText(""); + routeField.setText(""); // --- ADDED --- medicineUnitField.setText(""); medicinePriceField.setText(""); diff --git a/src/main/java/BsK/client/ui/component/DataDialog/UserManagementPanel.java b/src/main/java/BsK/client/ui/component/DataDialog/UserManagementPanel.java index dfc5b5a..7fde327 100644 --- a/src/main/java/BsK/client/ui/component/DataDialog/UserManagementPanel.java +++ b/src/main/java/BsK/client/ui/component/DataDialog/UserManagementPanel.java @@ -149,7 +149,7 @@ public class UserManagementPanel extends JPanel { panel.add(new JLabel("Vai trò:"), gbc); gbc.gridx = 1; gbc.weightx = 1; - roleComboBox = new JComboBox<>(new String[]{"ADMIN", "DOCTOR", "STAFF"}); + roleComboBox = new JComboBox<>(new String[]{"ADMIN", "USER"}); panel.add(roleComboBox, gbc); } diff --git a/src/main/java/BsK/client/ui/component/common/MedicineDialog/MedicineDialog.java b/src/main/java/BsK/client/ui/component/common/MedicineDialog/MedicineDialog.java index ee61d8b..002df2d 100644 --- a/src/main/java/BsK/client/ui/component/common/MedicineDialog/MedicineDialog.java +++ b/src/main/java/BsK/client/ui/component/common/MedicineDialog/MedicineDialog.java @@ -18,17 +18,18 @@ import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.*; -import java.text.NumberFormat; // --- ADD THIS IMPORT --- +import java.text.NumberFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Locale; // --- ADD THIS IMPORT --- +import java.util.Locale; @Slf4j public class MedicineDialog extends JDialog { private JTextField medicineNameField; private JTextField medicineCompanyField; private JTextArea medicineDescriptionField; + private JTextField routeField; // --- ADDED --- private JCheckBox chkIsSupplement; // The new checkbox private JSpinner quantitySpinner; private JComboBox<String> UnitComboBox; @@ -258,6 +259,23 @@ public class MedicineDialog extends JDialog { medicineInfoPanel.add(descriptionScrollPane, gbc); gbc.weightx = 0.0; + // --- ADDED: Route of Administration Field --- + gbc.gridy++; + gbc.gridx = 0; + JLabel routeLabel = new JLabel("Đường dùng:"); + routeLabel.setFont(labelFont); + medicineInfoPanel.add(routeLabel, gbc); + + gbc.gridx = 1; + gbc.weightx = 1.0; + routeField = new JTextField(20); + routeField.setFont(textFont); + routeField.setPreferredSize(textFieldSize); + routeField.setEditable(false); + medicineInfoPanel.add(routeField, gbc); + gbc.weightx = 0.0; + // --- END ADDED --- + gbc.gridy++; gbc.gridx = 0; gbc.gridwidth = 2; @@ -408,10 +426,12 @@ public class MedicineDialog extends JDialog { suggestionPopup.add(suggestionScrollPane, BorderLayout.CENTER); suggestionPopup.setFocusable(false); - String[] selectedColumnNames = {"ID", "Tên thuốc", "SL", "ĐVT", "Sáng", "Trưa", "Chiều", "Đơn giá", "Thành tiền", "Ghi chú", "Supplement"}; + // --- UPDATED: Added "Đường dùng" column --- + String[] selectedColumnNames = {"ID", "Tên thuốc", "SL", "ĐVT", "Sáng", "Trưa", "Chiều", "Đơn giá", "Thành tiền", "Ghi chú", "Supplement", "Đường dùng"}; selectedTableModel = new DefaultTableModel(new String[][]{}, selectedColumnNames) { @Override public boolean isCellEditable(int row, int column) { + // Allow editing Quantity, Dosage, and Note return column == 2 || column == 4 || column == 5 || column == 6 || column == 9; } }; @@ -603,8 +623,9 @@ public class MedicineDialog extends JDialog { logger.info("Prescription saved."); if (medicinePrescription != null) { for (String[] row : medicinePrescription) { - logger.info("Med: ID={}, Name={}, Qty={}, Unit={}, M={}, N={}, E={}, Price={}, Total={}, Note={}", - row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9]); + // --- UPDATED: Logged the new 'route' field --- + logger.info("Med: ID={}, Name={}, Qty={}, Unit={}, M={}, N={}, E={}, Price={}, Total={}, Note={}, Supp={}, Route={}", + row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11]); } } dispose(); @@ -724,6 +745,7 @@ public class MedicineDialog extends JDialog { medicineCompanyField.setText(medicine.getCompany()); medicineDescriptionField.setText(medicine.getDescription()); + routeField.setText(medicine.getRoute()); // --- ADDED --- UnitComboBox.setSelectedItem(medicine.getUnit()); priceField.setText(medicine.getSellingPrice()); @@ -764,6 +786,7 @@ public class MedicineDialog extends JDialog { // Don't clear the name field as the user is typing in it medicineCompanyField.setText(""); medicineDescriptionField.setText(""); + routeField.setText(""); // --- ADDED --- UnitComboBox.setSelectedIndex(0); priceField.setText(""); totalField.setText(""); @@ -800,7 +823,7 @@ public class MedicineDialog extends JDialog { private void addSelectedMedicine() { int selectedRowInSuggestionTable = suggestionTable.getSelectedRow(); - String medicineId, name, unit, currentPrice, supplement; + String medicineId, name, unit, currentPrice, supplement, route; // --- UPDATED --- String searchName = medicineNameField.getText().trim(); if (searchName.isEmpty()) { @@ -835,6 +858,7 @@ public class MedicineDialog extends JDialog { unit = selectedMedicine.getUnit(); currentPrice = selectedMedicine.getSellingPrice(); supplement = selectedMedicine.getSupplement(); + route = selectedMedicine.getRoute(); // --- ADDED --- int quantity = (Integer) quantitySpinner.getValue(); int morningVal = (Integer) morningSpinner.getValue(); @@ -848,8 +872,8 @@ public class MedicineDialog extends JDialog { return; } - // Include supplement information - selectedTableModel.addRow(new Object[]{medicineId, name, quantity, unit, morningVal, noonVal, eveningVal, currentPrice, totalAmount, note, supplement}); + // --- UPDATED: Add 'route' to the table row data --- + selectedTableModel.addRow(new Object[]{medicineId, name, quantity, unit, morningVal, noonVal, eveningVal, currentPrice, totalAmount, note, supplement, route}); // Clear fields for next entry isProgrammaticallySettingMedicineNameField = true; @@ -874,22 +898,27 @@ public class MedicineDialog extends JDialog { medicinePrescription = new String[0][0]; return; } - medicinePrescription = new String[rowCount][11]; + // --- UPDATED: Array size changed from 11 to 12 --- + medicinePrescription = new String[rowCount][12]; for (int i = 0; i < rowCount; i++) { - medicinePrescription[i][0] = selectedTableModel.getValueAt(i, 0).toString(); - medicinePrescription[i][1] = selectedTableModel.getValueAt(i, 1).toString(); - medicinePrescription[i][2] = selectedTableModel.getValueAt(i, 2).toString(); - medicinePrescription[i][3] = selectedTableModel.getValueAt(i, 3).toString(); - medicinePrescription[i][4] = selectedTableModel.getValueAt(i, 4).toString(); - medicinePrescription[i][5] = selectedTableModel.getValueAt(i, 5).toString(); - medicinePrescription[i][6] = selectedTableModel.getValueAt(i, 6).toString(); - medicinePrescription[i][7] = selectedTableModel.getValueAt(i, 7).toString(); - medicinePrescription[i][8] = selectedTableModel.getValueAt(i, 8).toString(); - medicinePrescription[i][9] = selectedTableModel.getValueAt(i, 9).toString(); + medicinePrescription[i][0] = selectedTableModel.getValueAt(i, 0).toString(); // ID + medicinePrescription[i][1] = selectedTableModel.getValueAt(i, 1).toString(); // Tên + medicinePrescription[i][2] = selectedTableModel.getValueAt(i, 2).toString(); // SL + medicinePrescription[i][3] = selectedTableModel.getValueAt(i, 3).toString(); // ĐVT + medicinePrescription[i][4] = selectedTableModel.getValueAt(i, 4).toString(); // Sáng + medicinePrescription[i][5] = selectedTableModel.getValueAt(i, 5).toString(); // Trưa + medicinePrescription[i][6] = selectedTableModel.getValueAt(i, 6).toString(); // Chiều + medicinePrescription[i][7] = selectedTableModel.getValueAt(i, 7).toString(); // Đơn giá + medicinePrescription[i][8] = selectedTableModel.getValueAt(i, 8).toString(); // Thành tiền + medicinePrescription[i][9] = selectedTableModel.getValueAt(i, 9).toString(); // Ghi chú // Get supplement value (0/1) or default to "0" if null Object supplementObj = selectedTableModel.getValueAt(i, 10); - medicinePrescription[i][10] = (supplementObj != null) ? supplementObj.toString() : "0"; + medicinePrescription[i][10] = (supplementObj != null) ? supplementObj.toString() : "0"; // Supplement + + // --- ADDED: Get route value --- + Object routeObj = selectedTableModel.getValueAt(i, 11); + medicinePrescription[i][11] = (routeObj != null) ? routeObj.toString() : ""; // Đường dùng } } @@ -958,7 +987,8 @@ public class MedicineDialog extends JDialog { if (prescription != null && prescription.length > 0) { System.out.println("Prescription obtained:"); for (String[] item : prescription) { - System.out.println(String.format("ID:%s, Name:%s, Qty:%s, Unit:%s, M:%s, N:%s, E:%s, Price:%s, Total:%s, Note:%s", + // --- UPDATED: Test printout format --- + System.out.println(String.format("ID:%s, Name:%s, Qty:%s, Unit:%s, M:%s, N:%s, E:%s, Price:%s, Total:%s, Note:%s, Supp:%s, Route:%s", (Object[]) item)); } } else { diff --git a/src/main/java/BsK/common/entity/Medicine.java b/src/main/java/BsK/common/entity/Medicine.java index 6c9d678..b86d1af 100644 --- a/src/main/java/BsK/common/entity/Medicine.java +++ b/src/main/java/BsK/common/entity/Medicine.java @@ -20,6 +20,7 @@ public class Medicine { private String preferredNote; private String supplement; // 0: no, 1: yes private String deleted; // 0: no, 1: yes + private String route; /** * Constructor to create Medicine from array data @@ -38,6 +39,7 @@ public class Medicine { this.preferredNote = data[6]; this.supplement = data[7]; this.deleted = data[8]; + this.route = data[9]; } /** @@ -45,6 +47,6 @@ public class Medicine { * @return String array representation of Medicine */ public String[] toStringArray() { - return new String[]{id, name, company, description, unit, sellingPrice, preferredNote, supplement, deleted}; + return new String[]{id, name, company, description, unit, sellingPrice, preferredNote, supplement, deleted, route}; } } \ No newline at end of file diff --git a/src/main/java/BsK/common/packet/req/AddMedicineRequest.java b/src/main/java/BsK/common/packet/req/AddMedicineRequest.java index 72057f4..ec08947 100644 --- a/src/main/java/BsK/common/packet/req/AddMedicineRequest.java +++ b/src/main/java/BsK/common/packet/req/AddMedicineRequest.java @@ -15,4 +15,5 @@ public class AddMedicineRequest implements Packet{ private String preferredNote; private Boolean supplement; private Boolean deleted; + private String route; } diff --git a/src/main/java/BsK/common/packet/req/EditMedicineRequest.java b/src/main/java/BsK/common/packet/req/EditMedicineRequest.java index e99592e..428d8e8 100644 --- a/src/main/java/BsK/common/packet/req/EditMedicineRequest.java +++ b/src/main/java/BsK/common/packet/req/EditMedicineRequest.java @@ -16,4 +16,5 @@ public class EditMedicineRequest implements Packet { private String preferredNote; private Boolean supplement; private Boolean deleted; + private String route; } diff --git a/src/main/java/BsK/common/packet/res/ClinicInfoResponse.java b/src/main/java/BsK/common/packet/res/ClinicInfoResponse.java index ed225f0..921608f 100644 --- a/src/main/java/BsK/common/packet/res/ClinicInfoResponse.java +++ b/src/main/java/BsK/common/packet/res/ClinicInfoResponse.java @@ -12,4 +12,5 @@ public class ClinicInfoResponse implements Packet { private String clinicName; private String clinicAddress; private String clinicPhone; + private String clinicPrefix; } diff --git a/src/main/java/BsK/server/Server.java b/src/main/java/BsK/server/Server.java index 32154d9..aab5115 100644 --- a/src/main/java/BsK/server/Server.java +++ b/src/main/java/BsK/server/Server.java @@ -2,6 +2,8 @@ package BsK.server; import BsK.server.network.handler.ServerHandler; import BsK.server.service.GoogleDriveServiceOAuth; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; @@ -23,32 +25,32 @@ import java.io.IOException; import java.io.InputStream; import java.net.InetSocketAddress; import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.SQLException; -import java.sql.Statement; import java.util.Properties; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; @Slf4j public class Server { - private static int PORT; - public static Connection connection; - public static GoogleDriveServiceOAuth googleDriveService; - private static boolean googleDriveEnabled = true; // Can be configured - private static String googleDriveRootFolderName = "BSK_Clinic_Patient_Files"; // Default - public static String imageDbPath = "img_db"; // Default - public static String checkupMediaBaseDir = "src/main/resources/image/checkup_media"; // Default + private static int PORT; + + // --- REFACTORED DATABASE CONNECTION --- + // The single, static connection pool (DataSource). This is thread-safe. + private static HikariDataSource dataSource; + + // These static fields are still okay as they are configured once at startup. + public static GoogleDriveServiceOAuth googleDriveService; + private static boolean googleDriveEnabled = true; + private static String googleDriveRootFolderName = "BSK_Clinic_Patient_Files"; + public static String imageDbPath = "img_db"; + public static String checkupMediaBaseDir = "src/main/resources/image/checkup_media"; + // Static initializer block to set up the server configuration and connection pool static { try { - // Load configuration + // --- Load configuration --- Properties props = new Properties(); - - // First try to load from external config file File externalConfig = new File("config/config.properties"); if (externalConfig.exists()) { try (var input = Files.newInputStream(externalConfig.toPath())) { @@ -56,7 +58,6 @@ public class Server { log.info("Loaded configuration from external file: {}", externalConfig.getAbsolutePath()); } } else { - // Fall back to internal config try (InputStream input = Server.class.getClassLoader().getResourceAsStream("config.properties")) { if (input == null) { log.error("Unable to find config.properties"); @@ -66,67 +67,108 @@ public class Server { log.info("Loaded configuration from internal resources"); } } - - // Get port configuration - String portStr = props.getProperty("server.port"); - String addressStr = props.getProperty("server.address"); - - // Log address configuration - if (addressStr != null) { - log.info("Server address configured as: {}", addressStr); - } else { - log.info("No server address configured, clients will need to use the correct address to connect"); - } - - // Get port configuration - if (portStr != null) { - PORT = Integer.parseInt(portStr); - log.info("Using configured port: {}", PORT); - } else { - PORT = 1999; - log.info("Using default port: {}", PORT); - } - // Get Google Drive configuration - String driveEnabledStr = props.getProperty("google.drive.enabled"); - if (driveEnabledStr != null) { - googleDriveEnabled = Boolean.parseBoolean(driveEnabledStr); - } - - String driveRootFolderStr = props.getProperty("google.drive.root.folder"); - if (driveRootFolderStr != null && !driveRootFolderStr.trim().isEmpty()) { - googleDriveRootFolderName = driveRootFolderStr.trim(); - } - - log.info("Google Drive integration enabled: {}", googleDriveEnabled); + PORT = Integer.parseInt(props.getProperty("server.port", "1999")); + log.info("Using port: {}", PORT); + + // Load other properties + googleDriveEnabled = Boolean.parseBoolean(props.getProperty("google.drive.enabled", "true")); + googleDriveRootFolderName = props.getProperty("google.drive.root.folder", "BSK_Clinic_Patient_Files").trim(); + imageDbPath = props.getProperty("storage.image_db_path", "img_db").trim(); + checkupMediaBaseDir = props.getProperty("storage.checkup_media_base_dir", "src/main/resources/image/checkup_media").trim(); + log.info("Google Drive enabled: {}", googleDriveEnabled); log.info("Google Drive root folder: {}", googleDriveRootFolderName); - - // Get Storage paths configuration - String imageDbPathStr = props.getProperty("storage.image_db_path"); - if (imageDbPathStr != null && !imageDbPathStr.trim().isEmpty()) { - imageDbPath = imageDbPathStr.trim(); - } - - String checkupMediaBaseDirStr = props.getProperty("storage.checkup_media_base_dir"); - if (checkupMediaBaseDirStr != null && !checkupMediaBaseDirStr.trim().isEmpty()) { - checkupMediaBaseDir = checkupMediaBaseDirStr.trim(); - } - log.info("Image DB path: {}", imageDbPath); log.info("Checkup media base dir: {}", checkupMediaBaseDir); - // Directly use the provided database path + + // --- DATABASE POOL INITIALIZATION --- String dbPath = "src/main/resources/database/BSK.db"; - connection = DriverManager.getConnection("jdbc:sqlite:" + dbPath); + + // 1. Configure HikariCP + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:sqlite:" + dbPath); + config.setConnectionTestQuery("SELECT 1"); + config.setMaximumPoolSize(10); // Max 10 concurrent connections, perfect for your use case + config.setPoolName("BsK-DB-Pool"); + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + + // 2. Create the DataSource (the pool itself) + dataSource = new HikariDataSource(config); + log.info("✅ Database connection pool initialized successfully for {}", dbPath); // Initialize Google Drive service if enabled initializeGoogleDriveService(); } catch (Exception e) { + log.error("❌ Failed to initialize server", e); throw new RuntimeException("Failed to initialize server", e); } } + /** + * This is the new, safe way for handlers to get a database connection. + * @return A database connection from the pool. + * @throws SQLException if a connection cannot be obtained. + */ + public static Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + public static void main(String[] args) throws InterruptedException { + log.info("\n____ _____ _ __\n| _ \\ / ____| |/ \n| |_) | (___ | ' / \n| _ < \\___ \\| <\n| |_) |____) | . \\\n|____/|_____/|_|\\_\n"); + ServerDashboard dashboard = ServerDashboard.getInstance(); + dashboard.setVisible(true); + dashboard.updateStatus("Starting...", Color.ORANGE); + dashboard.updatePort(PORT); + dashboard.updateGoogleDriveStatus(isGoogleDriveConnected(), isGoogleDriveConnected() ? "Connected" : "Disconnected"); + + EventLoopGroup parentGroup = Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup(); + EventLoopGroup childGroup = Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup(); + try { + ServerBootstrap bootstrap = new ServerBootstrap() + .group(parentGroup, childGroup) + .channel(Epoll.isAvailable() ? EpollServerSocketChannel.class : NioServerSocketChannel.class) + .localAddress(new InetSocketAddress(PORT)) + .childHandler(new ChannelInitializer<SocketChannel>() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline() + .addLast(new IdleStateHandler(60 * 30, 0, 0, TimeUnit.SECONDS)) + .addLast(new HttpServerCodec()) + .addLast(new ChunkedWriteHandler()) + .addLast(new HttpObjectAggregator(50 * 1024 * 1024)) + .addLast(new WebSocketServerProtocolHandler("/", null, true, 50 * 1024 * 1024)) + .addLast(new ServerHandler()); // A new handler for each client + } + }); + + ChannelFuture f = bootstrap.bind().sync(); + log.info("Server started on port {}", PORT); + dashboard.updateStatus("Running", Color.GREEN); + dashboard.addLog("Server started successfully on port " + PORT); + + f.channel().closeFuture().sync(); + } catch (Exception e) { + dashboard.updateStatus("Error", Color.RED); + dashboard.addLog("Server error: " + e.getMessage()); + log.error("Server crashed", e); + } finally { + dashboard.updateStatus("Shutting down", Color.ORANGE); + dashboard.addLog("Server shutting down..."); + parentGroup.shutdownGracefully(); + childGroup.shutdownGracefully(); + if (dataSource != null) { + dataSource.close(); // Close the connection pool on shutdown + log.info("Database connection pool closed."); + } + } + } + + // --- Google Drive and other helper methods --- + private static void initializeGoogleDriveService() { if (!googleDriveEnabled) { log.info("Google Drive integration is disabled"); @@ -139,7 +181,6 @@ public class Server { googleDriveService = new GoogleDriveServiceOAuth(googleDriveRootFolderName); log.info("✅ Google Drive OAuth service initialized successfully"); - // Update dashboard if it exists if (ServerDashboard.getInstance() != null) { ServerDashboard.getInstance().updateGoogleDriveStatus(true, "Connected"); } @@ -147,48 +188,31 @@ public class Server { } catch (Exception e) { log.error("❌ Failed to initialize Google Drive OAuth service: {}", e.getMessage()); log.info("💡 Server will continue without Google Drive integration"); - log.info("🔧 To fix this, ensure google-oauth-credentials.json is properly configured"); googleDriveService = null; - // Update dashboard if it exists if (ServerDashboard.getInstance() != null) { ServerDashboard.getInstance().updateGoogleDriveStatus(false, "Failed: " + e.getMessage()); } } } - /** - * Manually retry Google Drive connection - */ public static void retryGoogleDriveConnection() { log.info("🔄 Retrying Google Drive connection..."); initializeGoogleDriveService(); } - /** - * Check if Google Drive is connected - */ public static boolean isGoogleDriveConnected() { return googleDriveService != null; } - /** - * Get Google Drive service instance - */ public static GoogleDriveServiceOAuth getGoogleDriveService() { return googleDriveService; } - /** - * Get the current Google Drive root folder name - */ public static String getGoogleDriveRootFolderName() { return googleDriveRootFolderName; } - /** - * Update Google Drive root folder name and reinitialize service - */ public static void updateGoogleDriveRootFolder(String newRootFolderName) throws Exception { if (newRootFolderName == null || newRootFolderName.trim().isEmpty()) { throw new IllegalArgumentException("Root folder name cannot be empty"); @@ -197,23 +221,17 @@ public class Server { googleDriveRootFolderName = newRootFolderName.trim(); log.info("🔄 Updating Google Drive root folder to: {}", googleDriveRootFolderName); - // Save to configuration file saveGoogleDriveRootFolderToConfig(googleDriveRootFolderName); - // Reinitialize Google Drive service with new root folder if (googleDriveEnabled) { initializeGoogleDriveService(); } } - /** - * Save Google Drive root folder name to config file - */ private static void saveGoogleDriveRootFolderToConfig(String rootFolderName) { try { Properties props = new Properties(); - // Load existing properties File externalConfig = new File("config/config.properties"); if (externalConfig.exists()) { try (var input = Files.newInputStream(externalConfig.toPath())) { @@ -227,16 +245,13 @@ public class Server { } } - // Update the root folder property props.setProperty("google.drive.root.folder", rootFolderName); - // Create config directory if it doesn't exist File configDir = new File("config"); if (!configDir.exists()) { configDir.mkdirs(); } - // Save to external config file try (var output = Files.newOutputStream(externalConfig.toPath())) { props.store(output, "BSK Server Configuration - Updated by Dashboard"); log.info("💾 Saved Google Drive root folder setting to config file"); @@ -247,96 +262,6 @@ public class Server { } } - private static String extractDatabaseFile() throws IOException { - throw new UnsupportedOperationException("extractDatabaseFile is not used anymore. Database is read directly from the specified path."); - } - - public static Statement statement; - - static { - try { - statement = connection.createStatement(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public Server() throws SQLException { - } - - public static void main(String[] args) throws InterruptedException, SQLException { - log.info("\n____ _____ _ __\n| _ \\ / ____| |/\n| |_) | (___ | ' /\n| _ < \\___ \\| <\n| |_) |____) | . \\\n|____/|_____/|_|\\_\n"); - // Initialize and show server dashboard - ServerDashboard dashboard = ServerDashboard.getInstance(); - dashboard.setVisible(true); - dashboard.updateStatus("Starting...", Color.ORANGE); - dashboard.updatePort(PORT); - - // Update Google Drive status on dashboard - dashboard.updateGoogleDriveStatus(isGoogleDriveConnected(), - isGoogleDriveConnected() ? "Connected" : "Disconnected"); - - EventLoopGroup parentGroup = - Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup(); - EventLoopGroup childGroup = - Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup(); - try { - ServerBootstrap bootstrap = - new ServerBootstrap() - .group(parentGroup, childGroup) - .channel( - Epoll.isAvailable() - ? EpollServerSocketChannel.class - : NioServerSocketChannel.class) - .localAddress(new InetSocketAddress(PORT)) - .childHandler( - new ChannelInitializer<SocketChannel>() { - @Override - protected void initChannel(SocketChannel ch) throws Exception { - ch.pipeline() - .addLast(new IdleStateHandler(60 * 30, 0, 0, TimeUnit.SECONDS)) - .addLast(new HttpServerCodec()) - .addLast(new ChunkedWriteHandler()) - .addLast(new HttpObjectAggregator(50 * 1024 * 1024)) - .addLast(new WebSocketServerProtocolHandler("/", null, true, 50 * 1024 * 1024)) - .addLast(new ServerHandler()); - } - }); - - ChannelFuture f = bootstrap.bind().sync(); - - log.info("Server started on port {}", PORT); - log.info("To connect, clients should use:"); - log.info(" - If on same machine: ws://localhost:{} or ws://127.0.0.1:{}", PORT, PORT); - log.info(" - If on network: ws://<this-computer's-ip>:{}", PORT); - - // Update dashboard status to running - dashboard.updateStatus("Running", Color.GREEN); - dashboard.addLog("Server started successfully on port " + PORT); - if (isGoogleDriveConnected()) { - dashboard.addLog("Google Drive integration: Connected ✅"); - } else { - dashboard.addLog("Google Drive integration: Disconnected ❌"); - } - - f.channel().closeFuture().sync(); - } catch (Exception e) { - dashboard.updateStatus("Error", Color.RED); - dashboard.addLog("Server error: " + e.getMessage()); - throw e; - } finally { - dashboard.updateStatus("Shutting down", Color.ORANGE); - dashboard.addLog("Server shutting down..."); - parentGroup.shutdownGracefully(); - childGroup.shutdownGracefully(); - } - } - - /** - * Initiates the backup of the main database file to Google Drive. - * This is intended to be called from the ServerDashboard. - * @throws IOException if the file cannot be found or the upload fails. - */ public static void backupDatabaseToDrive() throws IOException { ServerDashboard dashboard = ServerDashboard.getInstance(); @@ -345,7 +270,6 @@ public class Server { throw new IOException("Google Drive service is not available."); } - // Define the path to the database String dbPath = "src/main/resources/database/BSK.db"; java.io.File dbFile = new java.io.File(dbPath); @@ -354,7 +278,6 @@ public class Server { throw new IOException("Database file not found: " + dbPath); } - // Call the service to perform the backup googleDriveService.backupDatabaseFile(dbFile); - } + } } diff --git a/src/main/java/BsK/server/network/handler/ServerHandler.java b/src/main/java/BsK/server/network/handler/ServerHandler.java index a716914..604466b 100644 --- a/src/main/java/BsK/server/network/handler/ServerHandler.java +++ b/src/main/java/BsK/server/network/handler/ServerHandler.java @@ -116,7 +116,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram "from checkup as a\n" + "join customer as c on a.customer_id = c.customer_id\n" + "join Doctor D on a.doctor_id = D.doctor_id\n" + - "where a.status = 'ĐANG KHÁM' or a.status = 'CHỜ KHÁM'" + "where a.checkup_date >= CAST(strftime('%s', date('now', 'start of day')) AS INTEGER) * 1000\n" + + "AND a.checkup_date < CAST(strftime('%s', date('now', 'start of day', '+1 day')) AS INTEGER) * 1000" ); if (!rs.isBeforeFirst()) { @@ -310,7 +311,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram log.debug("Received ClinicInfoRequest"); try { ResultSet rs = statement.executeQuery( - "select name, address, phone\n" + + "select name, address, phone, prefix\n" + " from Clinic" ); @@ -320,8 +321,9 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram String clinicName = rs.getString("name"); String clinicAddress = rs.getString("address"); String clinicPhone = rs.getString("phone"); + String clinicPrefix = rs.getString("prefix"); - UserUtil.sendPacket(currentUser.getSessionId(), new ClinicInfoResponse(clinicName, clinicAddress, clinicPhone)); + UserUtil.sendPacket(currentUser.getSessionId(), new ClinicInfoResponse(clinicName, clinicAddress, clinicPhone, clinicPrefix)); } } catch (SQLException e) { @@ -566,107 +568,113 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram } if (packet instanceof AddCheckupRequest addCheckupRequest) { - log.debug("Received AddCheckupRequest to add patient{}", addCheckupRequest.getCustomerId()); + log.debug("Received AddCheckupRequest to add for customer {}", addCheckupRequest.getCustomerId()); + + // Khai báo các biến ID ở ngoài khối try để có thể sử dụng sau này + int generatedCheckupId = 0; + int queueNumber = 0; + try { - // Disable auto-commit - Server.connection.setAutoCommit(false); - - int queueNumber = 0; - // Use a transaction to ensure atomic operations - try { - // First, try to update an existing counter for today - try (PreparedStatement updateStmt = Server.connection.prepareStatement( - "UPDATE DailyQueueCounter SET current_count = current_count + 1 " + - "WHERE date = date('now', 'localtime') RETURNING current_count")) { - ResultSet rs = updateStmt.executeQuery(); - if (rs.next()) { - // Update successful, get the new value - queueNumber = rs.getInt(1); - } else { - // No row for today exists yet, insert one - try (PreparedStatement insertStmt = Server.connection.prepareStatement( - "INSERT INTO DailyQueueCounter (date, current_count) VALUES (date('now', 'localtime'), 1) " + - "RETURNING current_count")) { - ResultSet insertRs = insertStmt.executeQuery(); - if (insertRs.next()) { - queueNumber = insertRs.getInt(1); // Should be 1 - } else { - throw new SQLException("Failed to insert new queue counter"); - } - } - } - } - } catch (SQLException e) { - log.error("Error updating queue counter", e); - throw new RuntimeException(e); - } - // First query: Insert Checkup - PreparedStatement checkupStmt = Server.connection.prepareStatement( - "INSERT INTO Checkup (customer_id, doctor_id, checkup_type, status, queue_number) VALUES (?, ?, ?, ?, ?)"); - checkupStmt.setInt(1, addCheckupRequest.getCustomerId()); - checkupStmt.setInt(2, addCheckupRequest.getDoctorId()); - checkupStmt.setString(3, addCheckupRequest.getCheckupType()); - checkupStmt.setString(4, addCheckupRequest.getStatus()); - checkupStmt.setInt(5, queueNumber); - checkupStmt.executeUpdate(); - - // Second query: Insert MedicineOrder - PreparedStatement medOrderStmt = Server.connection.prepareStatement( - "INSERT INTO MedicineOrder (checkup_id, customer_id, processed_by) VALUES (last_insert_rowid(), ?, ?)"); - medOrderStmt.setInt(1, addCheckupRequest.getCustomerId()); - medOrderStmt.setInt(2, addCheckupRequest.getProcessedById()); - medOrderStmt.executeUpdate(); - - // Third query: Update Checkup - - PreparedStatement updateStmt = Server.connection.prepareStatement( - "UPDATE Checkup SET prescription_id = last_insert_rowid() WHERE checkup_id = (SELECT MAX(checkup_id) FROM Checkup WHERE customer_id = ?)"); - updateStmt.setInt(1, addCheckupRequest.getCustomerId()); - updateStmt.executeUpdate(); - - // Get the generated checkup ID safely - int generatedCheckupId = 0; - PreparedStatement getCheckupIdStmt = Server.connection.prepareStatement( - "SELECT MAX(checkup_id) FROM Checkup WHERE customer_id = ?"); - getCheckupIdStmt.setInt(1, addCheckupRequest.getCustomerId()); - ResultSet checkupIdRs = getCheckupIdStmt.executeQuery(); - if (checkupIdRs.next()) { - generatedCheckupId = checkupIdRs.getInt(1); - } - getCheckupIdStmt.close(); - checkupIdRs.close(); - - // Commit the transaction - Server.connection.commit(); - - // Send immediate response to client - UserUtil.sendPacket(currentUser.getSessionId(), new AddCheckupResponse(true, "Thêm bệnh nhân thành công", queueNumber)); - - broadcastQueueUpdate(); - - // Create Google Drive folder asynchronously (don't block the response) - createCheckupGoogleDriveFolderAsync(generatedCheckupId, addCheckupRequest.getCustomerId()); + // Bắt đầu một transaction + Server.connection.setAutoCommit(false); + + // --- 1. LẤY SỐ THỨ TỰ (QUEUE NUMBER) MỘT CÁCH AN TOÀN --- + // Sử dụng UPSERT (INSERT ON CONFLICT) để đảm bảo thao tác là nguyên tử + String queueSql = "INSERT INTO DailyQueueCounter (date, current_count) " + + "VALUES (date('now', 'localtime'), 1) " + + "ON CONFLICT(date) DO UPDATE SET current_count = current_count + 1 " + + "RETURNING current_count"; + + try (PreparedStatement queueStmt = Server.connection.prepareStatement(queueSql)) { + ResultSet rs = queueStmt.executeQuery(); + if (rs.next()) { + queueNumber = rs.getInt(1); + } else { + throw new SQLException("Failed to get or update queue number."); + } + } + + // --- 2. CHÈN VÀO BẢNG CHECKUP VÀ LẤY LẠI CHECKUP_ID --- + String checkupSql = "INSERT INTO Checkup (customer_id, doctor_id, checkup_type, status, queue_number) VALUES (?, ?, ?, ?, ?)"; + try (PreparedStatement checkupStmt = Server.connection.prepareStatement(checkupSql, Statement.RETURN_GENERATED_KEYS)) { + checkupStmt.setInt(1, addCheckupRequest.getCustomerId()); + checkupStmt.setInt(2, addCheckupRequest.getDoctorId()); + checkupStmt.setString(3, addCheckupRequest.getCheckupType()); + checkupStmt.setString(4, addCheckupRequest.getStatus()); + checkupStmt.setInt(5, queueNumber); + checkupStmt.executeUpdate(); + + // Lấy checkup_id vừa được tạo ra một cách an toàn + try (ResultSet generatedKeys = checkupStmt.getGeneratedKeys()) { + if (generatedKeys.next()) { + generatedCheckupId = generatedKeys.getInt(1); + } else { + throw new SQLException("Creating checkup failed, no ID obtained."); + } + } + } + + // --- 3. CHÈN VÀO BẢNG MEDICINEORDER VÀ LẤY LẠI PRESCRIPTION_ID --- + int generatedPrescriptionId = 0; + String medOrderSql = "INSERT INTO MedicineOrder (checkup_id, customer_id, processed_by) VALUES (?, ?, ?)"; + try (PreparedStatement medOrderStmt = Server.connection.prepareStatement(medOrderSql, Statement.RETURN_GENERATED_KEYS)) { + medOrderStmt.setInt(1, generatedCheckupId); // Sử dụng ID đã lấy được + medOrderStmt.setInt(2, addCheckupRequest.getCustomerId()); + medOrderStmt.setInt(3, addCheckupRequest.getProcessedById()); + medOrderStmt.executeUpdate(); + + // Lấy prescription_id vừa được tạo ra một cách an toàn + try (ResultSet generatedKeys = medOrderStmt.getGeneratedKeys()) { + if (generatedKeys.next()) { + generatedPrescriptionId = generatedKeys.getInt(1); + } else { + throw new SQLException("Creating medicine order failed, no ID obtained."); + } + } + } + + // --- 4. CẬP NHẬT BẢNG CHECKUP VỚI PRESCRIPTION_ID --- + String updateSql = "UPDATE Checkup SET prescription_id = ? WHERE checkup_id = ?"; + try (PreparedStatement updateStmt = Server.connection.prepareStatement(updateSql)) { + updateStmt.setInt(1, generatedPrescriptionId); // Sử dụng ID đã lấy được + updateStmt.setInt(2, generatedCheckupId); // Sử dụng ID đã lấy được + updateStmt.executeUpdate(); + } + + // Nếu tất cả các bước thành công, commit transaction + Server.connection.commit(); + + // Gửi phản hồi thành công về cho client + UserUtil.sendPacket(currentUser.getSessionId(), new AddCheckupResponse(true, "Thêm bệnh nhân thành công", queueNumber)); + + // Broadcast cập nhật hàng chờ cho các client khác + broadcastQueueUpdate(); + + // Tạo thư mục Google Drive bất đồng bộ (không làm chậm phản hồi) + // generatedCheckupId bây giờ đã có giá trị chính xác + createCheckupGoogleDriveFolderAsync(generatedCheckupId, addCheckupRequest.getCustomerId()); + + } catch (SQLException e) { + log.error("SQLException during AddCheckupRequest, rolling back transaction.", e); + try { + // Rollback nếu có lỗi + Server.connection.rollback(); + } catch (SQLException rollbackEx) { + log.error("Error during rollback", rollbackEx); + } + String errorMessage = e.getMessage(); + UserUtil.sendPacket(currentUser.getSessionId(), new AddCheckupResponse(false, "Lỗi Server: " + errorMessage, -1)); + // Không cần throw RuntimeException nữa để server không bị sập + + } finally { + try { + // Luôn luôn reset auto-commit về true + Server.connection.setAutoCommit(true); + } catch (SQLException e) { + log.error("Error resetting auto-commit", e); + } } - catch (SQLException e) { - try { - // Rollback on error - Server.connection.rollback(); - } catch (SQLException rollbackEx) { - log.error("Error during rollback", rollbackEx); - } - String errorMessage = e.getMessage(); - UserUtil.sendPacket(currentUser.getSessionId(), new AddCheckupResponse(false, "Lỗi: " + errorMessage, -1)); - throw new RuntimeException(e); - } - finally { - try { - // Reset auto-commit - Server.connection.setAutoCommit(true); - } catch (SQLException e) { - log.error("Error resetting auto-commit", e); - } - } - } + } if (packet instanceof CallPatientRequest callPatientRequest) { log.debug("Received CallPatientRequest to call patient checkup_id: {}", callPatientRequest.getPatientId()); @@ -894,7 +902,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram OI.price_per_unit, OI.total_price, OI.notes, - M.supplement + M.supplement, + M.route FROM OrderItem OI JOIN Medicine M ON OI.med_id = M.med_id WHERE OI.checkup_id = ? @@ -905,7 +914,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram ArrayList<String[]> medList = new ArrayList<>(); while(medRs.next()) { - String[] med = new String[11]; + String[] med = new String[12]; med[0] = medRs.getString("med_id"); med[1] = medRs.getString("med_name"); med[2] = medRs.getString("quantity_ordered"); @@ -933,6 +942,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram med[8] = medRs.getString("total_price"); med[9] = medRs.getString("notes"); med[10] = medRs.getString("supplement"); + med[11] = medRs.getString("route"); medList.add(med); } medicinePrescription = medList.toArray(new String[0][]); @@ -1458,7 +1468,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram } log.info("Received AddMedRequest"); try { - String sql = "INSERT INTO Medicine (med_name, med_company, med_description, med_unit, med_selling_price, preferred_note, supplement, deleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + String sql = "INSERT INTO Medicine (med_name, med_company, med_description, med_unit, med_selling_price, preferred_note, supplement, deleted, route) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; PreparedStatement stmt = Server.connection.prepareStatement(sql); stmt.setString(1, addMedicineRequest.getName()); stmt.setString(2, addMedicineRequest.getCompany()); @@ -1468,6 +1478,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram stmt.setString(6, addMedicineRequest.getPreferredNote()); stmt.setBoolean(7, addMedicineRequest.getSupplement()); stmt.setBoolean(8, addMedicineRequest.getDeleted()); + stmt.setString(9, addMedicineRequest.getRoute()); stmt.executeUpdate(); log.info("Added medicine: {}", addMedicineRequest.getName()); getMedInfo(currentUser.getSessionId()); @@ -1483,7 +1494,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram } log.info("Received EditMedRequest"); try { - String sql = "UPDATE Medicine SET med_name = ?, med_company = ?, med_description = ?, med_unit = ?, med_selling_price = ?, preferred_note = ?, supplement = ?, deleted = ? WHERE med_id = ?"; + String sql = "UPDATE Medicine SET med_name = ?, med_company = ?, med_description = ?, med_unit = ?, med_selling_price = ?, preferred_note = ?, supplement = ?, deleted = ?, route = ? WHERE med_id = ?"; PreparedStatement stmt = Server.connection.prepareStatement(sql); stmt.setString(1, editMedicineRequest.getName()); stmt.setString(2, editMedicineRequest.getCompany()); @@ -1493,7 +1504,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram stmt.setString(6, editMedicineRequest.getPreferredNote()); stmt.setBoolean(7, editMedicineRequest.getSupplement()); stmt.setBoolean(8, editMedicineRequest.getDeleted()); - stmt.setString(9, editMedicineRequest.getId()); + stmt.setString(9, editMedicineRequest.getRoute()); + stmt.setString(10, editMedicineRequest.getId()); stmt.executeUpdate(); log.info("Updated medicine: {}", editMedicineRequest.getName()); getMedInfo(currentUser.getSessionId()); @@ -1666,7 +1678,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram private void getMedInfo(int sessionId) { try { ResultSet rs = statement.executeQuery( - "select med_id, med_name, med_company, med_description, med_unit, med_selling_price, preferred_note, supplement, deleted\n" + + "select med_id, med_name, med_company, med_description, med_unit, med_selling_price, preferred_note, supplement, deleted, route\n" + " from Medicine" ); @@ -1684,9 +1696,10 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram String preferredNote = rs.getString("preferred_note"); String supplement = rs.getString("supplement"); String deleted = rs.getString("deleted"); + String route = rs.getString("route"); String result = String.join("|",medId, medName, medCompany, medDescription, medUnit, - medSellingPrice, preferredNote != null ? preferredNote : "", supplement != null ? supplement : "0", deleted); + medSellingPrice, preferredNote != null ? preferredNote : "", supplement != null ? supplement : "0", deleted, route); resultList.add(result); } @@ -2156,7 +2169,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram "from checkup as a\n" + "join customer as c on a.customer_id = c.customer_id\n" + "join Doctor D on a.doctor_id = D.doctor_id\n" + - "where a.status = 'ĐANG KHÁM' or a.status = 'CHỜ KHÁM'" + "where a.checkup_date >= CAST(strftime('%s', date('now', 'start of day')) AS INTEGER) * 1000\n" + + "AND a.checkup_date < CAST(strftime('%s', date('now', 'start of day', '+1 day')) AS INTEGER) * 1000" ); String[][] resultArray; diff --git a/src/main/resources/assets/logo.jpg b/src/main/resources/assets/logo.jpg deleted file mode 100644 index c98dcc4..0000000 Binary files a/src/main/resources/assets/logo.jpg and /dev/null differ diff --git a/src/main/resources/database/BSK.db b/src/main/resources/database/BSK.db index 05f1b4c..7f4b404 100644 Binary files a/src/main/resources/database/BSK.db and b/src/main/resources/database/BSK.db differ diff --git a/src/main/resources/reports/medserinvoice.jrxml b/src/main/resources/reports/medserinvoice.jrxml deleted file mode 100644 index 861a71b..0000000 Binary files a/src/main/resources/reports/medserinvoice.jrxml and /dev/null differ diff --git a/src/main/resources/reports/ultrasoundresult.jrxml b/src/main/resources/reports/ultrasoundresult.jrxml deleted file mode 100644 index b581bb4..0000000 --- a/src/main/resources/reports/ultrasoundresult.jrxml +++ /dev/null @@ -1,270 +0,0 @@ -<!-- Created with Jaspersoft Studio version 7.0.3.final using JasperReports Library version 7.0.3-41034ca841d452f3305ba55b9042260aaa1ab5dd --> -<jasperReport name="Blank_A4_Landscape" language="java" columnCount="1" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e7f9ca7e-f0db-48b0-bef9-93be21b3b0a3"> - <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/> - <parameter name="checkupNote" class="java.lang.String"/> - <parameter name="checkupDate" class="java.lang.String"/> - <parameter name="patientDiagnos" class="java.lang.String"/> - <parameter name="doctorName" class="java.lang.String"/> - <parameter name="medicineDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> - <parameter name="serviceDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> - <parameter name="supplementDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> - <parameter name="name" class="java.lang.String"/> - <parameter name="clinicName" class="java.lang.String"/> - <parameter name="patientAddress" class="java.lang.String"/> - <parameter name="clinicPhone" class="java.lang.String"/> - <parameter name="patientName" class="java.lang.String"/> - <parameter name="patientDOB" class="java.lang.String"/> - <parameter name="clinicAddress" class="java.lang.String"/> - <parameter name="logoImage" class="java.lang.String"/> - <parameter name="barcodeNumber" class="java.lang.String"/> - <parameter name="patientGender" class="java.lang.String"/> - <parameter name="hasMedicines" class="java.lang.Boolean"/> - <parameter name="hasServices" class="java.lang.Boolean"/> - <parameter name="hasSupplements" class="java.lang.Boolean"/> - <parameter name="checkupConclusion" class="java.lang.String"/> - <parameter name="checkupSuggestion" class="java.lang.String"/> - <parameter name="reCheckupDate" class="java.lang.String"/> - <parameter name="image1" class="java.lang.String"/> - <parameter name="image2" class="java.lang.String"/> - <parameter name="image3" class="java.lang.String"/> - <parameter name="checkupHeight" class="java.lang.String"/> - <parameter name="image4" class="java.lang.String"/> - <parameter name="image5" class="java.lang.String"/> - <parameter name="numberImage" class="java.lang.Integer"/> - <parameter name="image6" class="java.lang.String"/> - <parameter name="checkupBloodPressure" class="java.lang.String"/> - <parameter name="checkupHeartBeat" class="java.lang.String"/> - <parameter name="checkupWeight" class="java.lang.String"/> - <parameter name="templateTitle" class="java.lang.String"/> - <parameter name="driveURL" class="java.lang.String"/> - <parameter name="ultrasoundDoctorName" class="java.lang.String"/> - <query language="sql"><![CDATA[]]></query> - <background splitType="Stretch"/> - <title splitType="Stretch"/> - <pageHeader splitType="Stretch"/> - <columnHeader splitType="Stretch"/> - <detail> - <band height="540" splitType="Stretch"> - <element kind="frame" uuid="2b7ec588-953c-4145-87b7-1d861c272fe0" x="0" y="0" width="400" height="539"> - <element kind="image" uuid="fd80ab38-4cae-409b-84b9-356220d2b1e5" x="0" y="1" width="60" height="60"> - <expression><![CDATA[$P{logoImage}]]></expression> - </element> - <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="60" y="0" width="290" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <expression><![CDATA[$P{clinicName}]]></expression> - </element> - <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="60" y="20" width="235" height="25" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{clinicAddress}]]></expression> - </element> - <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="60" y="45" width="162" height="12" fontName="Times New Roman" fontSize="8.0"> - <expression><![CDATA["SDT: " + $P{clinicPhone}]]></expression> - </element> - <element kind="staticText" uuid="6f89a93f-2d10-4506-baa5-226bdd047b17" x="0" y="65" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <text><![CDATA[I.Thông tin]]></text> - </element> - <element kind="staticText" uuid="b8dfca43-cf97-49e5-b58d-4667143dba62" x="0" y="79" width="50" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Họ và tên:]]></text> - </element> - <element kind="staticText" uuid="0a9ca0c8-f2bd-4ade-a025-a6d79c13613f" x="1" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Ngày sinh:]]></text> - </element> - <element kind="staticText" uuid="21917ab8-ae07-44c8-ba4e-bc6c4c54b440" x="140" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Giới tính:]]></text> - </element> - <element kind="staticText" uuid="bcbb614e-7a4d-48a3-83c2-198e4fb62c5f" x="1" y="109" width="49" height="15" fontName="Times New Roman" bold="true" hTextAlign="Left"> - <text><![CDATA[Địa chỉ:]]></text> - </element> - <element kind="staticText" uuid="45fe4be1-9e21-459b-aeee-2efc8354f372" x="221" y="80" width="68" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Bác sĩ chỉ định:]]></text> - </element> - <element kind="staticText" uuid="f2ff4b17-63cc-4e8c-a3b0-2523f534f21a" x="221" y="94" width="60" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Ngày khám:]]></text> - </element> - <element kind="textField" uuid="1511f53a-b282-41b1-b233-612b6106c07a" x="48" y="79" width="172" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientName}]]></expression> - </element> - <element kind="textField" uuid="5bdac267-523d-4931-926b-76233ce9b84d" x="50" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientDOB}]]></expression> - </element> - <element kind="textField" uuid="f4df20b4-920c-491e-882b-6e0733cb4866" x="184" y="94" width="36" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientGender}]]></expression> - </element> - <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="39" y="109" width="361" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientAddress}]]></expression> - </element> - <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="290" y="80" width="110" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{doctorName}]]></expression> - </element> - <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="276" y="94" width="124" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupDate}]]></expression> - </element> - <element kind="staticText" uuid="9f7de81c-4c38-41a2-9fea-a165eff19431" x="1" y="124" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Chuẩn đoán:]]></text> - </element> - <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="60" y="124" width="340" height="26" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientDiagnos}]]></expression> - </element> - <element kind="staticText" uuid="b1fa845a-48da-4e45-82b8-8b9d972650f6" x="0" y="162" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <text><![CDATA[II.Nội dung]]></text> - </element> - <element kind="textField" uuid="6d652a25-b701-45bd-91ba-750842650004" x="0" y="177" width="398" height="362" markup="rtf" fontName="Times New Roman" fontSize="14.0"> - <expression><![CDATA[$P{checkupNote}]]></expression> - </element> - <element kind="staticText" uuid="8f720f6a-0257-4556-b3bc-3b81ad4f8099" x="1" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Chiều cao:]]></text> - </element> - <element kind="staticText" uuid="a57e7a9d-4ac7-4219-b268-cd08ce943327" x="100" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Cân nặng:]]></text> - </element> - <element kind="staticText" uuid="2b9cfd9d-ec8f-4036-9c96-039fd7855e24" x="200" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Nhịp tim:]]></text> - </element> - <element kind="staticText" uuid="c1356370-11ce-4b68-97d6-ce6e18e306c5" x="290" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Huyết áp:]]></text> - </element> - <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="50" y="150" width="50" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupWeight} +" cm"]]></expression> - </element> - <element kind="textField" uuid="fb080012-3196-4535-bcd2-e87274c66fa5" x="147" y="150" width="53" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupWeight} + " kg"]]></expression> - </element> - <element kind="textField" uuid="e4185ffe-8712-41e3-a9ff-2be6569dff15" x="243" y="150" width="47" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupHeartBeat} + " l/p"]]></expression> - </element> - <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="335" y="150" width="63" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupBloodPressure} +" mmHg"]]></expression> - </element> - <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="362" y="19" width="38" height="35"> - <component kind="barcode4j:QRCode"> - <codeExpression><![CDATA[$P{driveURL}]]></codeExpression> - </component> - </element> - <element kind="textField" uuid="9763a634-05c2-4f64-a903-c914455b7ee6" x="70" y="57" width="282" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> - <printWhenExpression><![CDATA[$P{templateTitle} != null && !$P{templateTitle}.trim().isEmpty()]]></printWhenExpression> - <expression><![CDATA["PHIẾU " + $P{templateTitle}]]></expression> - </element> - </element> - <element kind="frame" uuid="a72ffc70-007e-43af-a566-b34e6e07b312" x="400" y="0" width="400" height="540"> - <element kind="staticText" uuid="246a04b0-2565-4987-b7f3-dd369703035c" x="0" y="340" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> - <text><![CDATA[III.Kết luận]]></text> - </element> - <element kind="staticText" uuid="c53ef0ab-a702-47fc-9b7c-24307a495b30" x="0" y="430" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> - <text><![CDATA[Đề nghị:]]></text> - </element> - <element kind="staticText" uuid="a38b1187-ddb8-4410-9b52-dc041f894b7b" x="250" y="440" width="96" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> - <text><![CDATA[Bác sĩ siêu âm]]></text> - </element> - <element kind="textField" uuid="b548d99d-bedf-4e90-b13b-bdbc763aa974" x="200" y="513" width="200" height="21" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> - <expression><![CDATA[$P{ultrasoundDoctorName}]]></expression> - </element> - <element kind="textField" uuid="8bca58ab-0958-40fe-8e51-2a39a9d379a5" x="200" y="521" width="200" height="19" fontName="Times New Roman" pattern="MMMMM dd, yyyy" hTextAlign="Center" vTextAlign="Bottom"> - <expression><![CDATA[new java.text.SimpleDateFormat("'Đức Hoà, ngày ' dd ' tháng ' MM ' năm ' yyyy", new java.util.Locale("vi", "VN")).format(new java.util.Date())]]></expression> - </element> - <element kind="staticText" uuid="c062ce0e-80cb-4e67-a5d9-d85e769c6c4e" x="0" y="525" width="110" height="14" forecolor="#FF0905" fontName="Times New Roman" fontSize="10.0" bold="true"> - <text><![CDATA[Tái khám:]]></text> - </element> - <element kind="textField" uuid="e90ad772-4425-482d-9e75-f2bc66b9084d" x="0" y="358" width="400" height="70" fontName="Times New Roman" fontSize="12.0"> - <expression><![CDATA[$P{checkupConclusion}]]></expression> - </element> - <element kind="component" uuid="cb28d811-1328-45dc-9461-cfbb88b7eeae" x="-105" y="19" width="64" height="40"> - <component kind="barcode4j:Code128"> - <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> - </component> - </element> - <element kind="textField" uuid="d63165c2-19e2-43ad-8a3f-004e00bffdfe" x="0" y="450" width="240" height="66" fontName="Times New Roman" fontSize="12.0"> - <expression><![CDATA[$P{checkupSuggestion}]]></expression> - </element> - <element kind="textField" uuid="cece8e5b-67db-4019-b52a-bf73abae535e" x="48" y="525" width="150" height="15" fontName="Times New Roman" fontSize="12.0"> - <expression><![CDATA[$P{reCheckupDate}]]></expression> - </element> - <element kind="frame" uuid="2f301804-acfa-4b6f-9f52-236c04fd1197" x="0" y="0" width="400" height="344"> - <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 6]]></printWhenExpression> - <element kind="image" uuid="fe4e4fa7-8b26-4817-ae86-4c147a25abbe" x="83" y="3" width="111" height="113"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - <element kind="image" uuid="9c6302ea-8b4a-48d6-8c42-68313154be77" x="83" y="117" width="111" height="113"> - <expression><![CDATA[$P{image3}]]></expression> - </element> - <element kind="image" uuid="d7d6a47e-a129-4726-80b1-701113d0d9c2" x="83" y="231" width="111" height="113"> - <expression><![CDATA[$P{image5}]]></expression> - </element> - <element kind="image" uuid="7cd3d01b-f3ac-48d1-9749-ab5787497ab9" x="198" y="232" width="111" height="113"> - <expression><![CDATA[$P{image6}]]></expression> - </element> - <element kind="image" uuid="65610203-a91f-4b55-9a33-d6bfb7ffa7a6" x="199" y="117" width="111" height="113"> - <expression><![CDATA[$P{image4}]]></expression> - </element> - <element kind="image" uuid="127b0f54-33e9-43a5-af62-64152d74958f" x="199" y="3" width="111" height="113"> - <expression><![CDATA[$P{image2}]]></expression> - </element> - </element> - <element kind="frame" uuid="58523878-7ef9-46fe-aad7-ee5bd65115aa" x="0" y="1" width="400" height="344"> - <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 5]]></printWhenExpression> - <element kind="image" uuid="6870ae02-5ee4-40e8-9787-1ad084dc3b7f" x="83" y="3" width="111" height="113"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - <element kind="image" uuid="4216a22f-f20f-4bf1-9e93-79ccc3bbd5c6" x="83" y="117" width="111" height="113"> - <expression><![CDATA[$P{image3}]]></expression> - </element> - <element kind="image" uuid="3069d087-6d97-455c-bb0d-211b0698b54c" x="142" y="231" width="111" height="113"> - <expression><![CDATA[$P{image5}]]></expression> - </element> - <element kind="image" uuid="34187787-d55d-495a-be82-9ff67702211f" x="199" y="117" width="111" height="113"> - <expression><![CDATA[$P{image4}]]></expression> - </element> - <element kind="image" uuid="7b2d4efb-1f35-4c37-80a1-685195e1218e" x="199" y="3" width="111" height="113"> - <expression><![CDATA[$P{image2}]]></expression> - </element> - </element> - <element kind="frame" uuid="33b6f6ef-93e4-4488-a421-08de09b5458c" x="0" y="0" width="400" height="344"> - <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 4]]></printWhenExpression> - <element kind="image" uuid="1378905c-276f-42ba-9101-18b27ba14e0b" x="28" y="3" width="161" height="165"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - <element kind="image" uuid="58917767-70d5-4822-bb6f-7f5aba6f660e" x="29" y="173" width="161" height="165"> - <expression><![CDATA[$P{image3}]]></expression> - </element> - <element kind="image" uuid="6026efa4-cfd7-4b1d-90be-fe8912eb43c3" x="210" y="3" width="161" height="165"> - <expression><![CDATA[$P{image2}]]></expression> - </element> - <element kind="image" uuid="6c5adc41-f3d7-4e32-997a-e1845d7170c5" x="211" y="173" width="161" height="165"> - <expression><![CDATA[$P{image4}]]></expression> - </element> - </element> - <element kind="frame" uuid="94e66ae9-8863-45e0-9b9d-1a5fb7df84f5" x="0" y="0" width="400" height="344"> - <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 3]]></printWhenExpression> - <property name="com.jaspersoft.studio.unit.y" value="px"/> - <property name="com.jaspersoft.studio.unit.x" value="px"/> - <element kind="image" uuid="3ab88449-e282-41cd-898e-ab91aeef70b9" x="28" y="3" width="161" height="165"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - <element kind="image" uuid="119378b1-674d-457a-bc69-a9823f2160b7" x="121" y="173" width="161" height="165"> - <expression><![CDATA[$P{image3}]]></expression> - </element> - <element kind="image" uuid="8ac7bc19-5ae6-4569-87fb-c9cf72936b50" x="210" y="3" width="161" height="165"> - <expression><![CDATA[$P{image2}]]></expression> - </element> - </element> - <element kind="frame" uuid="935efa61-0cd7-47ab-b7d8-6508a1726537" x="0" y="0" width="400" height="344"> - <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 2]]></printWhenExpression> - <element kind="image" uuid="8f2957f9-fb76-49d1-94ce-08c723aec7ce" x="121" y="3" width="161" height="165"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - <element kind="image" uuid="f5585019-40b7-4b1b-9c7a-8b10386cf210" x="121" y="173" width="161" height="165"> - <expression><![CDATA[$P{image2}]]></expression> - </element> - </element> - <element kind="frame" uuid="dfa0c283-dbfc-40de-97e0-d1d04db85c96" x="0" y="0" width="400" height="344"> - <printWhenExpression><![CDATA[$P{numberImage}.intValue() == 1]]></printWhenExpression> - <property name="com.jaspersoft.studio.unit.y" value="px"/> - <element kind="image" uuid="a7cef70f-1dbe-4d6f-a007-7543bbc2b9b8" x="29" y="4" width="342" height="335"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - </element> - <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="-55" y="53" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> - <printWhenExpression><![CDATA[$P{driveURL} != null && !$P{driveURL}.trim().isEmpty()]]></printWhenExpression> - <text><![CDATA[Xem KQ online]]></text> - </element> - </element> - </band> - </detail> -</jasperReport> diff --git a/src/main/resources/reports/ultrasoundresult_potrait.jrxml b/src/main/resources/reports/ultrasoundresult_potrait.jrxml deleted file mode 100644 index f6082c0..0000000 --- a/src/main/resources/reports/ultrasoundresult_potrait.jrxml +++ /dev/null @@ -1,198 +0,0 @@ -<!-- Created with Jaspersoft Studio version 7.0.3.final using JasperReports Library version 7.0.3-41034ca841d452f3305ba55b9042260aaa1ab5dd --> -<jasperReport name="Blank_A4_Potrait" language="java" columnCount="1" pageWidth="595" pageHeight="842" orientation="Landscape" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e7f9ca7e-f0db-48b0-bef9-93be21b3b0a3"> - <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/> - <parameter name="checkupNote" class="java.lang.String"/> - <parameter name="checkupDate" class="java.lang.String"/> - <parameter name="patientDiagnos" class="java.lang.String"/> - <parameter name="doctorName" class="java.lang.String"/> - <parameter name="medicineDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> - <parameter name="serviceDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> - <parameter name="supplementDS" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> - <parameter name="name" class="java.lang.String"/> - <parameter name="clinicName" class="java.lang.String"/> - <parameter name="patientAddress" class="java.lang.String"/> - <parameter name="clinicPhone" class="java.lang.String"/> - <parameter name="patientName" class="java.lang.String"/> - <parameter name="patientDOB" class="java.lang.String"/> - <parameter name="clinicAddress" class="java.lang.String"/> - <parameter name="logoImage" class="java.lang.String"/> - <parameter name="barcodeNumber" class="java.lang.String"/> - <parameter name="patientGender" class="java.lang.String"/> - <parameter name="hasMedicines" class="java.lang.Boolean"/> - <parameter name="hasServices" class="java.lang.Boolean"/> - <parameter name="hasSupplements" class="java.lang.Boolean"/> - <parameter name="checkupConclusion" class="java.lang.String"/> - <parameter name="checkupSuggestion" class="java.lang.String"/> - <parameter name="reCheckupDate" class="java.lang.String"/> - <parameter name="image1" class="java.lang.String"/> - <parameter name="image2" class="java.lang.String"/> - <parameter name="image3" class="java.lang.String"/> - <parameter name="checkupHeight" class="java.lang.String"/> - <parameter name="image4" class="java.lang.String"/> - <parameter name="image5" class="java.lang.String"/> - <parameter name="numberImage" class="java.lang.Integer"/> - <parameter name="image6" class="java.lang.String"/> - <parameter name="checkupBloodPressure" class="java.lang.String"/> - <parameter name="checkupHeartBeat" class="java.lang.String"/> - <parameter name="checkupWeight" class="java.lang.String"/> - <parameter name="templateTitle" class="java.lang.String"/> - <parameter name="driveURL" class="java.lang.String"/> - <parameter name="ultrasoundDoctorName" class="java.lang.String"/> - <query language="sql"><![CDATA[]]></query> - <background splitType="Stretch"/> - <title splitType="Stretch"/> - <pageHeader splitType="Stretch"/> - <columnHeader splitType="Stretch"/> - <detail> - <band height="598" splitType="Stretch"> - <element kind="frame" uuid="2b7ec588-953c-4145-87b7-1d861c272fe0" x="0" y="0" width="551" height="598"> - <element kind="image" uuid="fd80ab38-4cae-409b-84b9-356220d2b1e5" x="0" y="-5" width="70" height="64"> - <expression><![CDATA[$P{logoImage}]]></expression> - </element> - <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="70" y="0" width="323" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <expression><![CDATA[$P{clinicName}]]></expression> - </element> - <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="70" y="20" width="323" height="22" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{clinicAddress}]]></expression> - </element> - <element kind="textField" uuid="260bb33d-1d11-4178-aceb-3fbf8fcb4b45" x="70" y="42" width="276" height="15" fontName="Times New Roman" fontSize="8.0"> - <expression><![CDATA[$P{clinicPhone}]]></expression> - </element> - <element kind="staticText" uuid="6f89a93f-2d10-4506-baa5-226bdd047b17" x="0" y="65" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <text><![CDATA[I.Thông tin]]></text> - </element> - <element kind="staticText" uuid="b8dfca43-cf97-49e5-b58d-4667143dba62" x="0" y="79" width="50" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Họ và tên:]]></text> - </element> - <element kind="staticText" uuid="0a9ca0c8-f2bd-4ade-a025-a6d79c13613f" x="1" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Ngày sinh:]]></text> - </element> - <element kind="staticText" uuid="21917ab8-ae07-44c8-ba4e-bc6c4c54b440" x="140" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Giới tính:]]></text> - </element> - <element kind="staticText" uuid="bcbb614e-7a4d-48a3-83c2-198e4fb62c5f" x="1" y="109" width="49" height="15" fontName="Times New Roman" bold="true" hTextAlign="Left"> - <text><![CDATA[Địa chỉ:]]></text> - </element> - <element kind="staticText" uuid="45fe4be1-9e21-459b-aeee-2efc8354f372" x="221" y="80" width="68" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Bác sĩ chỉ định:]]></text> - </element> - <element kind="staticText" uuid="f2ff4b17-63cc-4e8c-a3b0-2523f534f21a" x="221" y="94" width="60" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Ngày khám:]]></text> - </element> - <element kind="textField" uuid="1511f53a-b282-41b1-b233-612b6106c07a" x="48" y="79" width="172" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientName}]]></expression> - </element> - <element kind="textField" uuid="5bdac267-523d-4931-926b-76233ce9b84d" x="50" y="94" width="80" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientDOB}]]></expression> - </element> - <element kind="textField" uuid="f4df20b4-920c-491e-882b-6e0733cb4866" x="184" y="94" width="36" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientGender}]]></expression> - </element> - <element kind="textField" uuid="3b8ac40e-85aa-4ab8-8445-64bcddb8b267" x="39" y="109" width="361" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientAddress}]]></expression> - </element> - <element kind="textField" uuid="db40cdb0-2850-4d66-8430-addc54f90321" x="290" y="80" width="110" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{doctorName}]]></expression> - </element> - <element kind="textField" uuid="eb9cf54a-3b50-43c5-8696-cfc1e21bddfe" x="276" y="94" width="124" height="15" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupDate}]]></expression> - </element> - <element kind="staticText" uuid="9f7de81c-4c38-41a2-9fea-a165eff19431" x="1" y="124" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Chuẩn đoán:]]></text> - </element> - <element kind="textField" uuid="5ae67e13-7a79-437f-bfb8-c720d896720d" x="60" y="124" width="340" height="26" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{patientDiagnos}]]></expression> - </element> - <element kind="staticText" uuid="b1fa845a-48da-4e45-82b8-8b9d972650f6" x="0" y="162" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="14.0" bold="true"> - <text><![CDATA[II.Nội dung]]></text> - </element> - <element kind="textField" uuid="6d652a25-b701-45bd-91ba-750842650004" x="0" y="177" width="400" height="421" markup="rtf" fontName="Times New Roman" fontSize="16.0"> - <expression><![CDATA[$P{checkupNote}]]></expression> - </element> - <element kind="staticText" uuid="8f720f6a-0257-4556-b3bc-3b81ad4f8099" x="1" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Chiều cao:]]></text> - </element> - <element kind="staticText" uuid="a57e7a9d-4ac7-4219-b268-cd08ce943327" x="100" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Cân nặng:]]></text> - </element> - <element kind="staticText" uuid="2b9cfd9d-ec8f-4036-9c96-039fd7855e24" x="200" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Nhịp tim:]]></text> - </element> - <element kind="staticText" uuid="c1356370-11ce-4b68-97d6-ce6e18e306c5" x="290" y="150" width="59" height="16" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> - <text><![CDATA[Huyết áp:]]></text> - </element> - <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="50" y="150" width="50" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupWeight} +" cm"]]></expression> - </element> - <element kind="textField" uuid="fb080012-3196-4535-bcd2-e87274c66fa5" x="147" y="150" width="53" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupWeight} + " kg"]]></expression> - </element> - <element kind="textField" uuid="e4185ffe-8712-41e3-a9ff-2be6569dff15" x="243" y="150" width="47" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupHeartBeat} + " l/p"]]></expression> - </element> - <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="335" y="150" width="65" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupBloodPressure} +" mmHg"]]></expression> - </element> - <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="486" y="16" width="53" height="49"> - <component kind="barcode4j:QRCode"> - <codeExpression><![CDATA[$P{driveURL}]]></codeExpression> - </component> - </element> - <element kind="textField" uuid="9763a634-05c2-4f64-a903-c914455b7ee6" x="70" y="57" width="282" height="20" forecolor="#FF0905" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> - <printWhenExpression><![CDATA[$P{templateTitle} != null && !$P{templateTitle}.trim().isEmpty()]]></printWhenExpression> - <expression><![CDATA["PHIẾU " + $P{templateTitle}]]></expression> - </element> - <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="484" y="65" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> - <printWhenExpression><![CDATA[$P{driveURL} != null && !$P{driveURL}.trim().isEmpty()]]></printWhenExpression> - <text><![CDATA[Xem KQ online]]></text> - </element> - <element kind="component" uuid="73f562ce-2891-4577-aec2-7284203c8430" x="394" y="21" width="70" height="49"> - <component kind="barcode4j:Code128"> - <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> - </component> - </element> - <element kind="image" uuid="692eae9f-a304-4cda-856d-7a3a95fac3df" stretchType="NoStretch" x="400" y="91" width="151" height="124"> - <expression><![CDATA[$P{image1}]]></expression> - </element> - <element kind="image" uuid="9a15475c-d08c-4c8f-bbdf-70cf98f97e90" x="400" y="216" width="151" height="124"> - <expression><![CDATA[$P{image2}]]></expression> - </element> - <element kind="image" uuid="2902cf3c-31dd-4b96-be87-fa8a13ba88ae" x="400" y="342" width="151" height="124"> - <expression><![CDATA[$P{image3}]]></expression> - </element> - <element kind="image" uuid="129e6c61-d572-48a9-925e-1ab2e4e573e2" x="400" y="468" width="151" height="129"> - <expression><![CDATA[$P{image4}]]></expression> - </element> - </element> - </band> - </detail> - <summary height="179"> - <element kind="staticText" uuid="b6ee4329-aeb1-4ddf-99e8-41ebebaff12b" x="0" y="0" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> - <text><![CDATA[III.Kết luận]]></text> - </element> - <element kind="staticText" uuid="f4c12e4d-9aac-428d-bd79-59c3d15f0d87" x="0" y="60" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> - <text><![CDATA[Đề nghị:]]></text> - </element> - <element kind="staticText" uuid="d1d33b8f-b79a-45a1-b33b-1eecb656f49a" x="400" y="70" width="96" height="15" fontName="Times New Roman" fontSize="12.0" bold="true" hTextAlign="Center"> - <text><![CDATA[Bác sĩ siêu âm]]></text> - </element> - <element kind="textField" uuid="de0d077c-f1d6-4d0c-8bbd-fb08c19b07c6" x="347" y="140" width="200" height="21" fontName="Times New Roman" fontSize="14.0" bold="true" hTextAlign="Center"> - <expression><![CDATA[$P{ultrasoundDoctorName}]]></expression> - </element> - <element kind="textField" uuid="0b5be2b8-8837-41ee-a805-81f562f5f961" x="347" y="157" width="200" height="19" fontName="Times New Roman" pattern="MMMMM dd, yyyy" hTextAlign="Center" vTextAlign="Bottom"> - <expression><![CDATA[new java.text.SimpleDateFormat("'Đức Hoà, ngày ' dd ' tháng ' MM ' năm ' yyyy", new java.util.Locale("vi", "VN")).format(new java.util.Date())]]></expression> - </element> - <element kind="staticText" uuid="0b4ca7da-4831-4ca6-8272-94af19fd3089" x="0" y="155" width="110" height="14" forecolor="#FF0905" fontName="Times New Roman" fontSize="10.0" bold="true"> - <text><![CDATA[Tái khám:]]></text> - </element> - <element kind="textField" uuid="e4fb5d0b-bbc3-4e42-a431-1bd20bcfb25d" x="0" y="20" width="546" height="38" fontName="Times New Roman" fontSize="12.0"> - <expression><![CDATA[$P{checkupConclusion}]]></expression> - </element> - <element kind="textField" uuid="16b6dfab-1434-4de5-a1c4-619470f3d867" x="0" y="80" width="347" height="66" fontName="Times New Roman" fontSize="12.0"> - <expression><![CDATA[$P{checkupSuggestion}]]></expression> - </element> - <element kind="textField" uuid="4d8aeb33-ab41-4a5b-a5d1-52bab4043246" x="48" y="155" width="150" height="15" fontName="Times New Roman" fontSize="12.0"> - <expression><![CDATA[$P{reCheckupDate}]]></expression> - </element> - </summary> -</jasperReport>