Subversion Repositories SmartDukaan

Rev

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