Subversion Repositories SmartDukaan

Rev

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