Subversion Repositories SmartDukaan

Rev

Rev 12653 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.support.controllers;


import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import in.shop2020.config.ConfigException;
import in.shop2020.logistics.DeliveryType;
import in.shop2020.logistics.LogisticsServiceException;
import in.shop2020.logistics.PickUpType;
import in.shop2020.logistics.PickupStore;
import in.shop2020.logistics.Provider;
import in.shop2020.logistics.ProviderDetails;
import in.shop2020.model.v1.catalog.CatalogService;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.ItemType;
import in.shop2020.model.v1.inventory.BillingType;
import in.shop2020.model.v1.inventory.InventoryService;
import in.shop2020.model.v1.inventory.InventoryServiceException;
import in.shop2020.model.v1.inventory.Warehouse;
import in.shop2020.model.v1.order.AmazonOrder;
import in.shop2020.model.v1.order.Attribute;
import in.shop2020.model.v1.order.EbayOrder;
import in.shop2020.model.v1.order.FlipkartOrder;
import in.shop2020.model.v1.order.LineItem;
import in.shop2020.model.v1.order.OrderSource;
import in.shop2020.model.v1.order.OrderStatus;
import in.shop2020.model.v1.order.OrderType;
import in.shop2020.model.v1.order.ProductCondition;
import in.shop2020.model.v1.order.SnapdealOrder;
import in.shop2020.model.v1.order.TaxType;
import in.shop2020.model.v1.order.TransactionService;
import in.shop2020.support.utils.ReportsUtils;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.thrift.clients.InventoryClient;
import in.shop2020.thrift.clients.LogisticsClient;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.thrift.clients.config.ConfigClient;
import in.shop2020.model.v1.order.Order;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ibm.icu.text.RuleBasedNumberFormat;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.FontFactoryImp;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class BulkOrderBillingController extends ActionSupport implements ServletResponseAware, ServletRequestAware{

        private HttpServletRequest request;
        private HttpSession session;
        protected HttpServletResponse response;

        private File bulkBillingFile;
        private String errorMsg="";
        private String successMsg="";
        private String fileNameVal;
        private String orderIds;

        private String oneOrderId;

        private long singleTransactionId = 0l;
        private long singleUserId = 0l;

        private Map<Long, List<String>> orderImeiListMap = new HashMap<Long, List<String>>(); 

        private static Logger logger = LoggerFactory.getLogger(BulkOrderBillingController.class);


        @Override
        public void setServletRequest(HttpServletRequest request) {
                // TODO Auto-generated method stub
                this.request = request;
                this.session = request.getSession();    
        }

        public void setServletResponse(HttpServletResponse response) {
                this.response = response;
        }

        public String index() {
                if(!ReportsUtils.canAccessReport((Long)session.getAttribute(ReportsUtils.ROLE), request.getServletPath()))
                        return "authfail";
                return "bulk-order-billing";
        }

        public String create(){

                File fileToCreate = null;
                List<Long> orderIdList = new ArrayList<Long>();
                Map<Long, Order> ordersMap = new HashMap<Long, Order>();
                Map<Long, Map<Long, String>> orderItemsMap = new HashMap<Long, Map<Long, String>>();
                Map<Long, Boolean> billingLeftOrderIdMap = new HashMap<Long, Boolean>();
                Map<Long, Integer> orderBillingTypeMap = new HashMap<Long, Integer>();
                TransactionClient txnClient = null;
                CatalogClient catalogClient = null;
                InventoryClient inventoryClient = null;
                try {
                        txnClient = new TransactionClient();
                        catalogClient = new CatalogClient();
                        inventoryClient = new InventoryClient();
                } catch (TTransportException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                }

                if(bulkBillingFile!=null & fileNameVal !=null && !fileNameVal.isEmpty()){
                        logger.info("File Name "+bulkBillingFile.getName());
                        System.out.println("File Name "+bulkBillingFile.getName());

                        logger.info("File Name Value "+fileNameVal);
                        System.out.println("File Name Value "+fileNameVal);
                        String fileName = fileNameVal;

                        try {
                                if(!fileName.substring(fileName.lastIndexOf(".")+1).equalsIgnoreCase("txt")){
                                        throw new Exception("Not Again! File is not in expected TXT Format");
                                }
                                fileToCreate = new File("/tmp/", fileName);

                                FileUtils.copyFile(this.bulkBillingFile, fileToCreate);
                        } catch (Exception e) {
                                logger.error("Hurray!! Error while writing file used to the local file system", e);
                                errorMsg = e.getMessage();
                                return "bulk-order-billing";
                        }

                }
                else {
                        errorMsg = errorMsg + "<br>Folk, No File Uploaded or file name is blank";
                }
                if(fileToCreate==null){
                        errorMsg = errorMsg +" <br> No File to read";
                        return "bulk-order-billing";
                }

                if(orderIds==null || orderIds.trim().isEmpty() || orderIds.trim().length()==0){
                        errorMsg = errorMsg +" <br> Order Ids ";
                } else {
                        if(orderIds.contains(",")){
                                for(String s: orderIds.split(",")){
                                        orderIdList.add(Long.parseLong(s.trim()));
                                }
                        }else{
                                orderIdList.add(Long.parseLong(orderIds.trim()));
                        }
                }

                TransactionService.Client tClient = txnClient.getClient();
                InventoryService.Client iClient = inventoryClient.getClient();

                try{
                        List<Order> ordersList = tClient.getOrderList(orderIdList);
                        if(ordersList!=null && ordersList.size()>0){
                                long transactionId = ordersList.get(0).getTransactionId();
                                if(ordersList.size()>1){
                                        for (Order order: ordersList){
                                                if(transactionId== order.getTransactionId()){
                                                        List<Attribute> attrList = new ArrayList<Attribute>();
                                                        Attribute attr1 = new Attribute();
                                                        attr1.setName("Single Invoice");
                                                        attr1.setValue("true");
                                                        attrList.add(attr1);

                                                        ordersMap.put(order.getId(), order);

                                                        if(!tClient.isAlive()){
                                                                tClient = txnClient.getClient();
                                                        }
                                                        tClient.setOrderAttributes(order.getId(), attrList);

                                                        if(!iClient.isAlive()){
                                                                iClient = inventoryClient.getClient();
                                                        }

                                                        orderBillingTypeMap.put(order.getId(), iClient.getWarehouse(order.getWarehouse_id()).getBillingType().getValue());
                                                        singleTransactionId = transactionId;
                                                        singleUserId = order.getCustomer_id();
                                                } else {
                                                        billingLeftOrderIdMap.put(order.getId(), Boolean.TRUE);
                                                }
                                        }
                                } else {
                                        ordersMap.put(ordersList.get(0).getId(), ordersList.get(0));
                                        
                                        List<Attribute> attrList = new ArrayList<Attribute>();
                                        Attribute attr1 = new Attribute();
                                        attr1.setName("Single Invoice");
                                        attr1.setValue("true");
                                        attrList.add(attr1);

                                        if(!tClient.isAlive()){
                                                tClient = txnClient.getClient();
                                        }
                                        tClient.setOrderAttributes(ordersList.get(0).getId(), attrList);

                                        if(!iClient.isAlive()){
                                                iClient = inventoryClient.getClient();
                                        }
                                        singleTransactionId = transactionId;
                                        singleUserId = ordersList.get(0).getCustomer_id();
                                        orderBillingTypeMap.put(ordersList.get(0).getId(), iClient.getWarehouse(ordersList.get(0).getWarehouse_id()).getBillingType().getValue());
                                }
                        } else {
                                return "bulk-order-billing";
                        }

                } catch(Exception e){
                        e.printStackTrace();
                }

                CatalogService.Client cClient = catalogClient.getClient();

                
                try{
                        if(ordersMap!=null && ordersMap.size()>0){
                                for(Long orderId: ordersMap.keySet()){
                                        Order order = ordersMap.get(orderId);
                                        LineItem lineItem = order.getLineitems().get(0);
                                        if(!cClient.isAlive()){
                                                cClient = catalogClient.getClient();
                                        }
                                        Item orderItem = cClient.getItem(lineItem.getItem_id());
                                        Map<Long, String> itemTypeMap = new HashMap<Long, String>();
                                        if(orderItem.getType()==ItemType.NON_SERIALIZED){
                                                itemTypeMap.put(orderItem.getId(), "NON_SERIALIZED");
                                        } else {
                                                itemTypeMap.put(orderItem.getId(), "SERIALIZED");
                                        }
                                        orderItemsMap.put(orderId, itemTypeMap);
                                }
                        }
                } catch(Exception e){
                        e.printStackTrace();
                }

                Map<Long,List<String>> serialNumbersMap = new HashMap<Long, List<String>>();
                Map<Long,List<String>> itemNumbersMap = new HashMap<Long, List<String>>();
                Map<Long,Long> freebieWarehouseIdMap = new HashMap<Long,Long>();
                if(fileToCreate.isFile()){
                        try{
                                BufferedReader br = new BufferedReader(new FileReader(fileToCreate));
                                long line = 1;
                                String strLine;
                                String[] values;
                                

                                while((strLine = br.readLine())!=null){
                                        if(line==1){
                                                values = strLine.split("\t");                                           
                                                if(values.length !=4){
                                                        errorMsg = errorMsg + " File contains Inappropriate Content ";
                                                        addActionError(errorMsg);
                                                        return create();
                                                }
                                                line++;
                                                continue;
                                        }
                                        values = strLine.split("\t");
                                        logger.info("Row No "+line);
                                        System.out.print("Row No "+line);
                                        for(String s : values){
                                                logger.info(s);
                                                System.out.print(s);
                                        }
                                        if(!tClient.isAlive()){
                                                tClient = txnClient.getClient();
                                        }

                                        if(values[0]=="")
                                                continue;
                                        
                                        long ordId= Long.parseLong(values[0]);
                                        if(billingLeftOrderIdMap.containsKey(ordId)){
                                                line++;
                                                continue;
                                        }
                                        
                                        List<String> serialNumbers = null;
                                        List<String> itemNumbers = null;
                                        Order order = ordersMap.get(ordId);
                                        if(order.isSetFreebieItemId()){
                                                if(!freebieWarehouseIdMap.containsKey(ordId)){
                                                        freebieWarehouseIdMap.put(ordId, Long.parseLong(values[3]));
                                                }
                                        } else{
                                                if(!freebieWarehouseIdMap.containsKey(ordId)){
                                                        freebieWarehouseIdMap.put(ordId, 0l);
                                                }
                                        }
                                        if("SERIALIZED".equalsIgnoreCase(orderItemsMap.get(order.getId()).get(order.getLineitems().get(0).getItem_id()))){
                                                if(serialNumbersMap.containsKey(ordId)){
                                                        serialNumbers = serialNumbersMap.get(ordId);
                                                        serialNumbers.add(values[2]);
                                                        serialNumbersMap.put(ordId, serialNumbers);
                                                }else{
                                                        serialNumbers = new ArrayList<String>();
                                                        serialNumbers.add(values[2]);
                                                        serialNumbersMap.put(ordId, serialNumbers);
                                                }
                                                if(itemNumbersMap.containsKey(ordId)){
                                                        itemNumbers = itemNumbersMap.get(ordId);
                                                        itemNumbers.add(values[1]);
                                                        itemNumbersMap.put(ordId, itemNumbers);
                                                }else{
                                                        itemNumbers = new ArrayList<String>();
                                                        itemNumbers.add(values[1]);
                                                        itemNumbersMap.put(ordId, itemNumbers);
                                                }
                                                
                                        } else {
                                                if(itemNumbersMap.containsKey(ordId)){
                                                        itemNumbers = itemNumbersMap.get(ordId);
                                                        itemNumbers.add(values[1]);
                                                        itemNumbersMap.put(ordId, itemNumbers);
                                                }else{
                                                        itemNumbers = new ArrayList<String>();
                                                        itemNumbers.add(values[1]);
                                                        itemNumbersMap.put(ordId, itemNumbers);
                                                }
                                        }
                                        /*try{
                                                tClient.addBillingDetails(order.getId(), null, serialNumbers, itemNumbers, Long.parseLong(values[3]), "mp-mmx-admin", (long)(Math.random()*Math.pow(10.0, 7)), orderBillingTypeMap.get(order.getId()), order.getFulfilmentWarehouseId(), false);
                                        } catch(Exception e1){
                                                if(serialNumbers.size()>0){
                                                        if(orderImeiListMap.containsKey(order.getId())){
                                                                List<String> imeiList = orderImeiListMap.get(order.getId());
                                                                imeiList.addAll(serialNumbers);
                                                                orderImeiListMap.put(order.getId(), imeiList);
                                                        }
                                                        else{
                                                                orderImeiListMap.put(order.getId(), serialNumbers);
                                                        }
                                                }

                                                if(itemNumbers.size()>0 && serialNumbers.size()==0){
                                                        if(orderImeiListMap.containsKey(order.getId())){
                                                                List<String> imeiList = orderImeiListMap.get(order.getId());
                                                                imeiList.addAll(itemNumbers);
                                                                orderImeiListMap.put(order.getId(), imeiList);
                                                        }
                                                        else{
                                                                orderImeiListMap.put(order.getId(), itemNumbers);
                                                        }
                                                }
                                                line++;
                                                continue;

                                        }*/

                                        line++;
                                }

                                /*if(orderImeiListMap!=null && orderImeiListMap.size()>0){
                                        for(Long orderId : orderImeiListMap.keySet()){
                                                errorMsg = errorMsg + "<br> Error Occured for Order Id: "+ orderId ; 
                                                for(String imei : orderImeiListMap.get(orderId)){
                                                        errorMsg = errorMsg + " Imei :" + imei +" ";
                                                }
                                        }
                                }*/
                                
                                for(Order order: ordersMap.values()){
                                        try{
                                                if("SERIALIZED".equalsIgnoreCase(orderItemsMap.get(order.getId()).get(order.getLineitems().get(0).getItem_id()))){
                                                        tClient.addBillingDetails(order.getId(), null, serialNumbersMap.get(order.getId()), itemNumbersMap.get(order.getId()), freebieWarehouseIdMap.get(order.getId()), "mp-mmx-admin", (long)(Math.random()*Math.pow(10.0, 7)), orderBillingTypeMap.get(order.getId()), order.getFulfilmentWarehouseId(), false);
                                                }else{
                                                        tClient.addBillingDetails(order.getId(), null, new ArrayList<String>(), itemNumbersMap.get(order.getId()), freebieWarehouseIdMap.get(order.getId()), "mp-mmx-admin", (long)(Math.random()*Math.pow(10.0, 7)), orderBillingTypeMap.get(order.getId()), order.getFulfilmentWarehouseId(), false);
                                                }
                                                
                                        } catch(Exception e1){
                                                errorMsg = errorMsg+ "<br>" + "Order Id :" +order.getId()+ " Got Some Error while billing";
                                                logger.error("Order Id :" +order.getId()+ " Got Some Error while billing", e1);
                                                continue;
                                        }
                                }

                                if(billingLeftOrderIdMap!=null && billingLeftOrderIdMap.size()>0){
                                        errorMsg = errorMsg+ "<br>" + "These orders have been left because does not have same transaction id ";
                                        for(Long orderId : billingLeftOrderIdMap.keySet()){
                                                errorMsg = errorMsg+ orderId+ " ";
                                        }
                                }

                                
                                
                                
                        } catch(Exception e){
                                logger.error(errorMsg, e);
                        }
                }

                if(singleTransactionId>0 && singleUserId>0){
                        try{
                                if(!tClient.isAlive()){
                                        tClient = txnClient.getClient();
                                }
                                tClient.addInvoiceDetailsToOrders(singleTransactionId, singleUserId);
                        } catch(Exception e){
                                errorMsg = errorMsg + "<br>Error while generating invoice number for transaction";
                                logger.error(errorMsg, e);
                        }
                }

                successMsg="All Orders have been billed sucessfully and also Invoice Number genrated";
                return "bulk-order-billing";
        }

        public void downloadInvoice(){
                TransactionClient txnClient = null;
                try{
                        txnClient = new TransactionClient();
                        TransactionService.Client tClient = txnClient.getClient();
                        Order singleOrder = null;
                        if(oneOrderId!=null && StringUtils.isNumeric(oneOrderId)){
                                singleOrder = tClient.getOrder(Long.parseLong(oneOrderId));
                                if(singleOrder.getSource()!=OrderSource.WEBSITE.getValue()){
                                        errorMsg = "Order source is not Website. Can't Bill using this functionality";
                                        return;
                                }
                                if(!singleOrder.isSetInvoice_number()){
                                        errorMsg = "Order has not been billed. Can't generate invoice";
                                        return;
                                }
                        }
                        ByteArrayOutputStream baos = null;

                        InvoiceGenerationService invoiceGenerationService = new InvoiceGenerationService();
                        baos = invoiceGenerationService.generateInvoice(singleOrder.getTransactionId(), singleOrder.getCustomer_id(), true, false);

                        logger.info("After this piece of code");
                        response.setContentType("application/pdf");
                        response.setHeader("Content-disposition", "inline; filename=invoice-"+singleOrder.getTransactionId()+".pdf" );

                        ServletOutputStream sos = response.getOutputStream();
                        sos.write(baos.toByteArray());
                        sos.flush();
                }
                catch(Exception e){
                        logger.error("Unablke to stream",e);
                        e.printStackTrace();
                }
                
        }

        public File getBulkBillingFile() {
                return bulkBillingFile;
        }

        public void setBulkBillingFile(File bulkBillingFile) {
                this.bulkBillingFile = bulkBillingFile;
        }

        public String getErrorMsg() {
                return errorMsg;
        }

        public void setErrorMsg(String errorMsg) {
                this.errorMsg = errorMsg;
        }

        public String getSuccessMsg() {
                return successMsg;
        }

        public void setSuccessMsg(String successMsg) {
                this.successMsg = successMsg;
        }

        public String getFileNameVal() {
                return fileNameVal;
        }

        public void setFileNameVal(String fileNameVal) {
                this.fileNameVal = fileNameVal;
        }

        public String getOrderIds() {
                return orderIds;
        }

        public void setOrderIds(String orderIds) {
                this.orderIds = orderIds;
        }

        public static Warehouse getWarehouse(long warehouseId) {
                try{
                        InventoryClient catalogServiceClient = new InventoryClient();
                        InventoryService.Client catalogClient = catalogServiceClient.getClient();
                        return catalogClient.getWarehouse(warehouseId);
                }catch(Exception e){
                        e.printStackTrace();
                }
                return null;
        }

        public String getOneOrderId() {
                return oneOrderId;
        }

        public void setOneOrderId(String oneOrderId) {
                this.oneOrderId = oneOrderId;
        }
}


class InvoiceGenerationService {

        private static Logger logger = LoggerFactory.getLogger(InvoiceGenerationService.class);

        private TransactionClient tsc = null;
        private InventoryClient csc = null;
        private LogisticsClient lsc = null;
        private CatalogClient ctsc = null;

        private static Locale indianLocale = new Locale("en", "IN");
        private DecimalFormat amountFormat = new DecimalFormat("#,##0.00");

        //Start:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
        private static final Font helvetica6 = FontFactory.getFont(FontFactory.HELVETICA, 6);
        //End:-Added By Manish Sharma for FedEx Integration  - Shipment Creation on 21-Aug-2013
        private static final Font helvetica8 = FontFactory.getFont(FontFactory.HELVETICA, 8);
        /*private static final Font helvetica10 = FontFactory.getFont(FontFactory.HELVETICA, 10);
        private static final Font helvetica12 = FontFactory.getFont(FontFactory.HELVETICA, 12);*/
        private static final Font helvetica16 = FontFactory.getFont(FontFactory.HELVETICA, 16);
        //private static final Font helvetica22 = FontFactory.getFont(FontFactory.HELVETICA, 22);

        private static final Font helveticaBold8 = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 8);
        private static final Font helveticaBold12 = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12);

        private static final String delhiPincodePrefix = "11";
        private static final String[] maharashtraPincodePrefix = {"40", "41", "42", "43", "44"};

        public InvoiceGenerationService() {
                try {
                        tsc = new TransactionClient();
                        csc = new InventoryClient();
                        lsc = new LogisticsClient();
                        ctsc = new CatalogClient();
                } catch (Exception e) {
                        logger.error("Error while instantiating thrift clients.", e);
                }
        }

        public ByteArrayOutputStream generateInvoice(long transactionId, long customerId, boolean withBill, boolean printAll) {
                ByteArrayOutputStream baosPDF = null;
                in.shop2020.model.v1.order.TransactionService.Client tclient = tsc.getClient();
                

                try {
                        baosPDF = new ByteArrayOutputStream();

                        Document document = new Document();
                        PdfWriter.getInstance(document, baosPDF);
                        document.addAuthor("shop2020");
                        //document.addTitle("Invoice No: " + order.getInvoice_number());
                        document.open();

                        List<Order> orders = new ArrayList<Order>();

                        if(!tclient.isAlive()){
                                tclient = tsc.getClient();
                        }

                        List<Order> ordersByTransaction = tclient.getOrdersForTransaction(transactionId, customerId);
                        for(Order order: ordersByTransaction){
                                if(order.isSetInvoice_number()){
                                        orders.add(order);
                                }
                        }



                        PdfPTable taxTable = getTaxCumRetailInvoiceTable(orders);
                        taxTable.setWidthPercentage(90.0f);
                        taxTable.setSpacingAfter(5.0f);


                        PdfPTable orderItemsDetailTable = new PdfPTable(1);
                        orderItemsDetailTable.setWidthPercentage(90.0f);
                        orderItemsDetailTable.setSpacingBefore(5.0f);
                        orderItemsDetailTable.addCell(new Phrase("Order Reference Ids :", helveticaBold8));
                        StringBuffer sbOrders = new StringBuffer();

                        for(Order o1 : orders){
                                sbOrders.append(o1.getId()+",");
                        }

                        
                        String orderIds = sbOrders.toString();
                        orderIds = orderIds.substring(0, orderIds.length()-1);

                        orderItemsDetailTable.addCell(new Phrase(orderIds.toString(), helvetica8));
                        orderItemsDetailTable.addCell(new Phrase("IMEI Details :", helveticaBold8));

                        StringBuffer sbImeis = new StringBuffer();

                        for(Order o1 : orders){
                                sbImeis.append(o1.getLineitems().get(0).getSerial_number()+",");
                        }

                        String imeis = sbImeis.toString();
                        imeis = imeis.substring(0, imeis.length()-1);

                        orderItemsDetailTable.addCell(new Phrase(imeis, helvetica8));




                        document.add(taxTable);
                        document.add(new DottedLineSeparator());
                        document.add(orderItemsDetailTable);



                        document.close();
                        baosPDF.close();
                        // Adding facility to store the bill on the local directory. This will happen for only for Mahipalpur warehouse.
                        if(withBill && !printAll){
                                /*String strOrderId = StringUtils.repeat("0", 10-String.valueOf(transactionId).length()) + transactionId;  
                                String dirPath = "/SaholicInvoices" + File.separator + strOrderId.substring(0, 2) + File.separator + strOrderId.substring(2, 4) + File.separator + strOrderId.substring(4, 6);
                                String filename = dirPath + File.separator + transactionId + ".pdf";*/
                                String  filename = "/tmp/"+"invoice-"+transactionId+".pdf";
                                /*File dirFile = new File(dirPath);
                                if(!dirFile.exists()){
                                        dirFile.mkdirs();
                                }*/
                                File f = new File(filename);
                                FileOutputStream fos = new FileOutputStream(f);
                                baosPDF.writeTo(fos);
                        }
                } catch (Exception e) {
                        logger.error("Error while generating Invoice: ", e);
                }
                return baosPDF;
        }



        private void addLogoTable(PdfPTable logoTable,Order order) {
                logoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                logoTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
                logoTable.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);

                PdfPCell logoCell;
                String logoPath;

                if(order.getSource() == OrderSource.STORE.getValue()){
                        logoCell = new PdfPCell(new Phrase(""));

                }else{
                        logoPath = InvoiceGenerationService.class.getResource("/logo.jpg").getPath();

                        try {
                                logoCell = new PdfPCell(Image.getInstance(logoPath), false);
                        } catch (Exception e) {
                                //Too Many exceptions to catch here: BadElementException, MalformedURLException and IOException
                                logger.warn("Couldn't load the Saholic logo: ", e);
                                logoCell = new PdfPCell(new Phrase("Saholic Logo"));
                        }

                }
                logoCell.setBorder(Rectangle.NO_BORDER);
                logoCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                logoTable.addCell(logoCell);
                logoTable.addCell(" ");

        }

        /*private Font getBarCodeFont(Provider provider, float barcodeFontSize) {
                String fontPath = InvoiceGenerationService.class.getResource("/" + provider.getName().toLowerCase() + "/barcode.TTF").getPath();
                FontFactoryImp ttfFontFactory = new FontFactoryImp();
                ttfFontFactory.register(fontPath, "barcode");
                Font barCodeFont = ttfFontFactory.getFont("barcode", BaseFont.CP1252, true, barcodeFontSize);
                return barCodeFont;
        }*/

        /*private PdfPCell getTitleCell() {
                PdfPCell titleCell = new PdfPCell(new Phrase("Dispatch Advice", helveticaBold12));
                titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                titleCell.setBorder(Rectangle.NO_BORDER);
                return titleCell;
        }*/

        /*private PdfPTable getProviderTable(Order order, Provider provider, Font barCodeFont) {
                PdfPTable providerInfoTable = new PdfPTable(1);
                providerInfoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                if(order.isLogisticsCod()){
                        PdfPCell deliveryTypeCell = new PdfPCell(new Phrase("COD   ", helvetica22));
                        deliveryTypeCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                        deliveryTypeCell.setBorder(Rectangle.NO_BORDER);
                        providerInfoTable.addCell(deliveryTypeCell);
                }


                PdfPCell providerNameCell = new PdfPCell(new Phrase(provider.getName(), helveticaBold12));
                providerNameCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                providerNameCell.setBorder(Rectangle.NO_BORDER);
                PdfPCell formIdCell= null;
                if(order.getLogistics_provider_id()==7L){
                        if(order.isCod()){
                                formIdCell = new PdfPCell(new Paragraph(order.getAirwaybill_no()+" Form id-0305", helvetica6));
                        }
                        else{
                                formIdCell = new PdfPCell(new Paragraph(order.getAirwaybill_no()+" Form id-0467", helvetica6));
                        }
                        formIdCell.setPaddingTop(1.0f);
                        formIdCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                        formIdCell.setBorder(Rectangle.NO_BORDER);
                }


                PdfPCell awbNumberCell= null;
                String fedexPackageBarcode = "";
                if(order.getLogistics_provider_id()!=7L){
                        awbNumberCell = new PdfPCell(new Paragraph("*" + order.getAirwaybill_no() + "*", barCodeFont));
                        awbNumberCell.setPaddingTop(20.0f);
                }
                else{
                        in.shop2020.model.v1.order.TransactionService.Client tclient = tsc.getClient();
                        try {
                                fedexPackageBarcode = tclient.getOrderAttributeValue(order.getId(), "FedEx_Package_BarCode");
                        } catch (TException e1) {
                                logger.error("Error while getting the provider information.", e1);
                        }
                        awbNumberCell = new PdfPCell(new Paragraph(" ", helvetica6));
                }
                awbNumberCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                awbNumberCell.setBorder(Rectangle.NO_BORDER);

                providerInfoTable.addCell(providerNameCell);
                if(formIdCell != null){
                        providerInfoTable.addCell(formIdCell);
                }
                //End:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
                if(order.getLogistics_provider_id()==7L){
                        generateBarcode(fedexPackageBarcode, "fedex_"+order.getId());

                        Image barcodeImage=null;
                        try {
                                barcodeImage = Image.getInstance("/tmp/"+"fedex_"+order.getId()+".png");
                        } catch (Exception e) {
                                logger.error("Exception during getting Barcode Image for Fedex : ", e);
                        }
                        providerInfoTable.addCell(barcodeImage);
                }
                providerInfoTable.addCell(awbNumberCell);

                Warehouse warehouse = null;
                try{
                InventoryClient isc = new InventoryClient();
                warehouse = isc.getClient().getWarehouse(order.getWarehouse_id());
                } catch(Exception e) {
                    logger.error("Unable to get warehouse for id : " + order.getWarehouse_id(), e);
                    //TODO throw e;
                }
                DeliveryType dt =  DeliveryType.PREPAID;
        if (order.isLogisticsCod()) {
            dt = DeliveryType.COD;
        }
        //Start:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
        if(order.getLogistics_provider_id()!=7L){
                for (ProviderDetails detail : provider.getDetails()) {
                    if(in.shop2020.model.v1.inventory.WarehouseLocation.findByValue((int) detail.getLogisticLocation()) == warehouse.getLogisticsLocation() && detail.getDeliveryType() == dt) {
                        providerInfoTable.addCell(new Phrase("Account No : " + detail.getAccountNo(), helvetica8));
                    }
                }
        }
        else{
                providerInfoTable.addCell(new Phrase("STANDARD OVERNIGHT ", helvetica8));
        }
        //End:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
                Date awbDate;
                if(order.getBilling_timestamp() == 0){
                        awbDate = new Date();
                }else{
                        awbDate = new Date(order.getBilling_timestamp());
                }
                if(order.getLogistics_provider_id()!=7L){
                        providerInfoTable.addCell(new Phrase("AWB Date   : " + DateFormat.getDateInstance(DateFormat.MEDIUM).format(awbDate), helvetica8));
                }
                providerInfoTable.addCell(new Phrase("Weight         : " + order.getTotal_weight() + " Kg", helvetica8));
                if(order.getSource() == OrderSource.EBAY.getValue()){
                        EbayOrder ebayOrder = null;
                        try {
                                ebayOrder = tsc.getClient().getEbayOrderByOrderId(order.getId());
                        } catch (TException e) {
                                logger.error("Error while getting ebay order", e);
                        }
                        providerInfoTable.addCell(new Phrase("PaisaPayId            : " + ebayOrder.getPaisaPayId(), helvetica8));
                        providerInfoTable.addCell(new Phrase("Sales Rec Number: " + ebayOrder.getSalesRecordNumber(), helvetica8));
                }
                //Start:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
                if(order.getLogistics_provider_id()==7L){
                        providerInfoTable.addCell(new Phrase("Bill T/C Sender      "+ "Bill D/T Sender", helvetica8));
                }
                //End:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
                return providerInfoTable;
        }*/

        /*private PdfPTable getTopInvoiceTable(Order order, String tinNo){
                PdfPTable invoiceTable = new PdfPTable(new float[]{0.2f, 0.2f, 0.3f, 0.1f, 0.1f, 0.1f});
                invoiceTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

                invoiceTable.addCell(getInvoiceTableHeader(6));

                invoiceTable.addCell(new Phrase("Order No", helvetica8));
                invoiceTable.addCell(new Phrase("Paymode", helvetica8));
                invoiceTable.addCell(new Phrase("Product Name", helvetica8));
                invoiceTable.addCell(new Phrase("Quantity", helvetica8));
                invoiceTable.addCell(new Phrase("Rate", helvetica8));
                invoiceTable.addCell(new Phrase("Amount", helvetica8));
                populateTopInvoiceTable(order, invoiceTable);


                if(order.getInsurer() > 0) {
                        invoiceTable.addCell(getInsuranceCell(4));
                        invoiceTable.addCell(getPriceCell(order.getInsuranceAmount()));
                        invoiceTable.addCell(getPriceCell(order.getInsuranceAmount()));
                }

                if(order.getSource() == OrderSource.STORE.getValue()) {
                        invoiceTable.addCell(getAdvanceAmountCell(4));
                        invoiceTable.addCell(getPriceCell(order.getAdvanceAmount()));
                        invoiceTable.addCell(getPriceCell(order.getAdvanceAmount()));
                }

                invoiceTable.addCell(getTotalCell(4));      
                invoiceTable.addCell(getRupeesCell());
                invoiceTable.addCell(getTotalAmountCell(order.getTotal_amount()-order.getGvAmount()-order.getAdvanceAmount()));

                PdfPCell tinCell = new PdfPCell(new Phrase("TIN NO. " + tinNo, helvetica8));
                tinCell.setColspan(6);
                tinCell.setPadding(2);
                invoiceTable.addCell(tinCell);

                return invoiceTable;
        }*/

        /*private void populateTopInvoiceTable(Order order, PdfPTable invoiceTable) {
                List<LineItem> lineitems = order.getLineitems();
                for (LineItem lineitem : lineitems) {
                        invoiceTable.addCell(new Phrase(order.getId() + "", helvetica8));
                        if(order.getPickupStoreId() > 0 && order.isCod() == true)
                                invoiceTable.addCell(new Phrase("In-Store", helvetica8));
                        else if (order.isCod())
                                invoiceTable.addCell(new Phrase("COD", helvetica8));
                        else
                                invoiceTable.addCell(new Phrase("Prepaid", helvetica8));

                        invoiceTable.addCell(getProductNameCell(lineitem, false, order.getFreebieItemId()));

                        invoiceTable.addCell(new Phrase(lineitem.getQuantity() + "", helvetica8));

                        invoiceTable.addCell(getPriceCell(lineitem.getUnit_price()-order.getGvAmount()));

                        invoiceTable.addCell(getPriceCell(lineitem.getTotal_price()-order.getGvAmount()));
                }
        }*/

        /*private PdfPCell getAddressCell(String address) {
                Paragraph addressParagraph = new Paragraph(address, new Font(FontFamily.TIMES_ROMAN, 8f));
                PdfPCell addressCell = new PdfPCell();
                addressCell.addElement(addressParagraph);
                addressCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                addressCell.setBorder(Rectangle.NO_BORDER);
                return addressCell;
        }*/

        private PdfPTable getTaxCumRetailInvoiceTable(List<Order> orders){
                in.shop2020.model.v1.inventory.InventoryService.Client iclient = csc.getClient();
                
                String ourAddress = "";
                String tinNo = "";

                Order order = null;
                for(Order ord: orders){
                        Warehouse warehouse = null;
                        Warehouse shippingLocation = null;
                        order =ord;
                        try {
                                warehouse = iclient.getWarehouse(order.getWarehouse_id());
                                shippingLocation = BulkOrderBillingController.getWarehouse(warehouse.getShippingWarehouseId());
                                ourAddress = shippingLocation.getLocation() + "-" + shippingLocation.getPincode();
                                tinNo = shippingLocation.getTinNumber();
                        } catch (InventoryServiceException ise) {
                                logger.error("Error while getting the warehouse information.", ise);
                                return null;
                        } catch (TException te) {
                                logger.error("Error while getting some essential information from the services", te);
                                return null;
                        }
                        break;
                }

                PdfPTable taxTable = new PdfPTable(1);
                Phrase phrase = null;
                taxTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                taxTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

                PdfPTable logoTitleAndOurAddressTable = new PdfPTable(new float[]{0.4f, 0.3f, 0.3f});
                logoTitleAndOurAddressTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                logoTitleAndOurAddressTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);


                PdfPTable logoTable = new PdfPTable(2);
                addLogoTable(logoTable,order); 

                if (order.getOrderType().equals(OrderType.B2B)) {
                        phrase = new Phrase("TAX INVOICE", helveticaBold12);
                } else {
                        phrase = new Phrase("RETAIL INVOICE", helveticaBold12);
                }
                PdfPCell retailInvoiceTitleCell = new PdfPCell(phrase);
                retailInvoiceTitleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                retailInvoiceTitleCell.setBorder(Rectangle.NO_BORDER);

                Paragraph sorlAddress = new Paragraph(ourAddress + "\n Contact No.- 0120-2479977" + "\nTIN NO. " + tinNo, new Font(FontFamily.TIMES_ROMAN, 8f, Element.ALIGN_CENTER));
                PdfPCell sorlAddressCell = new PdfPCell(sorlAddress);
                sorlAddressCell.addElement(sorlAddress);
                sorlAddressCell.setHorizontalAlignment(Element.ALIGN_LEFT);

                PdfPTable customerAddress = getCustomerAddressTable(order, null, true, helvetica8, true);
                PdfPTable orderDetails = getOrderDetails(order);

                PdfPTable addrAndOrderDetailsTable = new PdfPTable(new float[]{0.5f, 0.1f, 0.4f});
                addrAndOrderDetailsTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                addrAndOrderDetailsTable.addCell(customerAddress);
                addrAndOrderDetailsTable.addCell(new Phrase(" "));
                addrAndOrderDetailsTable.addCell(orderDetails);

                boolean isVAT = isVatApplicable(order);
                PdfPTable invoiceTable = getBottomInvoiceTable(orders, isVAT);

                PdfPTable regAddAndDisCellTable = new PdfPTable(2);

                PdfPCell disclaimerCell = new PdfPCell(new Phrase("Goods once sold will not be taken back.\nAll disputes subject to Delhi Jurisdiction.\nThis is a Computer generated Invoice.", helvetica8));
                disclaimerCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                disclaimerCell.setBorder(Rectangle.NO_BORDER);

                PdfPCell regAddressCell = new PdfPCell(new Phrase(" SPICE ONLINE RETAIL PRIVATE LIMITED\n Regd. Add. 60-D, STREET NO. C-5, SAINIK FARMS,NEW DELHI-110062\n CIN: U74140DL2008PTC183856 Tel. No. 0120-2479977 E-mail. help@saholic.com Website. www.saholic.com", helvetica6));
                regAddressCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                regAddressCell.setBorder(Rectangle.NO_BORDER);
                /*SPICE ONLINE RETAIL PRIVATE LIMITED
                Regd. Add. 60-D, STREET NO. C-5, SAINIK FARMS,NEW DELHI-110062
                CIN: U74140DL2008PTC183856
                Tel. No. 0120-2479977
                E-mail. help@saholic.com
                Website. www.saholic.com*/


                logoTitleAndOurAddressTable.addCell(logoTable);
                logoTitleAndOurAddressTable.addCell(retailInvoiceTitleCell);
                logoTitleAndOurAddressTable.addCell(sorlAddress);

                regAddAndDisCellTable.addCell(disclaimerCell);
                regAddAndDisCellTable.addCell(regAddressCell);

                taxTable.addCell(logoTitleAndOurAddressTable);
                taxTable.addCell(addrAndOrderDetailsTable);
                taxTable.addCell(invoiceTable);
                taxTable.addCell(regAddAndDisCellTable);

                if(order.getProductCondition().equals(ProductCondition.BAD)){
                        PdfPCell badSaleDisclaimerCell = new PdfPCell(new Phrase(" Item(s) above are sold on as is where is basis. They " +
                                        "may be in dead/defective/damaged/refurbished/incomplete/open condition. These " +
                                        "are not returnable, exchangeable or refundable under any circumstances. No " +
                                        "warranty is assured on these items." ,
                                        new Font(FontFamily.TIMES_ROMAN, 8f)));
                        badSaleDisclaimerCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                        badSaleDisclaimerCell.setBorder(Rectangle.NO_BORDER);
                        taxTable.addCell(badSaleDisclaimerCell);
                }
                return taxTable;
        }

        private boolean isVatApplicable(Order order) {
                if(order.getWarehouse_id() == 7) {
                        if(order.getCustomer_pincode().startsWith(delhiPincodePrefix)) {
                                return true;
                        } else {
                                return false;
                        }
                } else {
                        for(int i=0; i< maharashtraPincodePrefix.length; i++) {
                                if(order.getCustomer_pincode().startsWith(maharashtraPincodePrefix[i])) {
                                        return true;
                                }
                        }
                        return false;
                }
        }

        /*private PdfPTable getFlipkartBarCodes(Order order) {
                PdfPTable flipkartTable = new PdfPTable(3);

                PdfPCell spacerCell = new PdfPCell();
                spacerCell.setBorder(Rectangle.NO_BORDER);
                spacerCell.setColspan(3);
                spacerCell.setPaddingTop(330.0f);

                String flipkartCodeFontPath = InvoiceGenerationService.class.getResource("/saholic-wn.TTF").getPath();
                FontFactoryImp ttfFontFactory = new FontFactoryImp();
                ttfFontFactory.register(flipkartCodeFontPath, "barcode");
                Font flipkartBarCodeFont = ttfFontFactory.getFont("barcode", BaseFont.CP1252, true, 20);

                String serialNumber = "0000000000";
                if(order.getLineitems().get(0).getSerial_number()!=null && !order.getLineitems().get(0).getSerial_number().isEmpty()) {
                        serialNumber = order.getLineitems().get(0).getSerial_number();
                } else if(order.getLineitems().get(0).getItem_number()!=null && !order.getLineitems().get(0).getItem_number().isEmpty()) {
                        serialNumber = order.getLineitems().get(0).getItem_number();
                }

                PdfPCell serialNumberBarCodeCell = new PdfPCell(new Paragraph("*" +  serialNumber + "*", flipkartBarCodeFont));
                serialNumberBarCodeCell.setBorder(Rectangle.TOP);
                serialNumberBarCodeCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                serialNumberBarCodeCell.setPaddingTop(11.0f);


                PdfPCell invoiceNumberBarCodeCell = new PdfPCell(new Paragraph("*" +  order.getInvoice_number() + "*", flipkartBarCodeFont));
                invoiceNumberBarCodeCell.setBorder(Rectangle.TOP);
                invoiceNumberBarCodeCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                invoiceNumberBarCodeCell.setPaddingTop(11.0f);

                double rate = order.getLineitems().get(0).getVatRate();
                double salesTax = (rate * order.getTotal_amount())/(100 + rate);
                PdfPCell vatAmtBarCodeCell = new PdfPCell(new Paragraph("*" +  amountFormat.format(salesTax) + "*", flipkartBarCodeFont));
                vatAmtBarCodeCell.setBorder(Rectangle.TOP);
                vatAmtBarCodeCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                vatAmtBarCodeCell.setPaddingTop(11.0f);

                flipkartTable.addCell(spacerCell);
                flipkartTable.addCell(serialNumberBarCodeCell);
                flipkartTable.addCell(invoiceNumberBarCodeCell);
                flipkartTable.addCell(vatAmtBarCodeCell);

                return flipkartTable;

        }*/

        private PdfPTable getCustomerAddressTable(Order order, String destCode, boolean showPaymentMode, Font font, boolean forInvoce){
                PdfPTable customerTable = new PdfPTable(1);
                customerTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                if(forInvoce || order.getPickupStoreId() == 0){
                        customerTable.addCell(new Phrase(order.getCustomer_name(), font));
                        customerTable.addCell(new Phrase(order.getCustomer_address1(), font));
                        customerTable.addCell(new Phrase(order.getCustomer_address2(), font));
                        customerTable.addCell(new Phrase(order.getCustomer_city() + "," + order.getCustomer_state(), font));
                        //Start:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
                        in.shop2020.model.v1.order.TransactionService.Client tclient = tsc.getClient();
                        if(order.getLogistics_provider_id()!=7L){
                                if(destCode != null)
                                        customerTable.addCell(new Phrase(order.getCustomer_pincode() + " - " + destCode, helvetica16));
                                else
                                        customerTable.addCell(new Phrase(order.getCustomer_pincode(), font));
                        }
                        else{
                                String fedexLocationcode = "";
                                try {
                                        fedexLocationcode = tclient.getOrderAttributeValue(order.getId(), "FedEx_Location_Code");
                                } catch (TException e1) {
                                        logger.error("Error while getting the provider information.", e1);
                                }
                                customerTable.addCell(new Phrase(order.getCustomer_pincode() + " - " + fedexLocationcode, helvetica16));
                        }
                        //Start:-Added By Manish Sharma for FedEx Integration - Shipment Creation on 21-Aug-2013
                        if(order.getCustomer_mobilenumber()!=null && !order.getCustomer_mobilenumber().isEmpty()) {
                                customerTable.addCell(new Phrase("Phone : " + (order.getCustomer_mobilenumber()== null ? "" : order.getCustomer_mobilenumber()), font));
                        }
                        
                }else{
                        try {
                                in.shop2020.logistics.LogisticsService.Client lclient = (new LogisticsClient()).getClient();
                                PickupStore store = lclient.getPickupStore(order.getPickupStoreId());
                                customerTable.addCell(new Phrase(order.getCustomer_name() + " \nc/o " + store.getName(), font));
                                customerTable.addCell(new Phrase(store.getLine1(), font));
                                customerTable.addCell(new Phrase(store.getLine2(), font));
                                customerTable.addCell(new Phrase(store.getCity() + "," + store.getState(), font));
                                if(destCode != null)
                                        customerTable.addCell(new Phrase(store.getPin() + " - " + destCode, helvetica16));
                                else
                                        customerTable.addCell(new Phrase(store.getPin(), font));
                                customerTable.addCell(new Phrase("Phone :" + store.getPhone(), font));
                                
                                
                        } catch (TException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }

                }

                if(order.getOrderType().equals(OrderType.B2B)) {
                        String tin = null;
                        in.shop2020.model.v1.order.TransactionService.Client tclient = tsc.getClient();
                        List<Attribute> attributes;
                        try {
                                attributes = tclient.getAllAttributesForOrderId(order.getId());

                                for(Attribute attribute : attributes) {
                                        if(attribute.getName().equals("tinNumber")) {
                                                tin = attribute.getValue();
                                        }
                                }
                                if (tin != null) {
                                        customerTable.addCell(new Phrase("TIN :" + tin, font));
                                }

                        } catch (Exception e) {
                                logger.error("Error while getting order attributes", e);
                        }
                }
                /*
        if(showPaymentMode){
            customerTable.addCell(new Phrase(" ", font));
            customerTable.addCell(new Phrase("Payment Mode: Prepaid", font));
        }*/
                return customerTable;
        }

        private PdfPTable getOrderDetails(Order order){
                PdfPTable orderTable = new PdfPTable(new float[]{0.4f, 0.6f});
                orderTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);

                orderTable.addCell(new Phrase("Invoice No:", helvetica8));
                orderTable.addCell(new Phrase(order.getInvoice_number(), helvetica8));

                orderTable.addCell(new Phrase("Date:", helvetica8));
                orderTable.addCell(new Phrase(DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date(order.getBilling_timestamp())), helvetica8));

                try {
                        String poRefVal = tsc.getClient().getOrderAttributeValue(order.getId(), "poRefNumber");
                        if(poRefVal!=null && poRefVal.length()>0){
                                orderTable.addCell(new Phrase("PO Ref:", helvetica8));
                                orderTable.addCell(new Phrase(poRefVal, helvetica8));
                        }
                        
                } catch (TException e) {
                        logger.error("Error while getting amazon order", e);
                }

                orderTable.addCell(new Phrase("Tax Type:", helvetica8));

                if(order.getTaxType().equals(TaxType.CFORM)) {
                        orderTable.addCell(new Phrase("CST Against CForm", helvetica8));
                } else {
                        
                        if(isVatApplicable(order)){
                                orderTable.addCell(new Phrase("VAT", helvetica8));
                        } else {
                                orderTable.addCell(new Phrase("CST", helvetica8));
                        }
                        orderTable.addCell(getVATLabelCell(isVatApplicable(order)));
                }
                return orderTable;
        }

        private PdfPTable getBottomInvoiceTable(List<Order> orders, boolean isVAT){
                PdfPTable invoiceTable = new PdfPTable(new float[]{0.1f, 0.3f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f});
                invoiceTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

                invoiceTable.addCell(getInvoiceTableHeader(8));

                invoiceTable.addCell(new Phrase("Sl. No.", helveticaBold8));
                invoiceTable.addCell(new Phrase("Description", helveticaBold8));
                invoiceTable.addCell(new Phrase("Quantity", helveticaBold8));
                invoiceTable.addCell(new Phrase("Rate (Rs)", helveticaBold8));
                invoiceTable.addCell(new Phrase("Amount (Rs)", helveticaBold8));
                invoiceTable.addCell(new Phrase("Tax Rate%", helveticaBold8));
                invoiceTable.addCell(new Phrase("Tax (Rs)", helveticaBold8));
                invoiceTable.addCell(new Phrase("Item Total (Rs)", helveticaBold8));

                double totalOrdersAmount = 0.0;
                int i=1;
                for(Order order :orders){
                        LineItem lineItem = order.getLineitems().get(0);
                        double orderAmount = order.getTotal_amount();
                        double rate = lineItem.getVatRate();
                        double salesTax = (rate * (orderAmount - order.getInsuranceAmount()))/(100 + rate);

                        invoiceTable.addCell(new Phrase(i+"", helveticaBold8));
                        invoiceTable.addCell(getProductNameCell(lineItem, false, order.getFreebieItemId()));
                        invoiceTable.addCell(new Phrase("" + lineItem.getQuantity(), helvetica8));


                        //populateBottomInvoiceTable(order, invoiceTable, rate);

                        double itemPrice = lineItem.getUnit_price();
                        double showPrice = (100 * itemPrice)/(100 + rate);
                        invoiceTable.addCell(getPriceCell(showPrice));

                        double totalPrice = lineItem.getTotal_price();
                        showPrice = (100 * totalPrice)/(100 + rate);
                        invoiceTable.addCell(getPriceCell(showPrice));

                        PdfPCell salesTaxCell = getPriceCell(salesTax);


                        invoiceTable.addCell(new Phrase(rate + "%", helvetica8));
                        invoiceTable.addCell(salesTaxCell);
                        invoiceTable.addCell(getTotalAmountCell(orderAmount));

                        totalOrdersAmount = totalOrdersAmount+ orderAmount;
                        i++;
                }


                invoiceTable.addCell(getEmptyCell(8));

                invoiceTable.addCell(getTotalCell(6));
                invoiceTable.addCell(getRupeesCell());
                invoiceTable.addCell(getTotalAmountCell(totalOrdersAmount));

                invoiceTable.addCell(new Phrase("Amount in Words:", helveticaBold8));
                invoiceTable.addCell(getAmountInWordsCell(totalOrdersAmount));

                invoiceTable.addCell(getEOECell(8));

                return invoiceTable;
        }

        private PdfPCell getInvoiceTableHeader(int colspan) {
                PdfPCell invoiceTableHeader = new PdfPCell(new Phrase("Order Item Details:", helveticaBold12));
                invoiceTableHeader.setBorder(Rectangle.NO_BORDER);
                invoiceTableHeader.setColspan(colspan);
                invoiceTableHeader.setPaddingTop(1);
                return invoiceTableHeader;
        }

        /*private void populateBottomInvoiceTable(Order order, PdfPTable invoiceTable, double rate) {
                for (LineItem lineitem : order.getLineitems()) {
                        invoiceTable.addCell(new Phrase("" + order.getId() , helvetica8));

                        invoiceTable.addCell(getProductNameCell(lineitem, false, order.getFreebieItemId()));

                        invoiceTable.addCell(new Phrase("" + lineitem.getQuantity(), helvetica8));

                        double itemPrice = lineitem.getUnit_price();
                        double showPrice = (100 * itemPrice)/(100 + rate);
                        invoiceTable.addCell(getPriceCell(showPrice)); //Unit Price Cell

                        double totalPrice = lineitem.getTotal_price();
                        showPrice = (100 * totalPrice)/(100 + rate);
                        invoiceTable.addCell(getPriceCell(showPrice));  //Total Price Cell
                }
        }*/

        private PdfPCell getProductNameCell(LineItem lineitem, boolean appendIMEI, Long freebieItemId) {
                String itemName = getItemDisplayName(lineitem, appendIMEI);
                if(freebieItemId!=null && freebieItemId!=0){
                        try {
                                CatalogService.Client catalogClient = ctsc.getClient();
                                Item item = catalogClient.getItem(freebieItemId);
                                itemName = itemName + "\n(Free Item: " + item.getBrand() + " " + item.getModelName() + " " + item.getModelNumber() + ")";
                        } catch(Exception tex) {
                                logger.error("Not able to get Freebie Item Details for ItemId:" + freebieItemId, tex);
                        }
                }
                PdfPCell productNameCell = new PdfPCell(new Phrase(itemName, helvetica8));
                productNameCell.setHorizontalAlignment(Element.ALIGN_LEFT);
                return productNameCell;
        }

        private PdfPCell getPriceCell(double price) {
                PdfPCell totalPriceCell = new PdfPCell(new Phrase(amountFormat.format(price), helvetica8));
                totalPriceCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return totalPriceCell;
        }

        private PdfPCell getVATLabelCell(boolean isVAT) {
                PdfPCell vatCell = null;
                if(isVAT){
                        vatCell = new PdfPCell(new Phrase("VAT", helveticaBold8));
                } else {
                        vatCell = new PdfPCell(new Phrase("CST", helveticaBold8));
                }
                vatCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return vatCell;
        }

        private PdfPCell getCFORMLabelCell() {
                PdfPCell cFormCell = null;
                cFormCell = new PdfPCell(new Phrase("CST Against CForm", helveticaBold8));
                cFormCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return cFormCell;
        }

        /*private PdfPCell getAdvanceAmountCell(int colspan) {
                PdfPCell insuranceCell = null;
                insuranceCell = new PdfPCell(new Phrase("Advance Amount Received", helvetica8));
                insuranceCell.setColspan(colspan);
                insuranceCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return insuranceCell;
        }*/

        /*private PdfPCell getInsuranceCell(int colspan) {
                PdfPCell insuranceCell = null;
                insuranceCell = new PdfPCell(new Phrase("1 Year WorldWide Theft Insurance", helvetica8));
                insuranceCell.setColspan(colspan);
                insuranceCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return insuranceCell;
        }*/

        private PdfPCell getEmptyCell(int colspan) {
                PdfPCell emptyCell = new PdfPCell(new Phrase(" ", helvetica8));
                emptyCell.setColspan(colspan);
                return emptyCell;
        }

        private PdfPCell getTotalCell(int colspan) {
                PdfPCell totalCell = new PdfPCell(new Phrase("Grand Total", helveticaBold8));
                totalCell.setColspan(colspan);
                totalCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return totalCell;
        }

        private PdfPCell getRupeesCell() {
                PdfPCell rupeesCell = new PdfPCell(new Phrase("Rs.", helveticaBold8));
                rupeesCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return rupeesCell;
        }

        private PdfPCell getTotalAmountCell(double orderAmount) {
                PdfPCell totalAmountCell = new PdfPCell(new Phrase(amountFormat.format(orderAmount), helveticaBold8));
                totalAmountCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return totalAmountCell;
        }

        /**
         * This method uses ICU4J libraries to convert the given amount into words
         * of Indian locale.
         * 
         * @param orderAmount
         *            The amount to convert.
         * @return the string representation of the given amount.
         */
        private PdfPCell getAmountInWordsCell(double orderAmount) {
                RuleBasedNumberFormat amountInWordsFormat = new RuleBasedNumberFormat(indianLocale, RuleBasedNumberFormat.SPELLOUT);
                StringBuilder amountInWords = new StringBuilder("Rs. ");
                amountInWords.append(WordUtils.capitalize(amountInWordsFormat.format((int)orderAmount)));
                amountInWords.append(" and ");
                amountInWords.append(WordUtils.capitalize(amountInWordsFormat.format((int)(orderAmount*100)%100)));
                amountInWords.append(" paise");

                PdfPCell amountInWordsCell= new PdfPCell(new Phrase(amountInWords.toString(), helveticaBold8));
                amountInWordsCell.setColspan(4);
                return amountInWordsCell;
        }

        /**
         * Returns the item name to be displayed in the invoice table.
         * 
         * @param lineitem
         *            The line item whose name has to be displayed
         * @param appendIMEI
         *            Whether to attach the IMEI No. to the item name
         * @return The name to be displayed for the given line item.
         */
        private String getItemDisplayName(LineItem lineitem, boolean appendIMEI){
                StringBuffer itemName = new StringBuffer();
                if(lineitem.getBrand()!= null)
                        itemName.append(lineitem.getBrand() + " ");
                if(lineitem.getModel_name() != null)
                        itemName.append(lineitem.getModel_name() + " ");
                if(lineitem.getModel_number() != null )
                        itemName.append(lineitem.getModel_number() + " ");
                if(lineitem.getColor() != null && !lineitem.getColor().trim().equals("NA"))
                        itemName.append("("+lineitem.getColor()+")");
                if(appendIMEI && lineitem.isSetSerial_number()){
                        itemName.append("\nIMEI No. " + lineitem.getSerial_number());
                }

                return itemName.toString();
        }

        /**
         * 
         * @param colspan
         * @return a PdfPCell containing the E&amp;OE text and spanning the given
         *         no. of columns
         */
        private PdfPCell getEOECell(int colspan) {
                PdfPCell eoeCell = new PdfPCell(new Phrase("E & O.E", helvetica8));
                eoeCell.setColspan(colspan);
                eoeCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
                return eoeCell;
        }

        /*private PdfPTable getExtraInfoTable(Order order, Provider provider, float barcodeFontSize, BillingType billingType){
                PdfPTable extraInfoTable = new PdfPTable(1);
                extraInfoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                extraInfoTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

                String fontPath = InvoiceGenerationService.class.getResource("/saholic-wn.TTF").getPath();
                FontFactoryImp ttfFontFactory = new FontFactoryImp();
                ttfFontFactory.register(fontPath, "barcode");
                Font barCodeFont = ttfFontFactory.getFont("barcode", BaseFont.CP1252, true, barcodeFontSize);

                PdfPCell extraInfoCell;
                if(billingType == BillingType.EXTERNAL){
                        extraInfoCell = new PdfPCell(new Paragraph( "*" + order.getId() + "*        *" + order.getCustomer_name() + "*        *"  + order.getTotal_amount() + "*", barCodeFont));
                }else{
                        extraInfoCell = new PdfPCell(new Paragraph( "*" + order.getId() + "*        *" + order.getLineitems().get(0).getTransfer_price() + "*", barCodeFont));  
                }

                extraInfoCell.setPaddingTop(20.0f);
                extraInfoCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                extraInfoCell.setBorder(Rectangle.NO_BORDER);

                extraInfoTable.addCell(extraInfoCell);


                return extraInfoTable;
        }*/

        /*private PdfPTable getFixedTextTable(float barcodeFontSize, String printText){
                PdfPTable extraInfoTable = new PdfPTable(1);
                extraInfoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                extraInfoTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

                String fontPath = InvoiceGenerationService.class.getResource("/saholic-wn.TTF").getPath();
                FontFactoryImp ttfFontFactory = new FontFactoryImp();
                ttfFontFactory.register(fontPath, "barcode");
                Font barCodeFont = ttfFontFactory.getFont("barcode", BaseFont.CP1252, true, barcodeFontSize);

                PdfPCell extraInfoCell = new PdfPCell(new Paragraph( "*" + printText + "*", barCodeFont));

                extraInfoCell.setPaddingTop(20.0f);
                extraInfoCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
                extraInfoCell.setBorder(Rectangle.NO_BORDER);

                extraInfoTable.addCell(extraInfoCell);

                return extraInfoTable;
        }*/

        /*private void generateBarcode(String barcodeString, String fileName){
                Code128Bean bean = new Code128Bean();

                final int dpi = 60;

                //Configure the barcode generator
                bean.setModuleWidth(UnitConv.in2mm(1.0f / dpi)); //makes the narrow bar 
                                                                 //width exactly one pixel
                bean.setFontSize(bean.getFontSize()+1.0f);
                bean.doQuietZone(false);

                try {
                        File outputFile = new File("/tmp/"+fileName+".png");
                        OutputStream out = new FileOutputStream(outputFile);

                    //Set up the canvas provider for monochrome PNG output 
                    BitmapCanvasProvider canvas = new BitmapCanvasProvider(
                            out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);

                    //Generate the barcode
                    bean.generateBarcode(canvas, barcodeString);

                    //Signal end of generation
                    canvas.finish();
                    out.close();

                } 
                catch(Exception e){
                        logger.error("Exception during generating Barcode : ", e);
                }
        }*/

        /*public static void main(String[] args) throws IOException {
                InvoiceGenerationService invoiceGenerationService = new InvoiceGenerationService();
                long orderId = 356324;
                ByteArrayOutputStream baos = invoiceGenerationService.generateInvoice(orderId, true, false, 1);
                String userHome = System.getProperty("user.home");
                File f = new File(userHome + "/invoice-" + orderId + ".pdf");
                FileOutputStream fos = new FileOutputStream(f);
                baos.writeTo(fos);
                System.out.println("Invoice generated.");
        }*/
}