Subversion Repositories SmartDukaan

Rev

Rev 4951 | Rev 5527 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2787 chandransh 1
package in.shop2020.hotspot.dashbaord.server;
2
 
3
import in.shop2020.config.ConfigException;
3044 chandransh 4
import in.shop2020.logistics.DeliveryType;
2787 chandransh 5
import in.shop2020.logistics.LogisticsServiceException;
6
import in.shop2020.logistics.Provider;
7
import in.shop2020.model.v1.catalog.InventoryServiceException;
8
import in.shop2020.model.v1.catalog.Warehouse;
9
import in.shop2020.model.v1.catalog.InventoryService.Client;
10
import in.shop2020.model.v1.order.LineItem;
11
import in.shop2020.model.v1.order.Order;
4361 rajveer 12
import in.shop2020.model.v1.order.OrderStatus;
3132 rajveer 13
import in.shop2020.thrift.clients.CatalogClient;
14
import in.shop2020.thrift.clients.LogisticsClient;
15
import in.shop2020.thrift.clients.TransactionClient;
2787 chandransh 16
import in.shop2020.thrift.clients.config.ConfigClient;
17
 
18
import java.io.ByteArrayOutputStream;
19
import java.io.File;
20
import java.io.FileOutputStream;
21
import java.io.IOException;
22
import java.text.DateFormat;
23
import java.text.DecimalFormat;
4361 rajveer 24
import java.util.ArrayList;
4746 rajveer 25
import java.util.Calendar;
2787 chandransh 26
import java.util.Date;
27
import java.util.Enumeration;
4746 rajveer 28
import java.util.GregorianCalendar;
2787 chandransh 29
import java.util.List;
30
import java.util.Locale;
31
import java.util.Properties;
32
import java.util.ResourceBundle;
33
 
34
import javax.servlet.ServletException;
35
import javax.servlet.ServletOutputStream;
36
import javax.servlet.http.HttpServlet;
37
import javax.servlet.http.HttpServletRequest;
38
import javax.servlet.http.HttpServletResponse;
39
 
40
import org.apache.commons.lang.WordUtils;
41
import org.apache.thrift.TException;
42
import org.slf4j.Logger;
43
import org.slf4j.LoggerFactory;
44
 
45
import com.ibm.icu.text.RuleBasedNumberFormat;
46
 
47
import com.itextpdf.text.Document;
48
import com.itextpdf.text.Element;
49
import com.itextpdf.text.Font;
50
import com.itextpdf.text.FontFactory;
51
import com.itextpdf.text.FontFactoryImp;
52
import com.itextpdf.text.Image;
53
import com.itextpdf.text.Paragraph;
54
import com.itextpdf.text.Phrase;
55
import com.itextpdf.text.Rectangle;
56
import com.itextpdf.text.Font.FontFamily;
57
import com.itextpdf.text.pdf.BaseFont;
58
import com.itextpdf.text.pdf.PdfPCell;
59
import com.itextpdf.text.pdf.PdfPTable;
60
import com.itextpdf.text.pdf.PdfWriter;
61
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
62
 
63
@SuppressWarnings("serial")
64
public class InvoiceServlet extends HttpServlet {
65
 
66
    private static Logger logger = LoggerFactory.getLogger(InvoiceServlet.class);
67
 
68
    @Override
69
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
70
        long orderId = Long.parseLong(request.getParameter("id"));
4361 rajveer 71
        long warehouseId = Long.parseLong(request.getParameter("warehouse"));
2843 chandransh 72
        boolean withBill = false;
4361 rajveer 73
        boolean printAll = false;
2843 chandransh 74
        try {
75
            withBill = Boolean.parseBoolean(request.getParameter("withBill"));
76
        } catch(Exception e){
77
            logger.warn("Couldn't infer whether bill should be printed. Not printing the bill.", e);
78
        }
4361 rajveer 79
        try {
80
        	printAll = Boolean.parseBoolean(request.getParameter("printAll"));
81
        } catch(Exception e){
82
            logger.warn("Couldn't infer whether bill should be printed. Not printing the bill.", e);
83
        }
84
 
2787 chandransh 85
        logger.info("Printing invoice for order id: " + orderId);
86
 
87
        InvoiceGenerationService invoiceGenerationService = new InvoiceGenerationService();
4361 rajveer 88
        ByteArrayOutputStream baos = invoiceGenerationService.generateInvoice(orderId, withBill, printAll, warehouseId);
2787 chandransh 89
        response.setContentType("application/pdf");
90
        response.setHeader("Content-disposition", "inline; filename=invoice-"+orderId+".pdf" );
91
 
92
        ServletOutputStream sos;
93
        try {
94
            sos = response.getOutputStream();
95
            baos.writeTo(sos);
96
            sos.flush();
97
        } catch (IOException e) {
98
            logger.error("Encountered error while sending invoice response: ", e);
99
        }
100
    }
101
}
102
 
103
class InvoiceGenerationService {
104
 
105
    private static Logger logger = LoggerFactory.getLogger(InvoiceGenerationService.class);
106
 
3132 rajveer 107
    private TransactionClient tsc = null;
108
    private CatalogClient csc = null;
109
    private LogisticsClient lsc = null;
2787 chandransh 110
 
5387 rajveer 111
    private static final long SELF_PICKUP = 4;
2787 chandransh 112
    private static Locale indianLocale = new Locale("en", "IN");
113
    private DecimalFormat amountFormat = new DecimalFormat("#,##0.00");
114
 
115
    private static final Font helvetica8 = FontFactory.getFont(FontFactory.HELVETICA, 8);
116
    private static final Font helvetica10 = FontFactory.getFont(FontFactory.HELVETICA, 10);
117
    private static final Font helvetica12 = FontFactory.getFont(FontFactory.HELVETICA, 12);
118
    private static final Font helvetica16 = FontFactory.getFont(FontFactory.HELVETICA, 16);
3065 chandransh 119
    private static final Font helvetica28 = FontFactory.getFont(FontFactory.HELVETICA, 28);
2787 chandransh 120
 
121
    private static final Font helveticaBold8 = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 8);
122
    private static final Font helveticaBold12 = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12);
123
 
124
    private static final Properties properties = readProperties();
125
    private static final String ourAddress = properties.getProperty("sales_tax_address",
126
                    "Spice Online Retail Pvt. Ltd.\nKhasra No. 819, Block-K\nMahipalpur, New Delhi-110037\n");
127
    private static final String tinNo = properties.getProperty("sales_tax_tin", "07250399732");
128
 
129
    private static final String delhiPincodePrefix = "11";
130
 
131
    private static final double salesTaxLowRate = Double.parseDouble(properties.getProperty("sales_tax_low_rate", "5.0"));
132
    private static final double salesTaxHighRate = Double.parseDouble(properties.getProperty("sales_tax_high_rate", "12.5"));
133
    private static final double salesTaxCutOff = (Double.parseDouble(properties.getProperty("sales_tax_cutoff", "10000")) * (100 + salesTaxLowRate))/100;
134
 
135
    private static Properties readProperties(){
136
        ResourceBundle resource = ResourceBundle.getBundle(InvoiceGenerationService.class.getName());
137
        Properties props = new Properties();
138
 
139
        Enumeration<String> keys = resource.getKeys();
140
        while (keys.hasMoreElements()) {
141
            String key = keys.nextElement();
142
            props.put(key, resource.getString(key));
143
        }
144
        return props;
145
    }
146
 
147
    public InvoiceGenerationService() {
148
        try {
3132 rajveer 149
            tsc = new TransactionClient();
150
            csc = new CatalogClient();
151
            lsc = new LogisticsClient();
2787 chandransh 152
        } catch (Exception e) {
153
            logger.error("Error while instantiating thrift clients.", e);
154
        }
155
    }
156
 
4361 rajveer 157
    public ByteArrayOutputStream generateInvoice(long orderId, boolean withBill, boolean printAll, long warehouseId) {
2787 chandransh 158
        ByteArrayOutputStream baosPDF = null;
159
        in.shop2020.model.v1.order.TransactionService.Client tclient = tsc.getClient();
160
        Client iclient = csc.getClient();
161
        in.shop2020.logistics.LogisticsService.Client logisticsClient = lsc.getClient();
162
 
4361 rajveer 163
 
2787 chandransh 164
        try {
165
            baosPDF = new ByteArrayOutputStream();
166
 
167
            Document document = new Document();
168
            PdfWriter.getInstance(document, baosPDF);
169
            document.addAuthor("shop2020");
4361 rajveer 170
            //document.addTitle("Invoice No: " + order.getInvoice_number());
2787 chandransh 171
            document.open();
4361 rajveer 172
 
173
            List<Order> orders = new ArrayList<Order>();
174
            if(printAll){
175
	            try {
4801 anupam.sin 176
	                List<OrderStatus> statuses = new ArrayList<OrderStatus>();
177
	                statuses.add(OrderStatus.ACCEPTED);
178
	                orders = tclient.getAllOrders(statuses, 0, 0, warehouseId);
4361 rajveer 179
	            } catch (Exception e) {
180
	            	logger.error("Error while getting order information", e);
181
	                return baosPDF; 
182
				}
183
            }else{
184
            	orders.add(tclient.getOrder(orderId));	
185
            }
2787 chandransh 186
 
4361 rajveer 187
            for(Order order: orders){
188
            	Warehouse warehouse = null;
189
            	Provider provider = null;
190
            	String destCode = null;
191
            	int barcodeFontSize = 0;
192
            	try {
193
            		warehouse = iclient.getWarehouse(order.getWarehouse_id());
194
            		long providerId = order.getLogistics_provider_id();
195
            		provider = logisticsClient.getProvider(providerId);
5387 rajveer 196
            		if(providerId == SELF_PICKUP)
197
            			destCode = "SELF";
198
            		else
199
            			destCode = logisticsClient.getDestinationCode(providerId, order.getCustomer_pincode());
200
 
4361 rajveer 201
            		barcodeFontSize = Integer.parseInt(ConfigClient.getClient().get(provider.getName().toLowerCase() + "_barcode_fontsize"));
202
            	} catch (InventoryServiceException ise) {
203
            		logger.error("Error while getting the warehouse information.", ise);
204
            		return baosPDF;
205
            	} catch (LogisticsServiceException lse) {
206
            		logger.error("Error while getting the provider information.", lse);
207
            		return baosPDF;
208
            	} catch (ConfigException ce) {
209
            		logger.error("Error while getting the fontsize for the given provider", ce);
210
            		return baosPDF;
211
            	} catch (TException te) {
212
            		logger.error("Error while getting some essential information from the services", te);
213
            		return baosPDF;
214
            	}
2787 chandransh 215
 
4361 rajveer 216
	            PdfPTable dispatchAdviceTable = getDispatchAdviceTable(order, warehouse, provider, barcodeFontSize, destCode, withBill);
217
	            dispatchAdviceTable.setSpacingAfter(10.0f);
218
	            dispatchAdviceTable.setWidthPercentage(90.0f);
219
 
220
	            document.add(dispatchAdviceTable);
221
	            if(withBill){
222
	                PdfPTable taxTable = getTaxCumRetailInvoiceTable(order, provider);
223
	                taxTable.setSpacingBefore(5.0f);
224
	                taxTable.setWidthPercentage(90.0f);
225
	                document.add(new DottedLineSeparator());
226
	                document.add(taxTable);
227
	            }else{
228
	            	PdfPTable extraInfoTable = getExtraInfoTable(order, provider, 16);
229
	            	extraInfoTable.setSpacingBefore(5.0f);
230
	            	extraInfoTable.setWidthPercentage(90.0f);
231
	                document.add(new DottedLineSeparator());
232
	                document.add(extraInfoTable);
233
	            }
234
	            document.newPage();
2843 chandransh 235
            }
2787 chandransh 236
            document.close();
237
            baosPDF.close();
4747 rajveer 238
         // Adding facility to store the bill on the local directory. This will happen for only for Mahipalpur warehouse.
239
            if(withBill && !printAll){
240
            	Calendar cal = new GregorianCalendar();
241
            	cal.setTimeInMillis(orders.get(0).getBilling_timestamp());
242
            	int year = cal.get(Calendar.YEAR);
243
      		  	int month = cal.get(Calendar.MONTH);
244
      		  	int day = cal.get(Calendar.DAY_OF_MONTH);
245
      		  	String dirPath = "/SaholicInvoices" + File.separator + year + File.separator  + month + File.separator + day;
246
      		  	File dirFile = new File(dirPath);
247
      		  	if(!dirFile.exists()){
248
      		  		dirFile.mkdirs();	
249
      		  	}
250
      		  	File f = new File( dirPath + File.separator + orderId + ".pdf");
251
                FileOutputStream fos = new FileOutputStream(f);
252
                baosPDF.writeTo(fos);
253
            }
2787 chandransh 254
        } catch (Exception e) {
255
            logger.error("Error while generating Invoice: ", e);
256
        }
257
        return baosPDF;
258
    }
259
 
2915 chandransh 260
    private PdfPTable getDispatchAdviceTable(Order order, Warehouse warehouse, Provider provider, float barcodeFontSize, String destCode, boolean withBill){
2787 chandransh 261
        Font barCodeFont = getBarCodeFont(provider, barcodeFontSize);
262
 
263
        PdfPTable table = new PdfPTable(1);
264
        table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
265
 
3065 chandransh 266
        PdfPTable logoTable = new PdfPTable(2);
267
        logoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
268
        logoTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
269
        logoTable.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
270
        logoTable.addCell(getLogoCell());
271
        if(order.isCod())
272
            logoTable.addCell(new Phrase("COD   ", helvetica28));
4550 rajveer 273
        else
274
        	logoTable.addCell(new Phrase("   ", helvetica28));
2787 chandransh 275
        PdfPCell titleCell = getTitleCell();
276
        PdfPTable customerTable = getCustomerAddressTable(order, destCode, false, helvetica12);
277
        PdfPTable providerInfoTable = getProviderTable(order, provider, barCodeFont);
278
 
279
        PdfPTable dispatchTable = new PdfPTable(new float[]{0.5f, 0.1f, 0.4f});
280
        dispatchTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
281
        dispatchTable.addCell(customerTable);
282
        dispatchTable.addCell(new Phrase(" "));
283
        dispatchTable.addCell(providerInfoTable);
284
 
2915 chandransh 285
 
286
        PdfPTable invoiceTable = null;
287
        if(withBill)
288
            invoiceTable = getTopInvoiceTable(order, tinNo);
289
        else
290
            invoiceTable = getTopInvoiceTable(order, warehouse.getTinNumber());
3065 chandransh 291
 
2915 chandransh 292
        PdfPCell addressCell = null;
293
        if(withBill)
294
            addressCell = getAddressCell(ourAddress);
295
        else
296
            addressCell = getAddressCell(warehouse.getLocation() + "\nPIN " + warehouse.getPincode() + "\n\n");
2787 chandransh 297
 
3065 chandransh 298
        PdfPTable chargesTable = new PdfPTable(1);
299
        chargesTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
300
        chargesTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
301
        if(order.isCod()){
302
            chargesTable.addCell(new Phrase("AMOUNT TO BE COLLECTED : Rs " + order.getTotal_amount(), helveticaBold12));
4313 rajveer 303
            chargesTable.addCell(new Phrase("RTO ADDRESS:DEL/ITG-111117"));
3065 chandransh 304
        } else {
305
            chargesTable.addCell(new Phrase("Do not pay any extra charges to the Courier."));  
306
        }
307
 
308
        PdfPTable addressAndNoteTable = new PdfPTable(new float[]{0.3f, 0.7f});
309
        addressAndNoteTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
310
        addressAndNoteTable.addCell(addressCell);
311
        addressAndNoteTable.addCell(chargesTable);
312
 
313
        table.addCell(logoTable);
2787 chandransh 314
        table.addCell(titleCell);
315
        table.addCell(dispatchTable);
316
        table.addCell(invoiceTable);
317
        table.addCell(new Phrase("If undelivered, return to:", helvetica10));
3065 chandransh 318
        table.addCell(addressAndNoteTable);
2787 chandransh 319
        return table;
320
    }
321
 
322
    private Font getBarCodeFont(Provider provider, float barcodeFontSize) {
323
        String fontPath = InvoiceGenerationService.class.getResource("/" + provider.getName().toLowerCase() + "/barcode.TTF").getPath();
324
        FontFactoryImp ttfFontFactory = new FontFactoryImp();
325
        ttfFontFactory.register(fontPath, "barcode");
326
        Font barCodeFont = ttfFontFactory.getFont("barcode", BaseFont.CP1252, true, barcodeFontSize);
327
        return barCodeFont;
328
    }
329
 
330
    private PdfPCell getLogoCell() {
331
        String logoPath = InvoiceGenerationService.class.getResource("/logo.jpg").getPath();
332
        PdfPCell logoCell;
333
        try {
334
            logoCell = new PdfPCell(Image.getInstance(logoPath), false);
335
        } catch (Exception e) {
336
            //Too Many exceptions to catch here: BadElementException, MalformedURLException and IOException
337
            logger.warn("Couldn't load the Saholic logo: ", e);
338
            logoCell = new PdfPCell(new Phrase("Saholic Logo"));
339
        }
340
        logoCell.setBorder(Rectangle.NO_BORDER);
341
        return logoCell;
342
    }
343
 
344
    private PdfPCell getTitleCell() {
345
        PdfPCell titleCell = new PdfPCell(new Phrase("Dispatch Advice", helveticaBold12));
346
        titleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
347
        titleCell.setBorder(Rectangle.NO_BORDER);
348
        return titleCell;
349
    }
350
 
351
    private PdfPTable getProviderTable(Order order, Provider provider, Font barCodeFont) {
352
        PdfPTable providerInfoTable = new PdfPTable(1);
353
        providerInfoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
354
        PdfPCell providerNameCell = new PdfPCell(new Phrase(provider.getName(), helveticaBold12));
355
        providerNameCell.setHorizontalAlignment(Element.ALIGN_LEFT);
356
        providerNameCell.setBorder(Rectangle.NO_BORDER);
357
 
358
        PdfPCell awbNumberCell = new PdfPCell(new Paragraph("*" + order.getAirwaybill_no() + "*", barCodeFont));
359
        awbNumberCell.setPaddingTop(20.0f);
360
        awbNumberCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
361
        awbNumberCell.setBorder(Rectangle.NO_BORDER);
362
 
363
        providerInfoTable.addCell(providerNameCell);
364
        providerInfoTable.addCell(awbNumberCell);
3065 chandransh 365
        if(order.isCod())
366
            providerInfoTable.addCell(new Phrase("Account No : " + provider.getDetails().get(DeliveryType.COD).getAccountNo(), helvetica8));
367
        else
368
            providerInfoTable.addCell(new Phrase("Account No : " + provider.getDetails().get(DeliveryType.PREPAID).getAccountNo(), helvetica8));
2787 chandransh 369
        providerInfoTable.addCell(new Phrase("AWB Date   : " + DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date()), helvetica8));
370
        providerInfoTable.addCell(new Phrase("Weight         : " + order.getTotal_weight() + " Kg", helvetica8));
371
        return providerInfoTable;
372
    }
373
 
2915 chandransh 374
    private PdfPTable getTopInvoiceTable(Order order, String tinNo){
2787 chandransh 375
        PdfPTable invoiceTable = new PdfPTable(new float[]{0.2f, 0.2f, 0.3f, 0.1f, 0.1f, 0.1f});
376
        invoiceTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
377
 
378
        invoiceTable.addCell(getInvoiceTableHeader(6));
379
 
380
        invoiceTable.addCell(new Phrase("Order No", helvetica8));
381
        invoiceTable.addCell(new Phrase("Paymode", helvetica8));
382
        invoiceTable.addCell(new Phrase("Product Name", helvetica8));
383
        invoiceTable.addCell(new Phrase("Quantity", helvetica8));
384
        invoiceTable.addCell(new Phrase("Rate", helvetica8));
385
        invoiceTable.addCell(new Phrase("Amount", helvetica8));
386
        populateTopInvoiceTable(order, invoiceTable);
387
 
388
        invoiceTable.addCell(getTotalCell(4));      
389
        invoiceTable.addCell(getRupeesCell());
390
        invoiceTable.addCell(getTotalAmountCell(order.getTotal_amount()));
391
 
392
        PdfPCell tinCell = new PdfPCell(new Phrase("TIN NO. " + tinNo, helvetica8));
393
        tinCell.setColspan(6);
394
        tinCell.setPadding(2);
395
        invoiceTable.addCell(tinCell);
396
 
397
        return invoiceTable;
398
    }
399
 
400
    private void populateTopInvoiceTable(Order order, PdfPTable invoiceTable) {
401
        List<LineItem> lineitems = order.getLineitems();
402
        for (LineItem lineitem : lineitems) {
403
            invoiceTable.addCell(new Phrase(order.getId() + "", helvetica8));
3065 chandransh 404
            if(order.isCod())
405
                invoiceTable.addCell(new Phrase("COD", helvetica8));
406
            else
407
                invoiceTable.addCell(new Phrase("Prepaid", helvetica8));
2787 chandransh 408
 
409
            invoiceTable.addCell(getProductNameCell(lineitem, false));
410
 
411
            invoiceTable.addCell(new Phrase(lineitem.getQuantity() + "", helvetica8));
412
 
413
            invoiceTable.addCell(getPriceCell(lineitem.getUnit_price()));
414
 
415
            invoiceTable.addCell(getPriceCell(lineitem.getTotal_price()));
416
        }
417
    }
418
 
2915 chandransh 419
    private PdfPCell getAddressCell(String address) {
420
        Paragraph addressParagraph = new Paragraph(address, new Font(FontFamily.TIMES_ROMAN, 8f));
2787 chandransh 421
        PdfPCell addressCell = new PdfPCell();
422
        addressCell.addElement(addressParagraph);
423
        addressCell.setHorizontalAlignment(Element.ALIGN_LEFT);
424
        addressCell.setBorder(Rectangle.NO_BORDER);
425
        return addressCell;
426
    }
427
 
428
    private PdfPTable getTaxCumRetailInvoiceTable(Order order, Provider provider){
429
        PdfPTable taxTable = new PdfPTable(1);
430
        taxTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
431
        taxTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
432
 
433
        PdfPCell retailInvoiceTitleCell = new PdfPCell(new Phrase("TAX CUM RETAIL INVOICE", helveticaBold12));
434
        retailInvoiceTitleCell.setHorizontalAlignment(Element.ALIGN_CENTER);
435
        retailInvoiceTitleCell.setBorder(Rectangle.NO_BORDER);
436
 
437
        Paragraph sorlAddress = new Paragraph(ourAddress + "TIN NO. " + tinNo, new Font(FontFamily.TIMES_ROMAN, 8f, Element.ALIGN_CENTER));
438
        PdfPCell sorlAddressCell = new PdfPCell(sorlAddress);
439
        sorlAddressCell.addElement(sorlAddress);
440
        sorlAddressCell.setHorizontalAlignment(Element.ALIGN_CENTER);
441
 
442
        PdfPTable customerAddress = getCustomerAddressTable(order, null, true, helvetica8);
443
        PdfPTable orderDetails = getOrderDetails(order, provider);
444
 
445
        PdfPTable addrAndOrderDetailsTable = new PdfPTable(new float[]{0.5f, 0.1f, 0.4f});
446
        addrAndOrderDetailsTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
447
        addrAndOrderDetailsTable.addCell(customerAddress);
448
        addrAndOrderDetailsTable.addCell(new Phrase(" "));
449
        addrAndOrderDetailsTable.addCell(orderDetails);
450
 
451
        boolean isVAT = order.getCustomer_pincode().startsWith(delhiPincodePrefix);
452
        PdfPTable invoiceTable = getBottomInvoiceTable(order, isVAT);
453
 
454
        PdfPCell disclaimerCell = new PdfPCell(new Phrase("Goods once sold will not be taken back.\nAll disputes subject to Delhi Jurisdiction.", helvetica8));
455
        disclaimerCell.setHorizontalAlignment(Element.ALIGN_LEFT);
456
        disclaimerCell.setBorder(Rectangle.NO_BORDER);
457
 
458
        taxTable.addCell(retailInvoiceTitleCell);
459
        taxTable.addCell(sorlAddress);
460
        taxTable.addCell(addrAndOrderDetailsTable);
461
        taxTable.addCell(invoiceTable);
462
        taxTable.addCell(disclaimerCell);
463
 
464
        return taxTable;
465
    }
466
 
467
    private PdfPTable getCustomerAddressTable(Order order, String destCode, boolean showPaymentMode, Font font){
468
        PdfPTable customerTable = new PdfPTable(1);
469
        customerTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
470
        customerTable.addCell(new Phrase(order.getCustomer_name(), font));
471
        customerTable.addCell(new Phrase(order.getCustomer_address1(), font));
472
        customerTable.addCell(new Phrase(order.getCustomer_address2(), font));
473
        customerTable.addCell(new Phrase(order.getCustomer_city() + "," + order.getCustomer_state(), font));
474
        if(destCode != null)
475
            customerTable.addCell(new Phrase(order.getCustomer_pincode() + " - " + destCode, helvetica16));
476
        else
477
            customerTable.addCell(new Phrase(order.getCustomer_pincode(), font));
478
        customerTable.addCell(new Phrase("Phone :" + order.getCustomer_mobilenumber(), font));
479
        if(showPaymentMode){
480
            customerTable.addCell(new Phrase(" ", font));
481
            customerTable.addCell(new Phrase("Payment Mode: Prepaid", font));
482
        }
483
        return customerTable;
484
    }
485
 
486
    private PdfPTable getOrderDetails(Order order, Provider provider){
487
        PdfPTable orderTable = new PdfPTable(new float[]{0.4f, 0.6f});
488
        orderTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
489
 
490
        orderTable.addCell(new Phrase("Invoice No:", helvetica8));
491
        orderTable.addCell(new Phrase(order.getInvoice_number(), helvetica8));
492
 
493
        orderTable.addCell(new Phrase("Date:", helvetica8));
494
        orderTable.addCell(new Phrase(DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date(order.getBilling_timestamp())), helvetica8));
495
 
496
        orderTable.addCell(new Phrase(" "));
497
        orderTable.addCell(new Phrase(" "));
498
 
499
        orderTable.addCell(new Phrase("Order ID:", helvetica8));
500
        orderTable.addCell(new Phrase("" + order.getId(), helvetica8));
501
 
502
        orderTable.addCell(new Phrase("Order Date:", helvetica8));
503
        orderTable.addCell(new Phrase(DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date(order.getCreated_timestamp())), helvetica8));
504
 
505
        orderTable.addCell(new Phrase("Courier:", helvetica8));
506
        orderTable.addCell(new Phrase(provider.getName(), helvetica8));
507
 
508
        orderTable.addCell(new Phrase("AWB No:", helvetica8));
509
        orderTable.addCell(new Phrase(order.getAirwaybill_no(), helvetica8));
510
 
511
        orderTable.addCell(new Phrase("AWB Date:", helvetica8));
512
        orderTable.addCell(new Phrase(DateFormat.getDateInstance(DateFormat.MEDIUM).format(new Date()), helvetica8));
513
 
514
        return orderTable;
515
    }
516
 
517
    private PdfPTable getBottomInvoiceTable(Order order, boolean isVAT){
518
        PdfPTable invoiceTable = new PdfPTable(new float[]{0.2f, 0.5f, 0.1f, 0.1f, 0.1f});
519
        invoiceTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
520
 
521
        invoiceTable.addCell(getInvoiceTableHeader(5));
522
 
523
        invoiceTable.addCell(new Phrase("Sl. No.", helveticaBold8));
524
        invoiceTable.addCell(new Phrase("Description", helveticaBold8));
525
        invoiceTable.addCell(new Phrase("Quantity", helveticaBold8));
526
        invoiceTable.addCell(new Phrase("Rate (Rs)", helveticaBold8));
527
        invoiceTable.addCell(new Phrase("Amount (Rs)", helveticaBold8));
528
 
529
        double orderAmount = order.getTotal_amount();
4951 mandeep.dh 530
        double rate = getTaxRate(order.getLineitems().get(0).getUnit_price());
2787 chandransh 531
        double salesTax = (rate * orderAmount)/(100 + rate);
532
 
533
        populateBottomInvoiceTable(order, invoiceTable, rate);
534
 
535
        PdfPCell salesTaxCell = getPriceCell(salesTax);
536
 
537
        invoiceTable.addCell(getVATLabelCell(isVAT));
538
        invoiceTable.addCell(new Phrase(rate + "%", helvetica8));
539
        invoiceTable.addCell(salesTaxCell);
540
 
541
        invoiceTable.addCell(getEmptyCell(5));
542
 
543
        invoiceTable.addCell(getTotalCell(3));
544
        invoiceTable.addCell(getRupeesCell());
545
        invoiceTable.addCell(getTotalAmountCell(orderAmount));
546
 
547
        invoiceTable.addCell(new Phrase("Amount in Words:", helvetica8));
548
        invoiceTable.addCell(getAmountInWordsCell(orderAmount));
549
 
550
        invoiceTable.addCell(getEOECell(5));
551
 
552
        return invoiceTable;
553
    }
554
 
555
    private PdfPCell getInvoiceTableHeader(int colspan) {
556
        PdfPCell invoiceTableHeader = new PdfPCell(new Phrase("Order Details:", helveticaBold12));
557
        invoiceTableHeader.setBorder(Rectangle.NO_BORDER);
558
        invoiceTableHeader.setColspan(colspan);
559
        invoiceTableHeader.setPaddingTop(10);
560
        return invoiceTableHeader;
561
    }
562
 
563
    private double getTaxRate(double orderAmount) {
564
        double rate;
565
        if(orderAmount <= salesTaxCutOff){
566
            rate = salesTaxLowRate;
567
        } else {
568
            rate = salesTaxHighRate;
569
        }
570
        return rate;
571
    }
572
 
573
    private void populateBottomInvoiceTable(Order order, PdfPTable invoiceTable, double rate) {
574
        for (LineItem lineitem : order.getLineitems()) {
575
            invoiceTable.addCell(new Phrase("" + order.getId() , helvetica8));
576
 
577
            invoiceTable.addCell(getProductNameCell(lineitem, true));
578
 
579
            invoiceTable.addCell(new Phrase("" + lineitem.getQuantity(), helvetica8));
580
 
581
            double itemPrice = lineitem.getUnit_price();
582
            double showPrice = (100 * itemPrice)/(100 + rate);
583
            invoiceTable.addCell(getPriceCell(showPrice)); //Unit Price Cell
584
 
585
            double totalPrice = lineitem.getTotal_price();
586
            showPrice = (100 * totalPrice)/(100 + rate);
587
            invoiceTable.addCell(getPriceCell(showPrice));  //Total Price Cell
588
        }
589
    }
590
 
591
    private PdfPCell getProductNameCell(LineItem lineitem, boolean appendIMEI) {
592
        String itemName = getItemDisplayName(lineitem, appendIMEI);
593
        PdfPCell productNameCell = new PdfPCell(new Phrase(itemName, helvetica8));
594
        productNameCell.setHorizontalAlignment(Element.ALIGN_LEFT);
595
        return productNameCell;
596
    }
597
 
598
    private PdfPCell getPriceCell(double price) {
599
        PdfPCell totalPriceCell = new PdfPCell(new Phrase(amountFormat.format(price), helvetica8));
600
        totalPriceCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
601
        return totalPriceCell;
602
    }
603
 
604
    private PdfPCell getVATLabelCell(boolean isVAT) {
605
        PdfPCell vatCell = null;
606
        if(isVAT){
607
            vatCell = new PdfPCell(new Phrase("VAT", helveticaBold8));
608
        } else {
609
            vatCell = new PdfPCell(new Phrase("CST", helveticaBold8));
610
        }
611
        vatCell.setColspan(3);
612
        vatCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
613
        return vatCell;
614
    }
615
 
616
    private PdfPCell getEmptyCell(int colspan) {
617
        PdfPCell emptyCell = new PdfPCell(new Phrase(" ", helvetica8));
618
        emptyCell.setColspan(colspan);
619
        return emptyCell;
620
    }
621
 
622
    private PdfPCell getTotalCell(int colspan) {
623
        PdfPCell totalCell = new PdfPCell(new Phrase("Total", helveticaBold8));
624
        totalCell.setColspan(colspan);
625
        totalCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
626
        return totalCell;
627
    }
628
 
629
    private PdfPCell getRupeesCell() {
630
        PdfPCell rupeesCell = new PdfPCell(new Phrase("Rs.", helveticaBold8));
631
        rupeesCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
632
        return rupeesCell;
633
    }
634
 
635
    private PdfPCell getTotalAmountCell(double orderAmount) {
636
        PdfPCell totalAmountCell = new PdfPCell(new Phrase(amountFormat.format(orderAmount), helveticaBold8));
637
        totalAmountCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
638
        return totalAmountCell;
639
    }
640
 
641
    /**
642
     * This method uses ICU4J libraries to convert the given amount into words
643
     * of Indian locale.
644
     * 
645
     * @param orderAmount
646
     *            The amount to convert.
647
     * @return the string representation of the given amount.
648
     */
649
    private PdfPCell getAmountInWordsCell(double orderAmount) {
650
        RuleBasedNumberFormat amountInWordsFormat = new RuleBasedNumberFormat(indianLocale, RuleBasedNumberFormat.SPELLOUT);
651
        StringBuilder amountInWords = new StringBuilder("Rs. ");
652
        amountInWords.append(WordUtils.capitalize(amountInWordsFormat.format((int)orderAmount)));
653
        amountInWords.append(" and ");
654
        amountInWords.append(WordUtils.capitalize(amountInWordsFormat.format((int)(orderAmount*100)%100)));
655
        amountInWords.append(" paise");
656
 
657
        PdfPCell amountInWordsCell= new PdfPCell(new Phrase(amountInWords.toString(), helveticaBold8));
658
        amountInWordsCell.setColspan(4);
659
        return amountInWordsCell;
660
    }
661
 
662
    /**
663
     * Returns the item name to be displayed in the invoice table.
664
     * 
665
     * @param lineitem
666
     *            The line item whose name has to be displayed
667
     * @param appendIMEI
668
     *            Whether to attach the IMEI No. to the item name
669
     * @return The name to be displayed for the given line item.
670
     */
671
    private String getItemDisplayName(LineItem lineitem, boolean appendIMEI){
672
        StringBuffer itemName = new StringBuffer();
673
        if(lineitem.getBrand()!= null)
674
            itemName.append(lineitem.getBrand() + " ");
675
        if(lineitem.getModel_name() != null)
676
            itemName.append(lineitem.getModel_name() + " ");
677
        if(lineitem.getModel_number() != null )
678
            itemName.append(lineitem.getModel_number() + " ");
679
        if(lineitem.getColor() != null && !lineitem.getColor().trim().equals("NA"))
680
            itemName.append("("+lineitem.getColor()+")");
4659 mandeep.dh 681
        if(appendIMEI && lineitem.isSetSerial_number()){
682
            itemName.append("\nIMEI No. " + lineitem.getSerial_number());
2787 chandransh 683
        }
684
 
685
        return itemName.toString();
686
    }
687
 
688
    /**
689
     * 
690
     * @param colspan
691
     * @return a PdfPCell containing the E&amp;OE text and spanning the given
692
     *         no. of columns
693
     */
694
    private PdfPCell getEOECell(int colspan) {
695
        PdfPCell eoeCell = new PdfPCell(new Phrase("E & O.E", helvetica8));
696
        eoeCell.setColspan(colspan);
697
        eoeCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
698
        return eoeCell;
699
    }
700
 
4262 rajveer 701
    private PdfPTable getExtraInfoTable(Order order, Provider provider, float barcodeFontSize){
702
        PdfPTable extraInfoTable = new PdfPTable(1);
703
        extraInfoTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
704
        extraInfoTable.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
705
 
706
        String fontPath = InvoiceGenerationService.class.getResource("/saholic.TTF").getPath();
707
        FontFactoryImp ttfFontFactory = new FontFactoryImp();
708
        ttfFontFactory.register(fontPath, "barcode");
709
        Font barCodeFont = ttfFontFactory.getFont("barcode", BaseFont.CP1252, true, barcodeFontSize);
710
 
711
        PdfPCell extraInfoCell = new PdfPCell(new Paragraph( "*" + order.getId() + "*        *" + order.getCustomer_name() + "*        *"  + order.getTotal_amount() + "*", barCodeFont));
712
        extraInfoCell.setPaddingTop(20.0f);
713
        extraInfoCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
714
        extraInfoCell.setBorder(Rectangle.NO_BORDER);
715
 
716
        extraInfoTable.addCell(extraInfoCell);
717
 
718
 
719
        return extraInfoTable;
720
    }
2787 chandransh 721
    public static void main(String[] args) throws IOException {
722
        InvoiceGenerationService invoiceGenerationService = new InvoiceGenerationService();
3065 chandransh 723
        long orderId = 542;
4361 rajveer 724
        ByteArrayOutputStream baos = invoiceGenerationService.generateInvoice(orderId, false, false, 1);
2787 chandransh 725
        String userHome = System.getProperty("user.home");
726
        File f = new File(userHome + "/invoice-" + orderId + ".pdf");
727
        FileOutputStream fos = new FileOutputStream(f);
728
        baos.writeTo(fos);
729
        System.out.println("Invoice generated.");
730
    }
731
}