Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
1631 ankur.sing 1
package in.shop2020.support.services;
2
 
3
import in.shop2020.model.v1.order.LineItem;
4
import in.shop2020.model.v1.order.Order;
2785 chandransh 5
import in.shop2020.model.v1.order.OrderStatus;
1631 ankur.sing 6
import in.shop2020.model.v1.order.TransactionServiceException;
2310 ankur.sing 7
import in.shop2020.payments.Attribute;
8
import in.shop2020.payments.Constants;
1631 ankur.sing 9
import in.shop2020.payments.Payment;
10
import in.shop2020.payments.PaymentException;
2061 ankur.sing 11
import in.shop2020.payments.PaymentGateway;
1631 ankur.sing 12
import in.shop2020.payments.PaymentStatus;
3125 rajveer 13
import in.shop2020.thrift.clients.PaymentClient;
14
import in.shop2020.thrift.clients.TransactionClient;
15
import in.shop2020.thrift.clients.UserClient;
1631 ankur.sing 16
 
17
import java.io.ByteArrayOutputStream;
18
import java.io.FileNotFoundException;
19
import java.io.FileOutputStream;
20
import java.io.IOException;
21
import java.text.DateFormat;
22
import java.text.ParseException;
23
import java.text.SimpleDateFormat;
24
import java.util.Calendar;
25
import java.util.Date;
2061 ankur.sing 26
import java.util.HashMap;
1631 ankur.sing 27
import java.util.List;
2061 ankur.sing 28
import java.util.Map;
1631 ankur.sing 29
 
30
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
31
import org.apache.poi.ss.usermodel.Cell;
32
import org.apache.poi.ss.usermodel.CellStyle;
1655 ankur.sing 33
import org.apache.poi.ss.usermodel.DataFormat;
1631 ankur.sing 34
import org.apache.poi.ss.usermodel.Font;
35
import org.apache.poi.ss.usermodel.Row;
36
import org.apache.poi.ss.usermodel.Sheet;
37
import org.apache.poi.ss.usermodel.Workbook;
38
import org.apache.poi.ss.util.CellRangeAddress;
39
import org.apache.thrift.TException;
3105 chandransh 40
import org.slf4j.Logger;
41
import org.slf4j.LoggerFactory;
1631 ankur.sing 42
 
43
public class PaymentDetailsGenerator {
3105 chandransh 44
 
45
    private static Logger logger = LoggerFactory.getLogger(PaymentDetailsGenerator.class);
46
 
3107 chandransh 47
    private static final int S_NO = 0, PAYMENT_ID = 1, GATEWAY = 2, PAYMENT_METHOD = 3, TXN_ID = 4, AMOUNT = 5, PAY_STATUS = 6, 
48
    PAY_STATUS_DESC = 7, TXN_STATUS = 8, REF_CODE = 9, TXN_TIME = 10, CUST_ID = 11, NAME = 12, 
49
    MOB_NO = 13, ADDR = 14, PINCODE = 15, CITY = 16, STATE = 17, EMAIL = 18, ORDER_ID = 19, ORDER_STATUS = 20, 
50
    ORDER_STATUS_DESC = 21, ITEM_ID = 22, PROD_GRP = 23, BRAND = 24, MOD_NAME = 25, MOD_NUM = 26, QTY = 27;
51
 
3125 rajveer 52
    TransactionClient tsc;
1660 ankur.sing 53
    in.shop2020.model.v1.order.TransactionService.Client tClient;
1631 ankur.sing 54
 
3125 rajveer 55
    PaymentClient psc;
1660 ankur.sing 56
    in.shop2020.payments.PaymentService.Client pClient;
1631 ankur.sing 57
 
3125 rajveer 58
    UserClient usc;
2061 ankur.sing 59
    in.shop2020.model.v1.user.UserContextService.Client uClient;
60
 
3107 chandransh 61
    Map<Long, PaymentGateway> gateWays = new HashMap<Long, PaymentGateway>(4);
2061 ankur.sing 62
 
1660 ankur.sing 63
    public PaymentDetailsGenerator() {
64
        try {
3125 rajveer 65
            tsc = new TransactionClient();
1660 ankur.sing 66
            tClient = tsc.getClient();
2061 ankur.sing 67
 
3125 rajveer 68
            psc = new PaymentClient();
1660 ankur.sing 69
            pClient = psc.getClient();
2061 ankur.sing 70
 
3125 rajveer 71
            usc = new UserClient();
2061 ankur.sing 72
            uClient = usc.getClient();
1660 ankur.sing 73
        } catch (Exception e) {
3105 chandransh 74
            logger.error("Error establishing connection to one of txn, payment or user service", e);
1660 ankur.sing 75
        }
76
    }
1631 ankur.sing 77
 
1660 ankur.sing 78
    /**
79
     * If any pending or failed payment exists between given date range, it returns ByteArrayOutputStream,
80
     * otherwise it returns null.
81
     * @param startDate
82
     * @param endDate
1881 ankur.sing 83
     * @param status 0 --> user input: Successful  1: Failed & pending
1660 ankur.sing 84
     * @return
85
     */
1881 ankur.sing 86
    public ByteArrayOutputStream generatePaymentDetailsReport(Date startDate, Date endDate, int status) {
1660 ankur.sing 87
        // Retrieving all the payments between start and end dates with status
88
        // as FAILED or INIT and for gateway Id = 1 (HDFC)
89
        List<Payment> payments = null;
3166 chandransh 90
        List<Payment> authorizedPayments = null;
1660 ankur.sing 91
        List<Payment> pendingPayments = null;
92
        try {
1881 ankur.sing 93
            if(status == 0) {
2061 ankur.sing 94
                payments = pClient.getPayments(startDate.getTime(), endDate.getTime(), PaymentStatus.SUCCESS, 0);
3166 chandransh 95
                authorizedPayments = pClient.getPayments(startDate.getTime(), endDate.getTime(), PaymentStatus.AUTHORIZED, 0);
96
                if(payments != null && authorizedPayments != null) {
97
                    payments.addAll(authorizedPayments);
98
                } else if(authorizedPayments != null){
99
                    payments = authorizedPayments;
100
                }
1881 ankur.sing 101
            } else {
2061 ankur.sing 102
                payments = pClient.getPayments(startDate.getTime(), endDate.getTime(), PaymentStatus.FAILED, 0);
103
                pendingPayments = pClient.getPayments(startDate.getTime(), endDate.getTime(), PaymentStatus.INIT, 0);
3166 chandransh 104
                if(payments != null && pendingPayments != null) {
1881 ankur.sing 105
                    payments.addAll(pendingPayments);
3166 chandransh 106
                } else if(pendingPayments != null){
1881 ankur.sing 107
                    payments = pendingPayments;
108
                }
109
            }
1660 ankur.sing 110
        } catch (PaymentException e) {
3105 chandransh 111
            logger.error("Error in payment service while getting payments", e);
1660 ankur.sing 112
        } catch (TException e) {
3105 chandransh 113
            logger.error("Error getting info from payment service", e);
1660 ankur.sing 114
        }
115
        if (payments == null || payments.isEmpty()) {
116
            return null;
117
        }
1631 ankur.sing 118
 
1660 ankur.sing 119
        // Preparing XLS file for output
4141 chandransh 120
        return getSpreadSheetData(payments, false);
121
    }
1631 ankur.sing 122
 
4141 chandransh 123
	/**
124
	 * Generates the payment reconciliation report for the payments captured
125
	 * between the given dates.
126
	 * 
127
	 * @param startDate
128
	 * @param endDate
129
	 * @return
130
	 */
131
    public ByteArrayOutputStream generatePaymentReconciliationReport(Date startDate, Date endDate) {
132
		// Retrieving all the payments between start and end dates with status
133
		// as CAPTURED
134
        List<Payment> payments = null;
135
        try {
136
            payments = pClient.getPaymentsByCapturedDate(startDate.getTime(), endDate.getTime(), 0);
137
        } catch (PaymentException e) {
138
            logger.error("Error in payment service while getting payments", e);
139
        } catch (TException e) {
140
            logger.error("Error getting info from payment service", e);
141
        }
142
        if (payments == null || payments.isEmpty())
143
            return null;
144
 
145
        // Preparing XLS file for output
146
        return getSpreadSheetData(payments, true);
1660 ankur.sing 147
    }
1631 ankur.sing 148
 
4141 chandransh 149
 
1660 ankur.sing 150
    // Prepares the XLS worksheet object and fills in the data with proper
151
    // formatting
4141 chandransh 152
    private ByteArrayOutputStream getSpreadSheetData(List<Payment> payments, boolean useCaptureTimeAsTxnTime) {
1660 ankur.sing 153
        ByteArrayOutputStream baosXLS = new ByteArrayOutputStream();
1631 ankur.sing 154
 
1660 ankur.sing 155
        Workbook wb = new HSSFWorkbook();
1631 ankur.sing 156
 
1660 ankur.sing 157
        Font font = wb.createFont();
158
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
159
        CellStyle style = wb.createCellStyle();
160
        style.setFont(font);
161
 
162
        CellStyle styleWT = wb.createCellStyle();
1655 ankur.sing 163
        styleWT.setWrapText(true);
1660 ankur.sing 164
 
1655 ankur.sing 165
        DataFormat format = wb.createDataFormat();
166
        CellStyle styleAmount = wb.createCellStyle();
167
        styleAmount.setDataFormat(format.getFormat("#,##0.00"));
1631 ankur.sing 168
 
1660 ankur.sing 169
        Sheet paymentSheet = wb.createSheet("Payment");
170
        short paymentSerialNo = 0;
1631 ankur.sing 171
 
1660 ankur.sing 172
        Row titleRow = paymentSheet.createRow(paymentSerialNo++);
173
        Cell titleCell = titleRow.createCell(0);
174
        titleCell.setCellValue("Payment Details");
175
        titleCell.setCellStyle(style);
1631 ankur.sing 176
 
1660 ankur.sing 177
        paymentSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 6));
1631 ankur.sing 178
 
1660 ankur.sing 179
        paymentSheet.createRow(paymentSerialNo++);
2310 ankur.sing 180
 
1660 ankur.sing 181
        Row headerRow = paymentSheet.createRow(paymentSerialNo++);
2310 ankur.sing 182
        headerRow.createCell(S_NO).setCellValue("S.No");
183
        headerRow.createCell(PAYMENT_ID).setCellValue("Payment Id");
184
        headerRow.createCell(GATEWAY).setCellValue("Gateway");
185
        headerRow.createCell(PAYMENT_METHOD).setCellValue("Payment Method");
186
        headerRow.getCell(PAYMENT_METHOD).setCellStyle(styleWT);
187
 
188
        headerRow.createCell(TXN_ID).setCellValue("Txn Id");
189
        headerRow.createCell(AMOUNT).setCellValue("Amount");
190
        headerRow.createCell(PAY_STATUS).setCellValue("Payment Status");
191
        headerRow.createCell(PAY_STATUS_DESC).setCellValue("Payment Status Description");
192
        headerRow.getCell(PAY_STATUS_DESC).setCellStyle(styleWT);
193
        headerRow.createCell(TXN_STATUS).setCellValue("Gateway Txn Status");
194
        headerRow.createCell(REF_CODE).setCellValue("Reference Code");
195
        headerRow.createCell(TXN_TIME).setCellValue("Transaction Time");
1631 ankur.sing 196
 
2310 ankur.sing 197
        headerRow.createCell(CUST_ID).setCellValue("Customer Id");
198
        headerRow.createCell(NAME).setCellValue("Name");
199
        headerRow.createCell(MOB_NO).setCellValue("MobileNo");
200
        headerRow.createCell(ADDR).setCellValue("Address");
201
        headerRow.getCell(ADDR).setCellStyle(styleWT);
202
        headerRow.createCell(PINCODE).setCellValue("Pincode");
203
        headerRow.createCell(CITY).setCellValue("City");
204
        headerRow.createCell(STATE).setCellValue("State");
205
        headerRow.createCell(EMAIL).setCellValue("Login Email");
1631 ankur.sing 206
 
2310 ankur.sing 207
        headerRow.createCell(ORDER_ID).setCellValue("Order Id");
208
        headerRow.createCell(ORDER_STATUS).setCellValue("Order Status");
209
        headerRow.createCell(ORDER_STATUS_DESC).setCellValue("Order Status Description");
1631 ankur.sing 210
 
2310 ankur.sing 211
        headerRow.createCell(ITEM_ID).setCellValue("Item Id");
212
        headerRow.createCell(PROD_GRP).setCellValue("Product Group");
213
        headerRow.createCell(BRAND).setCellValue("Brand");
214
        headerRow.createCell(MOD_NAME).setCellValue("Model Name");
215
        headerRow.createCell(MOD_NUM).setCellValue("Model Number");
216
        headerRow.createCell(QTY).setCellValue("Qty");
1631 ankur.sing 217
 
2310 ankur.sing 218
        int paymethodColWidth = 25, statusDescWidth = 25, addrColWidth = 35;
219
        paymentSheet.setColumnWidth(PAYMENT_METHOD, 256 * paymethodColWidth); // set width of payment method column
220
        paymentSheet.setColumnWidth(PAY_STATUS_DESC, 256 * statusDescWidth); // set width of payment status description column
221
        paymentSheet.setColumnWidth(ADDR, 256 * addrColWidth); // set width of address column
1660 ankur.sing 222
        List<Order> orders;
223
        long txnId;
224
        Row contentRow;
225
        Calendar calendar = Calendar.getInstance();
226
        DateFormat formatter = new SimpleDateFormat("EEE, dd-MMM-yyyy hh:mm a");
2310 ankur.sing 227
        float rowHeight = paymentSheet.getDefaultRowHeightInPoints();
228
        int sNo = 0;
1660 ankur.sing 229
        for (Payment payment : payments) {
2310 ankur.sing 230
            float newRowHeight = paymentSheet.getDefaultRowHeightInPoints();;
1660 ankur.sing 231
            try {
232
                paymentSerialNo++;
233
                contentRow = paymentSheet.createRow(paymentSerialNo);
2310 ankur.sing 234
                sNo++;
235
                contentRow.createCell(S_NO).setCellValue(sNo);
236
                contentRow.createCell(PAYMENT_ID).setCellValue(payment.getPaymentId());
2061 ankur.sing 237
 
2310 ankur.sing 238
                PaymentGateway gateway = gateWays.get(payment.getGatewayId());
2061 ankur.sing 239
                if(gateway == null) {
240
                    try {
241
                        gateway = pClient.getPaymentGateway(payment.getGatewayId());
242
                        gateWays.put(payment.getGatewayId(), gateway);
2492 ankur.sing 243
                    } catch (Exception e) {
3105 chandransh 244
                        logger.error("Error gerring payment gateway info from payment service", e);
2310 ankur.sing 245
                    }
2090 ankur.sing 246
                }
2310 ankur.sing 247
                contentRow.createCell(GATEWAY).setCellValue(gateway != null ? gateway.getName() : payment.getGatewayId()+"");
248
                //contentRow.createCell(GATEWAY).setCellValue(payment.getGatewayId());
249
 
250
                String paymentMethod = getPaymentMethod(payment.getAttributes());
251
                contentRow.createCell(PAYMENT_METHOD).setCellValue(paymentMethod);
252
                contentRow.getCell(PAYMENT_METHOD).setCellStyle(styleWT);
253
 
254
                if(paymentMethod.length() > paymethodColWidth) {
255
                    newRowHeight = Math.max(newRowHeight, (paymentMethod.length() / paymethodColWidth + 1) * rowHeight);
256
                }
257
 
258
                contentRow.createCell(TXN_ID).setCellValue(payment.getMerchantTxnId());
259
                contentRow.createCell(AMOUNT).setCellValue(payment.getAmount());
260
                contentRow.getCell(AMOUNT).setCellStyle(styleAmount);
261
                contentRow.createCell(PAY_STATUS).setCellValue(payment.getStatus().name());
262
                String desc = payment.getDescription();
263
                contentRow.createCell(PAY_STATUS_DESC).setCellValue(desc);
264
                contentRow.getCell(PAY_STATUS_DESC).setCellStyle(styleWT);
265
                if(desc != null && desc.length() > statusDescWidth) {
266
                    newRowHeight = Math.max(newRowHeight, (desc.length() / statusDescWidth + 1) * rowHeight);
267
                }
268
 
269
                contentRow.createCell(TXN_STATUS).setCellValue(payment.getGatewayTxnStatus());
270
                contentRow.createCell(REF_CODE).setCellValue(payment.getReferenceCode());
4141 chandransh 271
 
272
                if(useCaptureTimeAsTxnTime)
273
                	calendar.setTimeInMillis(payment.getSuccessTimestamp());
274
                else
275
                	calendar.setTimeInMillis(payment.getInitTimestamp());
2310 ankur.sing 276
                contentRow.createCell(TXN_TIME).setCellValue(formatter.format(calendar.getTime()));
1631 ankur.sing 277
 
3501 mandeep.dh 278
                txnId = payment.getMerchantTxnId();
1660 ankur.sing 279
                orders = tClient.getOrdersForTransaction(txnId, payment.getUserId());
280
                List<LineItem> lineItems;
1631 ankur.sing 281
 
1660 ankur.sing 282
                String address = "";
2310 ankur.sing 283
 
1660 ankur.sing 284
                if (orders == null || orders.isEmpty()) {
285
                    continue;
286
                }
2310 ankur.sing 287
                contentRow.createCell(CUST_ID).setCellValue(orders.get(0).getCustomer_id());
288
                contentRow.createCell(NAME).setCellValue(orders.get(0).getCustomer_name());
289
                contentRow.createCell(MOB_NO).setCellValue(orders.get(0).getCustomer_mobilenumber());
1660 ankur.sing 290
                address = orders.get(0).getCustomer_address1() + ", " + orders.get(0).getCustomer_address2();
2310 ankur.sing 291
                contentRow.createCell(ADDR).setCellValue(address);
292
                contentRow.getCell(ADDR).setCellStyle(styleWT);
293
 
294
                if(address.length() > addrColWidth) {
295
                    newRowHeight = Math.max(newRowHeight, (address.length() / addrColWidth + 1) * rowHeight);
296
                }
297
                contentRow.setHeightInPoints(newRowHeight);
298
 
299
                contentRow.createCell(PINCODE).setCellValue(orders.get(0).getCustomer_pincode());
300
                contentRow.createCell(CITY).setCellValue(orders.get(0).getCustomer_city());
301
                contentRow.createCell(STATE).setCellValue(orders.get(0).getCustomer_state());
302
                contentRow.createCell(EMAIL).setCellValue(orders.get(0).getCustomer_email());
303
 
304
                boolean firstOrder = true;
1660 ankur.sing 305
                for (Order o : orders) {
2785 chandransh 306
                    if(o.getStatus() == OrderStatus.SALES_RET_RESHIPPED || o.getStatus() == OrderStatus.DOA_RESHIPPED || o.getStatus() == OrderStatus.DOA_INVALID_RESHIPPED)
307
                        continue;
308
 
2310 ankur.sing 309
                    if(firstOrder) {
310
                        firstOrder = false;
311
                    } else {
312
                        paymentSerialNo++;
313
                        contentRow = paymentSheet.createRow(paymentSerialNo);
314
                    }
1631 ankur.sing 315
 
2310 ankur.sing 316
                    contentRow.createCell(ORDER_ID).setCellValue(o.getId());
317
                    contentRow.createCell(ORDER_STATUS).setCellValue(o.getStatus().name());
318
                    contentRow.createCell(ORDER_STATUS_DESC).setCellValue(o.getStatusDescription());
1631 ankur.sing 319
 
1660 ankur.sing 320
                    lineItems = tClient.getLineItemsForOrder(o.getId());
321
                    for (LineItem i : lineItems) {
322
                        /*
323
                         * Right now there can be only one line item in an
324
                         * order. So putting line item details in the same
325
                         * row as order details. Commenting below 2 lines
326
                         * for this.
327
                         */
328
                        // paymentSerialNo++;
329
                        // contentRow =
330
                        // paymentSheet.createRow(paymentSerialNo);
1631 ankur.sing 331
 
2310 ankur.sing 332
                        contentRow.createCell(ITEM_ID).setCellValue(i.getId());
333
                        contentRow.createCell(PROD_GRP).setCellValue(i.getProductGroup());
334
                        contentRow.createCell(BRAND).setCellValue(i.getBrand());
335
                        contentRow.createCell(MOD_NAME).setCellValue(i.getModel_name());
336
                        contentRow.createCell(MOD_NUM).setCellValue(i.getModel_number());
337
                        contentRow.createCell(QTY).setCellValue(i.getQuantity());
1660 ankur.sing 338
                    }
339
                }
340
            } catch (TransactionServiceException e) {
3105 chandransh 341
                logger.error("Error in transaction service while getting orders", e);
1660 ankur.sing 342
            } catch (TException e) {
3105 chandransh 343
                logger.error("Error getting info from transaction service", e);
1660 ankur.sing 344
            }
345
        }
346
 
2310 ankur.sing 347
        for (int i = 0; i <= QTY; i++) {
348
            if (i == PAYMENT_METHOD || i == PAY_STATUS_DESC || i == ADDR) // Address Column is of fixed size with wrap text style
1660 ankur.sing 349
                continue;
350
            paymentSheet.autoSizeColumn(i);
351
        }
352
 
353
        // Write the workbook to the output stream
354
        try {
355
            wb.write(baosXLS);
356
            baosXLS.close();
357
        } catch (IOException e) {
3105 chandransh 358
            logger.error("Error while streaming payment details report", e);
1660 ankur.sing 359
        }
360
        return baosXLS;
361
    }
2310 ankur.sing 362
 
363
    public String getPaymentMethod(List<Attribute> paymentAttributes) {
364
        String paymentMethod = null;
365
        if(paymentAttributes == null || paymentAttributes.isEmpty()) {
366
            return "N/A";
367
        }
368
        for(Attribute a : paymentAttributes) {
369
            if("payMethod".equals(a.getName())) {
370
                paymentMethod = Constants.PAYMENT_METHOD.get(a.getValue());
371
                break;
372
            }
373
        }
374
        return paymentMethod != null ? paymentMethod : "N/A";
375
    }
376
 
1660 ankur.sing 377
    public static void main(String[] args) {
378
        DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
379
        Date startDate = null, endDate = null;
380
        try {
381
            startDate = df.parse("01/01/2011");
2090 ankur.sing 382
            endDate = df.parse("06/30/2011");
1660 ankur.sing 383
            Calendar cal = Calendar.getInstance();
384
            cal.setTime(endDate);
385
            cal.add(Calendar.DATE, 1);
386
            endDate.setTime(cal.getTimeInMillis());
387
        } catch (ParseException pe) {
3105 chandransh 388
            logger.error("Error parsing the supplied date", pe);
1660 ankur.sing 389
        }
390
        PaymentDetailsGenerator pdg = new PaymentDetailsGenerator();
391
        try {
392
            String userHome = System.getProperty("user.home");
393
            FileOutputStream f = new FileOutputStream(userHome + "/payment-details-report.xls");
1881 ankur.sing 394
            ByteArrayOutputStream baosXLS = pdg.generatePaymentDetailsReport(startDate, endDate, 1);
1660 ankur.sing 395
            baosXLS.writeTo(f);
396
            f.close();
397
        } catch (FileNotFoundException e) {
3105 chandransh 398
            logger.error("Error creating payment details report", e);
1660 ankur.sing 399
        } catch (IOException e) {
3105 chandransh 400
            logger.error("IO error while creating payment details report", e);
1660 ankur.sing 401
        }
402
        System.out.println("Successfully generated the payment details report");
403
    }
1631 ankur.sing 404
}