diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java index e750aedb8..58e41234d 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java @@ -1231,4 +1231,56 @@ public class InvoiceController { } } } + + @PostMapping("/makeShippingTest") + public Result createShippingTestInvoice(@RequestBody int nbOfLines) throws UserException { + InvoiceMetaData metaData; + if(nbOfLines < 5) + throw new UserException("Number of lines must be at least 5"); + try { + metaData = shippingInvoiceService.makeShippingInvoiceTest(nbOfLines); + return Result.OK(metaData); + } catch (UserException e) { + return Result.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + return Result.error("Sorry, server error, please try later"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @PostMapping("/makePurchaseTest") + public Result createPurchaseTestInvoice(@RequestBody int nbOfLines) throws UserException { + InvoiceMetaData metaData; + if(nbOfLines < 5) + throw new UserException("Number of lines must be at least 5"); + try { + metaData = purchaseOrderService.makeInvoiceTest(nbOfLines); + return Result.OK(metaData); + } catch (UserException e) { + return Result.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + return Result.error("Sorry, server error, please try later"); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + @PostMapping("/makeCompleteTest") + public Result createCompleteTestInvoice(@RequestBody int nbOfLines) throws UserException { + InvoiceMetaData metaData; + if(nbOfLines < 5) + throw new UserException("Number of lines must be at least 5"); + try { + metaData = shippingInvoiceService.makeCompleteInvoiceTest(nbOfLines); + return Result.OK(metaData); + } catch (UserException e) { + return Result.error(e.getMessage()); + } catch (IOException e) { + log.error(e.getMessage()); + return Result.error("Sorry, server error, please try later"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/invoice/AbstractInvoice.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/invoice/AbstractInvoice.java index 50deecae8..c7bca5ba8 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/invoice/AbstractInvoice.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/invoice/AbstractInvoice.java @@ -161,6 +161,14 @@ public abstract class AbstractInvoice { org.apache.poi.ss.usermodel.Row sourceRow = sheet.getRow(FIRST_ROW); int footerRow = TOTAL_ROW + 1; // la ligne à laquelle le footer commence (1 ligne avant le total) int imgShift = additionalRowNum; // le nombre de ligne qu'on va décaler les images (signatures et tampon) + /** + * 1 : data.size() <= dataRowNumber + 1 -> only a few lines of data + * 2 : data fits in one page but not enough space for footer + * 3 : data fits in one page and enough space for footer + * 4 : data doesn't fit in one page and not enough space for footer + * 5 : data doesn't fit in one page and enough space for footer + */ + int situation = 1; if(data.size() > dataRowNumber + 1) { int startRow = LAST_ROW+1; @@ -174,33 +182,37 @@ public abstract class AbstractInvoice { if(TOTAL_ROW > LAST_ROW + 3) { // s'il ne reste pas assez de place pour le footer // on shift le footer à la page suivante (total + signature etc..) sheet.shiftRows(startRow, fileLastRow, PAGE_ROW_MAX - LAST_ROW - 1, true, false); - footerRow = PAGE_ROW_MAX - LAST_ROW + 1; imgShift = PAGE_ROW_MAX - LAST_ROW + 1; TOTAL_ROW = PAGE_ROW_MAX; + footerRow = TOTAL_ROW + 1; + situation = 2; } else { sheet.shiftRows(startRow, fileLastRow, additionalRowNum, true, false); - footerRow = additionalRowNum + 1; TOTAL_ROW = LAST_ROW + additionalRowNum+1; + footerRow = TOTAL_ROW + 1; + situation = 3; } } else {// on dépasse forcément le format A4 d'un PDF if(((TOTAL_ROW - 44) % 63) < 13) { // Not enough space for footer sheet.shiftRows(startRow, fileLastRow, TOTAL_ROW - LAST_ROW + ((TOTAL_ROW-44)%63), true, false); - footerRow = additionalRowNum + ((TOTAL_ROW-44)%63) + 1; imgShift = TOTAL_ROW-44 + ((TOTAL_ROW-44)%63) -1; TOTAL_ROW += ((TOTAL_ROW-44)%63) + 1; + footerRow = TOTAL_ROW+1; + situation = 4; } else { // Enough space for footer sheet.shiftRows(startRow, fileLastRow, TOTAL_ROW - LAST_ROW, true, false); - footerRow = TOTAL_ROW - LAST_ROW +1; + TOTAL_ROW = LAST_ROW + additionalRowNum + 1; + footerRow = TOTAL_ROW + 1; + situation = 5; } } - // inserting new rows after row 42 - for(int i = 0; i < footerRow; i++) { + for(int i = 0; i < footerRow - startRow; i++) { sheet.createRow(startRow-1 + i); org.apache.poi.ss.usermodel.Row newRow = sheet.getRow(startRow-1 + i); newRow.setHeight(sourceRow.getHeight()); @@ -211,7 +223,7 @@ public abstract class AbstractInvoice { Cell cell = newRow.createCell(j); CellStyle cellStyle = factory.getWorkbook().createCellStyle(); CellStyle middleCellStyle = factory.getWorkbook().createCellStyle(); - if (j == 1 || j == 9) { + if (j == 1 || j == 9) { // double bordure de la premiere et derniere colonne cellStyle.setBorderLeft(BorderStyle.DOUBLE); cell.setCellStyle(cellStyle); } @@ -256,11 +268,7 @@ public abstract class AbstractInvoice { if(data.size() > dataRowNumber) { org.apache.poi.ss.usermodel.Row totalRow; - // Si ça pète c'est surement ici - if(additionalRowNum%PAGE_ROW_MAX <= 13) - totalRow = sheet.getRow(TOTAL_ROW-1); - else - totalRow = sheet.getRow(TOTAL_ROW); + totalRow = sheet.getRow(TOTAL_ROW - 1); totalRow.setHeight(sourceRow.getHeight()); totalRow.setRowStyle(null); totalRow.setRowStyle(sourceRow.getRowStyle()); @@ -310,11 +318,11 @@ public abstract class AbstractInvoice { if(i==2) cell.setCellValue("Total"); if(i==5) - cell.setCellFormula("SUM(F"+FIRST_ROW+":F"+(TOTAL_ROW-1)+")"); + cell.setCellFormula("SUM(F" + FIRST_ROW + ":F" + (TOTAL_ROW - 1) + ")"); if(i==6) - cell.setCellFormula("SUM(G"+FIRST_ROW+":G"+(TOTAL_ROW-1)+")"); + cell.setCellFormula("SUM(G" + FIRST_ROW + ":G" + (TOTAL_ROW - 1) + ")"); if(i==7) - cell.setCellFormula("SUM(H"+FIRST_ROW+":H"+(TOTAL_ROW-1)+")"); + cell.setCellFormula("SUM(H" + FIRST_ROW + ":H" + (TOTAL_ROW - 1) + ")"); } //Total due @@ -328,7 +336,7 @@ public abstract class AbstractInvoice { // Si ça pète c'est pas là totalDueRow = sheet.getRow( totalRow.getRowNum() + 2); Cell totalDueCell = totalDueRow.createCell(7); - totalDueCell.setCellFormula("H" + (totalRow.getRowNum() + 1) + "-G" + (totalRow.getRowNum()) + 1); + totalDueCell.setCellFormula("H" + (totalRow.getRowNum() + 1) + "-G" + (totalRow.getRowNum() + 1)); totalDueCell.setCellStyle(totalDueCellStyle); } @@ -359,7 +367,6 @@ public abstract class AbstractInvoice { } } - /** * A shortcut to configure a cell of a sheet with a value and a style by global writer. * diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java index d6f5353c0..fe08f6179 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java @@ -107,6 +107,7 @@ public interface IPurchaseOrderService extends IService { * @throws IOException IO error while reading the file. */ InvoiceMetaData makeInvoice(String purchaseID) throws IOException, URISyntaxException, UserException; + InvoiceMetaData makeInvoiceTest(int nbOfLines) throws IOException, URISyntaxException, UserException; byte[] getInvoiceByte(String invoiceCode) throws IOException; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java index 8f3fbabef..1ee5ab4cd 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java @@ -8,6 +8,7 @@ import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.business.controller.UserException; import org.jeecg.modules.business.domain.excel.SheetManager; import org.jeecg.modules.business.domain.purchase.invoice.PurchaseInvoice; +import org.jeecg.modules.business.domain.purchase.invoice.PurchaseInvoiceEntry; import org.jeecg.modules.business.domain.shippingInvoice.CompleteInvoice; import org.jeecg.modules.business.domain.shippingInvoice.ShippingInvoice; import org.jeecg.modules.business.domain.shippingInvoice.ShippingInvoiceFactory; @@ -119,9 +120,13 @@ public class PlatformOrderShippingInvoiceService { @Value("${jeecg.path.shippingInvoiceDir}") private String INVOICE_DIR; + @Value("${jeecg.path.shippingInvoiceTestDir}") + private String INVOICE_TEST_DIR; @Value("${jeecg.path.purchaseInvoiceDir}") private String PURCHASE_INVOICE_DIR; + @Value("${jeecg.path.purchaseInvoiceTestDir}") + private String PURCHASE_INVOICE_TEST_DIR; @Value("${jeecg.path.purchaseInventoryDir}") private String PURCHASE_INVENTORY_DIR; @@ -930,4 +935,157 @@ public class PlatformOrderShippingInvoiceService { } return Collections.singletonList(out); } + + @Transactional + public InvoiceMetaData makeShippingInvoiceTest(int nbOfLines) throws Exception { + // Creates invoice by factory + Client client = clientService.getClientBySku("TEST"); + Map> ordersToContent = new HashMap<>(); + List savRefunds = new ArrayList<>(); + List extraFees = new ArrayList<>(); + BigDecimal exchangeRate = BigDecimal.ONE; + String invoiceCode = "SI-TEST-2" + nbOfLines; + + List poc = new ArrayList<>(); + PlatformOrderContent content = new PlatformOrderContent(); + content.setSkuId("TEST"); + content.setErpStatus("3"); + content.setQuantity(1); + content.setVat(BigDecimal.ZERO); + content.setShippingFee(BigDecimal.ZERO); + content.setPickingFee(BigDecimal.ZERO); + content.setShippingFee(BigDecimal.ZERO); + content.setServiceFee(BigDecimal.ONE); + poc.add(content); + + for(int i = 0; i < nbOfLines - 4; i++) { + PlatformOrder po = new PlatformOrder(); + po.setCountry("Country" + i); + po.setPickingFee(BigDecimal.ZERO); + po.setOrderServiceFee(BigDecimal.ZERO); + po.setPackagingMaterialFee(BigDecimal.ZERO); + po.setFretFee(BigDecimal.ZERO); + po.setPlatformOrderId("TEST" + i); + poc.get(0).setPlatformOrderId("TEST" + i); + ordersToContent.put(po, poc); + } + + ShippingInvoice invoice = new ShippingInvoice(client, invoiceCode, "Test subject", ordersToContent, savRefunds, extraFees, exchangeRate); + Path src; + src = Paths.get(SHIPPING_INVOICE_TEMPLATE_US); +// src = Paths.get(SHIPPING_INVOICE_TEMPLATE_EU); + + // Writes invoice content to a new excel file + String filename = "Invoice N°" + invoice.code() + " (" + invoice.client().getInvoiceEntity() + ")_" + nbOfLines +".xlsx"; + Path out = Paths.get(INVOICE_TEST_DIR, filename); + Files.copy(src, out, StandardCopyOption.REPLACE_EXISTING); + invoice.toExcelFile(out); + convertToPdfTest(invoiceCode, "invoice"); + + return new InvoiceMetaData(filename, invoice.code(), invoice.client().getInternalCode(), invoice.client().getInvoiceEntity(), ""); + } + @Transactional + public InvoiceMetaData makeCompleteInvoiceTest(int nbOfLines) throws Exception { + // Creates invoice by factory + Client client = clientService.getClientBySku("TEST"); + Map> ordersToContent = new HashMap<>(); + List savRefunds = new ArrayList<>(); + List extraFees = new ArrayList<>(); + List promotionDetails = new ArrayList<>(); + List purchaseInvoiceEntries = new ArrayList<>(); + BigDecimal exchangeRate = BigDecimal.ONE; + + String invoiceCode = "CI-TEST-7-" + nbOfLines; + + List poc = new ArrayList<>(); + PlatformOrderContent content = new PlatformOrderContent(); + content.setSkuId("TEST"); + content.setErpStatus("3"); + content.setQuantity(1); + content.setVat(BigDecimal.ZERO); + content.setShippingFee(BigDecimal.ZERO); + content.setPickingFee(BigDecimal.ZERO); + content.setShippingFee(BigDecimal.ZERO); + content.setServiceFee(BigDecimal.ONE); + poc.add(content); + + PlatformOrder po = new PlatformOrder(); + po.setCountry("Country"); + po.setPickingFee(BigDecimal.ZERO); + po.setOrderServiceFee(BigDecimal.ZERO); + po.setPackagingMaterialFee(BigDecimal.ZERO); + po.setFretFee(BigDecimal.ZERO); + po.setPlatformOrderId("TEST"); + poc.get(0).setPlatformOrderId("TEST"); + ordersToContent.put(po, poc); + for(int i = 0; i < nbOfLines - 5; i++) { + PurchaseInvoiceEntry entry = new PurchaseInvoiceEntry("SKU" + i, "Product" + i, 1, BigDecimal.ONE); + purchaseInvoiceEntries.add(entry); + } + + CompleteInvoice invoice = new CompleteInvoice(client, invoiceCode, "Test subject", ordersToContent, savRefunds, extraFees, purchaseInvoiceEntries, promotionDetails, exchangeRate); + Path src; +// src = Paths.get(COMPLETE_INVOICE_TEMPLATE_US); + src = Paths.get(COMPLETE_INVOICE_TEMPLATE_EU); + + // Writes invoice content to a new excel file + String filename = "Complete invoice N°" + invoice.code() + " (" + invoice.client().getInvoiceEntity() + ") _" + nbOfLines + ".xlsx"; + Path out = Paths.get(INVOICE_TEST_DIR, filename); + Files.copy(src, out, StandardCopyOption.REPLACE_EXISTING); + invoice.toExcelFile(out); + convertToPdfTest(invoiceCode, "invoice"); + return new InvoiceMetaData(filename, invoice.code(), invoice.client().getInternalCode(), invoice.client().getInvoiceEntity(), ""); + } + public void convertToPdfTest(String invoiceNumber, String fileType) throws Exception { + String excelFilePath = getInvoiceListTest(invoiceNumber, fileType);// (C:\PATH\filename.xlsx) + + if(!excelFilePath.equals("ERROR")) { + String pdfFilePath= INVOICE_PDF_DIR + "/" + invoiceNumber + ".pdf"; + pdfFilePath = INVOICE_PDF_DIR + "/Invoice N°" + invoiceNumber + ".pdf"; + + + Pattern p = Pattern.compile("^(.*)[\\/\\\\](.*)(\\.[a-z]+)"); //group(1): "C:\PATH" , group(2) : "filename", group(3): ".xlsx" + Matcher m = p.matcher(excelFilePath); + if (m.matches()) { + pdfFilePath = INVOICE_PDF_DIR + "/" + m.group(2) + ".pdf"; + } + // Créé un classeur pour charger le fichier Excel + PdfSaveOptions saveOptions = new PdfSaveOptions(); + saveOptions.setDefaultFont("Arial"); + saveOptions.setCheckWorkbookDefaultFont(false); + Workbook workbook = new Workbook(excelFilePath); + Worksheet sheet = workbook.getWorksheets().get(0); + // get number of lines + Cells cells = sheet.getCells(); + int maxRow = cells.getMaxDataRow(); + PageSetup pageSetup = sheet.getPageSetup(); + // Setting the number of pages to which the length of the worksheet will + if(maxRow < 63) { + // be spanned + pageSetup.setFitToPagesTall(1); + + // Setting the number of pages to which the width of the worksheet will be spanned + pageSetup.setFitToPagesWide(1); + } + // On enregistre le document au format PDF + workbook.save(pdfFilePath, saveOptions); + } + } + public String getInvoiceListTest(String invoiceNumber, String filetype) throws UserException, IOException { + log.info("Invoice number : " + invoiceNumber); + List pathList = new ArrayList<>(); + log.info("File asked is of type invoice"); + if(Invoice.getType(invoiceNumber).equalsIgnoreCase(PURCHASE.name())) + pathList = getPath(PURCHASE_INVOICE_TEST_DIR, invoiceNumber); + else + pathList = getPath(INVOICE_TEST_DIR, invoiceNumber); + if(pathList.isEmpty()) { + log.error("NO INVOICE FILE FOUND : " + invoiceNumber); + return "ERROR"; + } + for (Path path : pathList) { + log.info(path.toString()); + } + return pathList.get(0).toString(); + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java index 6f95ea3bc..ed64067dc 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java @@ -79,6 +79,8 @@ public class PurchaseOrderServiceImpl extends ServiceImpl purchaseOrderSkuList = new ArrayList<>(); + // -5 because we have at least 5 lines of promotions + for (int i = 0; i < nbOfLines - 5; i++) { + purchaseOrderSkuList.add(new PurchaseInvoiceEntry("SKU" + i, "SKU" + i, 1, BigDecimal.ONE)); + } + List promotionDetails = new ArrayList<>(); + for(int i = 0; i < 5; i++) { + promotionDetails.add(new PromotionDetail(1, BigDecimal.valueOf(0.5), "Test Promotion " + i)); + } + String invoiceCode = "P-TEST-CODE-" + nbOfLines; + BigDecimal eurToUsd = exchangeRatesMapper.getLatestExchangeRate("EUR", "USD"); + + String filename = "Invoice N°" + invoiceCode + " (" + client.getInvoiceEntity() + ")_" + nbOfLines + ".xlsx"; + Path template = Paths.get(INVOICE_TEMPLATE); + Path newInvoice = Paths.get(INVOICE_TEST_DIR, filename); + Files.copy(template, newInvoice, StandardCopyOption.REPLACE_EXISTING); + PurchaseInvoice pv = new PurchaseInvoice(client, invoiceCode, "Purchase Invoice", purchaseOrderSkuList, promotionDetails, eurToUsd); + pv.toExcelFile(newInvoice); + return new InvoiceMetaData(filename,invoiceCode, pv.client().getInternalCode(), pv.client().getInvoiceEntity(), ""); + } @Override public byte[] getInvoiceByte(String invoiceCode) throws IOException { diff --git a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml index a5ab50539..38df8da3a 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml +++ b/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml @@ -224,6 +224,7 @@ jeecg: purchaseTemplatePath: /wia/files/Purchase_Invoice_Template.xlsx # where to store generated file purchaseInvoiceDir: /wia/invoices/purchase + purchaseInvoiceTestDir: /wia/invoices/test/purchase purchaseInventoryDir: /wia/invoices/inventory # shipping invoice template @@ -235,6 +236,7 @@ jeecg: completeTemplatePath_US: /wia/files/Complete_Invoice_Template_US.xlsx # where to store generated file shippingInvoiceDir: /wia/invoices/shipping + shippingInvoiceTestDir: /wia/invoices/test/shipping shippingInvoiceDetailDir: /wia/invoices/shippingDetail shippingInvoicePdfDir: /wia/invoices/pdf/shipping shippingInvoiceDetailPdfDir: /wia/invoices/pdf/shippingDetail