Subversion Repositories SmartDukaan

Rev

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