package com.salesmanager.core.business.modules.order; import java.awt.Graphics2D; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; import java.util.Set; import javax.inject.Inject; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.jopendocument.dom.OOUtils; import org.jopendocument.dom.spreadsheet.Sheet; import org.jopendocument.dom.spreadsheet.SpreadSheet; import org.jopendocument.model.OpenDocument; import org.jopendocument.renderer.ODTRenderer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.itextpdf.text.Document; import com.itextpdf.text.PageSize; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfDocument; import com.itextpdf.text.pdf.PdfTemplate; import com.itextpdf.text.pdf.PdfWriter; import com.salesmanager.core.business.constants.Constants; import com.salesmanager.core.business.services.reference.country.CountryService; import com.salesmanager.core.business.services.reference.zone.ZoneService; import com.salesmanager.core.business.utils.ProductPriceUtils; import com.salesmanager.core.business.utils.ProductUtils; import com.salesmanager.core.model.merchant.MerchantStore; import com.salesmanager.core.model.order.Order; import com.salesmanager.core.model.order.OrderTotal; import com.salesmanager.core.model.order.orderproduct.OrderProduct; import com.salesmanager.core.model.reference.country.Country; import com.salesmanager.core.model.reference.language.Language; import com.salesmanager.core.model.reference.zone.Zone; public class ODSInvoiceModule implements InvoiceModule { private final static String INVOICE_TEMPLATE = "templates/invoice/Invoice"; private final static String INVOICE_TEMPLATE_EXTENSION = ".ods"; private final static String TEMP_INVOICE_SUFFIX_NAME = "_invoice.ods"; private final static int ADDRESS_ROW_START = 2; private final static int ADDRESS_ROW_END = 5; private final static int BILLTO_ROW_START = 8; private final static int BILLTO_ROW_END = 13; private final static int PRODUCT_ROW_START = 16; private static final Logger LOGGER = LoggerFactory.getLogger( ODSInvoiceModule.class ); @Inject private ZoneService zoneService; @Inject private CountryService countryService; @Inject private ProductPriceUtils priceUtil; @Override public ByteArrayOutputStream createInvoice(MerchantStore store, Order order, Language language) throws Exception { List<Zone> zones = zoneService.getZones(store.getCountry(), language); Map<String,Country> countries = countryService.getCountriesMap(language); //get default template String template = new StringBuilder().append(INVOICE_TEMPLATE).append("_").append(language.getCode().toLowerCase()).append(INVOICE_TEMPLATE_EXTENSION).toString(); //try by language InputStream is = null; try { is = getClass().getClassLoader().getResourceAsStream(template); } catch (Exception e) { LOGGER.warn("Cannot open template " + template); throw new Exception("Cannot open " + template); } if(is==null) { try { is = getClass().getClassLoader().getResourceAsStream(new StringBuilder().append(INVOICE_TEMPLATE).append(INVOICE_TEMPLATE_EXTENSION).toString()); } catch (Exception e) { LOGGER.warn("Cannot open template " + template); throw new Exception("Cannot open " + new StringBuilder().append(INVOICE_TEMPLATE).append(INVOICE_TEMPLATE_EXTENSION).toString()); } } if(is==null) { LOGGER.warn("Cannot open template " + template); throw new Exception("Cannot open " + new StringBuilder().append(INVOICE_TEMPLATE).append(INVOICE_TEMPLATE_EXTENSION).toString()); } File file = new File(order.getId() + "_working"); OutputStream os = new FileOutputStream(file); IOUtils.copy(is, os); os.close(); //File file = new File(resource.toURI().toURL()); Sheet sheet = SpreadSheet.createFromFile(file).getSheet(0); //Store name sheet.setValueAt(store.getStorename(), 0, 0); //Address //count store address cell int storeAddressCell = ADDRESS_ROW_START; Map<String,Zone> zns = zoneService.getZones(language); //3 StringBuilder storeAddress = null; if(!StringUtils.isBlank(store.getStoreaddress())) { storeAddress = new StringBuilder(); storeAddress.append(store.getStoreaddress()); } if(!StringUtils.isBlank(store.getStorecity())) { if(storeAddress==null) { storeAddress = new StringBuilder(); } else { storeAddress.append(", "); } storeAddress.append(store.getStorecity()); } if(storeAddress!=null) { sheet.setValueAt(storeAddress.toString(), 0, storeAddressCell); storeAddressCell ++; } //4 StringBuilder storeProvince = null; if(store.getZone()!=null) { storeProvince = new StringBuilder(); for(Zone z : zones) { if(z.getCode().equals(store.getZone().getCode())) { storeProvince.append(z.getName()); break; } } } else { if(!StringUtils.isBlank(store.getStorestateprovince())) { storeProvince = new StringBuilder(); storeProvince.append(store.getStorestateprovince()); } } if(store.getCountry()!=null) { if(storeProvince==null) { storeProvince = new StringBuilder(); } else { storeProvince.append(", "); } Country c = countries.get(store.getCountry().getIsoCode()); if(c!=null) { storeProvince.append(c.getName()); } else { storeProvince.append(store.getCountry().getIsoCode()); } } if(storeProvince!=null) { sheet.setValueAt(storeProvince.toString(), 0, storeAddressCell); storeAddressCell ++; } //5 if(!StringUtils.isBlank(store.getStorepostalcode())) { sheet.setValueAt(store.getStorepostalcode(), 0, storeAddressCell); storeAddressCell ++; } //6 if(!StringUtils.isBlank(store.getStorephone())) { sheet.setValueAt(store.getStorephone(), 0, storeAddressCell); } //delete address blank lines for(int i = storeAddressCell; i<ADDRESS_ROW_END; i++) { sheet.setValueAt("", 0, i); } //invoice date SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); sheet.setValueAt(format.format(order.getDatePurchased()), 3, 2); //invoice number sheet.setValueAt(order.getId(), 3, 3); //bill to //count bill to address cell int billToCell = BILLTO_ROW_START; if(!StringUtils.isBlank(order.getBilling().getFirstName())) { StringBuilder nm = new StringBuilder(); nm.append(order.getBilling().getFirstName()).append(" ").append(order.getBilling().getLastName()); sheet.setValueAt(nm.toString(), 0, billToCell); billToCell ++; } //9 if(!StringUtils.isBlank(order.getBilling().getCompany())) { sheet.setValueAt(order.getBilling().getCompany(), 0, billToCell); billToCell ++; } //10 StringBuilder billToAddress = null; if(!StringUtils.isBlank(order.getBilling().getAddress())) { billToAddress = new StringBuilder(); billToAddress.append(order.getBilling().getAddress()); } if(!StringUtils.isBlank(order.getBilling().getCity())) { if(billToAddress==null) { billToAddress = new StringBuilder(); } else { billToAddress.append(", "); } billToAddress.append(order.getBilling().getCity()); } if(billToAddress!=null) { sheet.setValueAt(billToAddress.toString(), 0, billToCell); billToCell ++; } //11 StringBuilder billToProvince = null; if(order.getBilling().getZone()!=null) { billToProvince = new StringBuilder(); Zone billingZone = zns.get(order.getBilling().getZone().getCode()); if(billingZone!=null) { billToProvince.append(billingZone.getName()); } } else { if(!StringUtils.isBlank(order.getBilling().getState())) { billToProvince = new StringBuilder(); billToProvince.append(order.getBilling().getState()); } } if(order.getBilling().getCountry()!=null) { if(billToProvince==null) { billToProvince = new StringBuilder(); } else { billToProvince.append(", "); } Country c = countries.get(order.getBilling().getCountry().getIsoCode()); if(c!=null) { billToProvince.append(c.getName()); } else { billToProvince.append(order.getBilling().getCountry().getIsoCode()); } } if(billToProvince!=null) { sheet.setValueAt(billToProvince.toString(), 0, billToCell); billToCell ++; } //12 if(!StringUtils.isBlank(order.getBilling().getPostalCode())) { billToCell ++; sheet.setValueAt(order.getBilling().getPostalCode(), 0, billToCell); billToCell ++; } //13 if(!StringUtils.isBlank(order.getBilling().getTelephone())) { sheet.setValueAt(order.getBilling().getTelephone(), 0, billToCell); } //delete address blank lines for(int i = billToCell; i<BILLTO_ROW_END; i++) { sheet.setValueAt("", 0, i); } //products Set<OrderProduct> orderProducts = order.getOrderProducts(); int productCell = PRODUCT_ROW_START; for(OrderProduct orderProduct : orderProducts) { String orderProductName = ProductUtils.buildOrderProductDisplayName(orderProduct); sheet.setValueAt(orderProductName.toString(), 0, productCell); int quantity = orderProduct.getProductQuantity(); sheet.setValueAt(quantity, 1, productCell); String amount = priceUtil.getStoreFormatedAmountWithCurrency(store, orderProduct.getOneTimeCharge()); sheet.setValueAt(amount, 2, productCell); String t = priceUtil.getStoreFormatedAmountWithCurrency(store, priceUtil.getOrderProductTotalPrice(store, orderProduct)); sheet.setValueAt(t, 3, productCell); productCell++; } //print totals productCell++; Set<OrderTotal> totals = order.getOrderTotal(); for(OrderTotal orderTotal : totals) { String totalName = orderTotal.getText(); if(totalName.contains(".")) { totalName = orderTotal.getTitle(); } String totalValue = priceUtil.getStoreFormatedAmountWithCurrency(store,orderTotal.getValue()); sheet.setValueAt(totalName, 2, productCell); sheet.setValueAt(totalValue, 3, productCell); productCell++; } //sheet.getCellAt(0, 0).setImage(arg0) //sheet.getCellAt(0, 0).setStyleName(arg0) //sheet.getCellAt(0, 0).getStyle(). //generate invoice file StringBuilder tempInvoiceName = new StringBuilder(); tempInvoiceName.append(order.getId()).append(TEMP_INVOICE_SUFFIX_NAME); File outputFile = new File(tempInvoiceName.toString()); OOUtils.open(sheet.getSpreadSheet().saveAs(outputFile)); final OpenDocument doc = new OpenDocument(); doc.loadFrom(tempInvoiceName.toString()); // Open the PDF document Document document = new Document(PageSize.A4); //File outFile = new File("invoice.pdf"); PdfDocument pdf = new PdfDocument(); document.addDocListener(pdf); //FileOutputStream fileOutputStream = new FileOutputStream(outFile); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PdfWriter writer = PdfWriter.getInstance(pdf, outputStream); pdf.addWriter(writer); document.open(); // Create a template and a Graphics2D object Rectangle pageSize = document.getPageSize(); int w = (int) (pageSize.getWidth() * 0.9); int h = (int) (pageSize.getHeight() * 0.95); PdfContentByte cb = writer.getDirectContent(); PdfTemplate tp = cb.createTemplate(w, h); Graphics2D g2 = tp.createPrinterGraphics(w, h, null); // If you want to prevent copy/paste, you can use // g2 = tp.createGraphicsShapes(w, h, true, 0.9f); tp.setWidth(w); tp.setHeight(h); // Configure the renderer ODTRenderer renderer = new ODTRenderer(doc); renderer.setIgnoreMargins(true); renderer.setPaintMaxResolution(true); // Scale the renderer to fit width renderer.setResizeFactor(renderer.getPrintWidth() / w); // Render renderer.paintComponent(g2); g2.dispose(); // Add our spreadsheet in the middle of the page float offsetX = (float) ((pageSize.getWidth() - w) / 2); float offsetY = (float) ((pageSize.getHeight() - h) / 2); cb.addTemplate(tp, offsetX, offsetY); // Close the PDF document document.close(); outputFile.delete();//remove temp file file.delete();//remove spreadsheet file is.close(); return outputStream; } }