Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
1901 vikas 1
package in.shop2020.support.controllers;
2
 
2340 vikas 3
import in.shop2020.model.v1.order.LineItem;
4
import in.shop2020.model.v1.order.Order;
2980 vikas 5
import in.shop2020.model.v1.order.OrderStatus;
1901 vikas 6
import in.shop2020.model.v1.user.Affiliate;
7
import in.shop2020.model.v1.user.MasterAffiliate;
8
import in.shop2020.model.v1.user.TrackLog;
3378 vikas 9
import in.shop2020.model.v1.user.TrackLogType;
3213 chandransh 10
import in.shop2020.model.v1.user.UserAffiliateException;
1901 vikas 11
import in.shop2020.model.v1.user.UserContextService.Client;
2340 vikas 12
import in.shop2020.payments.Payment;
3293 vikas 13
import in.shop2020.support.utils.ReportsUtils;
3125 rajveer 14
import in.shop2020.thrift.clients.PaymentClient;
15
import in.shop2020.thrift.clients.TransactionClient;
16
import in.shop2020.thrift.clients.UserClient;
1901 vikas 17
 
18
import java.io.ByteArrayOutputStream;
19
import java.io.IOException;
3293 vikas 20
import java.text.DateFormat;
21
import java.text.ParseException;
22
import java.text.SimpleDateFormat;
2501 vikas 23
import java.util.ArrayList;
3293 vikas 24
import java.util.Calendar;
1901 vikas 25
import java.util.Date;
26
import java.util.HashMap;
2393 vikas 27
import java.util.HashSet;
1901 vikas 28
import java.util.List;
29
import java.util.Map;
3315 vikas 30
import java.util.Map.Entry;
2393 vikas 31
import java.util.Set;
3315 vikas 32
import java.util.SortedSet;
33
import java.util.TimeZone;
34
import java.util.TreeSet;
1901 vikas 35
 
36
import javax.servlet.ServletOutputStream;
37
import javax.servlet.http.HttpServletRequest;
38
import javax.servlet.http.HttpServletResponse;
3293 vikas 39
import javax.servlet.http.HttpSession;
1901 vikas 40
 
41
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
42
import org.apache.poi.ss.usermodel.Cell;
43
import org.apache.poi.ss.usermodel.CellStyle;
44
import org.apache.poi.ss.usermodel.CreationHelper;
45
import org.apache.poi.ss.usermodel.Font;
46
import org.apache.poi.ss.usermodel.Row;
47
import org.apache.poi.ss.usermodel.Sheet;
48
import org.apache.poi.ss.usermodel.Workbook;
49
import org.apache.poi.ss.util.CellRangeAddress;
3293 vikas 50
import org.apache.struts2.convention.annotation.InterceptorRef;
51
import org.apache.struts2.convention.annotation.InterceptorRefs;
3936 chandransh 52
import org.apache.struts2.convention.annotation.Result;
53
import org.apache.struts2.convention.annotation.Results;
1901 vikas 54
import org.apache.struts2.interceptor.ServletRequestAware;
55
import org.apache.struts2.interceptor.ServletResponseAware;
3213 chandransh 56
import org.apache.thrift.TException;
57
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
1901 vikas 59
 
2904 chandransh 60
/**
61
 * Provides reports about successful registrations and orders place through an
62
 * affiliate.
63
 * 
64
 * @author Vikas Malik
65
 * 
66
 */
3293 vikas 67
@InterceptorRefs({
68
    @InterceptorRef("defaultStack"),
69
    @InterceptorRef("login")
70
})
3936 chandransh 71
@Results({
72
    @Result(name="authfail", type="redirectAction", params = {"actionName" , "reports"})
73
})
3293 vikas 74
public class AffiliateController implements ServletRequestAware, ServletResponseAware{
1901 vikas 75
 
3293 vikas 76
    private static Logger log = LoggerFactory.getLogger(AffiliateController.class);
3213 chandransh 77
 
1901 vikas 78
	private HttpServletResponse response;
79
	private HttpServletRequest request;
3293 vikas 80
	private HttpSession session;
81
 
1901 vikas 82
	private String errorMsg = "";
83
	private List<MasterAffiliate> masterAffiliates;
3315 vikas 84
	private Date startDate = null;
85
	private Date endDate = null;
1901 vikas 86
 
87
	@Override
88
	public void setServletResponse(HttpServletResponse res) {
89
		this.response = res;
90
	}
91
 
92
	@Override
93
    public void setServletRequest(HttpServletRequest req) {
94
	    this.request = req;
3293 vikas 95
        this.session = req.getSession();
1901 vikas 96
    }
97
 
98
	public String index()  {
3293 vikas 99
	    log.info(request.getServletPath());
100
        if (!ReportsUtils.canAccessReport(
101
                (Long) session.getAttribute(ReportsUtils.ROLE),
102
                request.getServletPath())) 
103
        {
3936 chandransh 104
            return "authfail";
3293 vikas 105
        }
1901 vikas 106
        try {
3125 rajveer 107
        	UserClient userContextServiceClient = new UserClient();
1901 vikas 108
            Client userClient = userContextServiceClient.getClient();
109
            masterAffiliates = userClient.getAllMasterAffiliates();
110
        } catch (Exception e) {
3293 vikas 111
            log.error("Error while getting all affiliates", e);
1901 vikas 112
        }
113
        return "report";
114
    }
115
 
116
	public String create()	{
117
	    try   {
118
	        long mAfId = Long.parseLong(request.getParameter("masterAffiliate"));
3315 vikas 119
	        String mAffName;
3293 vikas 120
	        String startDateStr = request.getParameter("startDate");
121
	        String endDateStr = request.getParameter("endDate");
122
 
123
	        DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
3315 vikas 124
	        df.setTimeZone(TimeZone.getTimeZone("IST"));
3293 vikas 125
	        try {
126
	            startDate = df.parse(startDateStr);
127
	            endDate = df.parse(endDateStr);
128
	            Calendar cal = Calendar.getInstance();
129
	            cal.setTime(endDate);
130
	            endDate.setTime(cal.getTimeInMillis());
131
	        } catch (ParseException pe) {
132
	            errorMsg = "Please enter start and end dates in format MM/dd/yyyy";
133
	            return "report";
134
	        }
135
 
3125 rajveer 136
	        UserClient userContextServiceClient = new UserClient();
137
            PaymentClient paymentServiceClient = new PaymentClient();
138
            TransactionClient transactionServiceClient = new TransactionClient();
2340 vikas 139
 
1901 vikas 140
            Client userClient = userContextServiceClient.getClient();
2340 vikas 141
            in.shop2020.payments.PaymentService.Client paymentClient = paymentServiceClient.getClient();
142
 
2501 vikas 143
            List<Affiliate> affiliates;
144
            if (mAfId == -1) {
3315 vikas 145
                mAffName = "All";
2501 vikas 146
                affiliates = new ArrayList<Affiliate>();
147
                for(MasterAffiliate mAffiliate : userClient.getAllMasterAffiliates()) {
148
                    affiliates.addAll(userClient.getAffiliatesByMasterAffiliate(mAffiliate.getId()));
149
                }
150
            }
151
            else {
152
                affiliates = userClient.getAffiliatesByMasterAffiliate(mAfId);
3315 vikas 153
                mAffName = userClient.getMasterAffiliateById(mAfId).getName();
2501 vikas 154
            }
2980 vikas 155
 
3315 vikas 156
            SortedSet<Date> dates = new TreeSet<Date>();
157
            Map<Date, Long> registerCountMap = new HashMap<Date, Long>();
158
            Map<Date, Double> saleQuantityMap = new HashMap<Date, Double>();
159
            Map<Date, Double> saleAmountMap = new HashMap<Date, Double>();
160
 
161
            Map<Date, Map<String, Double>> productQuantityMap = new HashMap<Date, Map<String, Double>>();
162
            Map<Date, Map<String, Double>> productAmountMap = new HashMap<Date, Map<String,Double>>();
163
 
2501 vikas 164
            for (Affiliate aff : affiliates) {
3315 vikas 165
                Set<Long> Payments = new HashSet<Long>(); // To deal with multiple refreshes on pay-success page.
3293 vikas 166
                for (TrackLog tracklog : userClient.getTrackLogsByAffiliate(aff.getId(), startDate.getTime(), endDate.getTime())) {
3315 vikas 167
                    Date date = df.parse(df.format(new Date(tracklog.getAddedOn())));
168
                    dates.add(date);
3378 vikas 169
                    if (tracklog.getEventType() == TrackLogType.NEW_REGISTRATION) {
3315 vikas 170
                        if (registerCountMap.containsKey(date)) {
171
                            Long count = registerCountMap.get(date);
172
                            registerCountMap.put(date, ++count);
173
                        }
174
                        else {
175
                            registerCountMap.put(date, 1l);
176
                        }
177
                    }
3378 vikas 178
                    else if (tracklog.getEventType() == TrackLogType.PAYMENT_SUCCESS) {
3343 vikas 179
                        long paymentId = Long.parseLong(tracklog.getData().replaceAll("\\(.*\\)", ""));
3315 vikas 180
                        if (Payments.contains(paymentId)) {
181
                            continue;
182
                        }
183
                        Payments.add(paymentId);
184
                        Payment payment = paymentClient.getPayment(paymentId);
185
                        List<Order> orders = transactionServiceClient.getClient().getOrdersForTransaction(
186
                                        payment.getMerchantTxnId(),
187
                                        payment.getUserId());
188
                        for (Order order : orders) {
3341 vikas 189
                            if (order.getStatus() == OrderStatus.DELIVERY_SUCCESS) {
3315 vikas 190
                                List<LineItem> items = order.getLineitems();
191
                                if (saleAmountMap.containsKey(date)) {
192
                                    Double amount = saleAmountMap.get(date);
193
                                    amount += order.getTotal_amount();
194
                                    saleAmountMap.put(date, amount);
2980 vikas 195
                                }
3315 vikas 196
                                else {
197
                                    saleAmountMap.put(date, order.getTotal_amount());
198
                                }
2340 vikas 199
                                for (LineItem item : items) {
3315 vikas 200
                                    if (saleQuantityMap.containsKey(date)) {
201
                                        Double quantity = saleQuantityMap.get(date);
202
                                        quantity += item.getQuantity();
203
                                        saleQuantityMap.put(date, quantity);
204
                                    }
205
                                    else {
206
                                        saleQuantityMap.put(date, item.getQuantity());
207
                                    }
208
 
209
                                    String productName = item.getBrand() + " "
2340 vikas 210
                                            + item.getModel_name() + " "
3315 vikas 211
                                            + item.getModel_number();
212
                                    productName = productName.replace("null", "").replaceAll("  ", " ").trim();
213
                                    if (productQuantityMap.containsKey(date)) {
214
                                        Map<String, Double> pQuantityMap = productQuantityMap.get(date);
215
                                        if (pQuantityMap.containsKey(productName)) {
216
                                            Double quantity = pQuantityMap.get(productName);
217
                                            quantity += item.getQuantity();
218
                                            pQuantityMap.put(productName, quantity);
219
                                        }
220
                                        else {
221
                                            pQuantityMap.put(productName, item.getQuantity());
222
                                        }
223
                                    }
224
                                    else {
225
                                        Map<String, Double> pQuantityMap = new HashMap<String, Double>();
226
                                        pQuantityMap.put(productName, item.getQuantity());
227
                                        productQuantityMap.put(date, pQuantityMap);
228
                                    }
229
 
230
                                    if (productAmountMap.containsKey(date)) {
231
                                        Map<String, Double> pAmountMap = productAmountMap.get(date);
232
                                        if (pAmountMap.containsKey(productName)) {
233
                                            Double amount = pAmountMap.get(productName);
234
                                            amount += item.getTotal_price();
235
                                            pAmountMap.put(productName, amount);
236
                                        }
237
                                        else {
238
                                            pAmountMap.put(productName, item.getTotal_price());
239
                                        }
240
                                    }
241
                                    else {
242
                                        Map<String, Double> pAmountMap = new HashMap<String, Double>();
243
                                        pAmountMap.put(productName, item.getTotal_price());
244
                                        productAmountMap.put(date, pAmountMap);
245
                                    }
2340 vikas 246
                                }
247
                            }
248
                        }
249
                    }
1901 vikas 250
                }
251
            }
3315 vikas 252
 
1901 vikas 253
            // Preparing XLS file for output
254
            response.setContentType("application/vnd.ms-excel");
255
 
3315 vikas 256
            response.setHeader("Content-disposition", "inline; filename=" + mAffName + "-affiliate-report" + ".xls");
1901 vikas 257
 
258
            ServletOutputStream sos;
259
            try {
3315 vikas 260
                ByteArrayOutputStream baos = getSpreadSheetData(mAffName, dates, registerCountMap, saleQuantityMap, saleAmountMap, productQuantityMap, productAmountMap);
1901 vikas 261
                sos = response.getOutputStream();
262
                baos.writeTo(sos);
263
                sos.flush();
264
            } catch (IOException e) {
3293 vikas 265
                log.error("Unable to stream the affiliates report", e);
1901 vikas 266
                errorMsg = "Failed to write to response.";
267
            }
3213 chandransh 268
        } catch (UserAffiliateException e) {
3293 vikas 269
            log.error("Error while getting affiliated users", e);
1901 vikas 270
            errorMsg = e.getMessage();
3213 chandransh 271
        } catch (TException e) {
3293 vikas 272
            log.error("Unable to get affiliated users", e);
3213 chandransh 273
            errorMsg = e.getMessage();
274
        } catch (Exception e) {
3293 vikas 275
            log.error("Unexpected exception", e);
3213 chandransh 276
            errorMsg = e.getMessage();
1901 vikas 277
        }
278
        return null;
279
	}
280
 
3315 vikas 281
    // Prepares the XLS worksheet object and fills in the data with proper formatting
282
	private ByteArrayOutputStream getSpreadSheetData(String mAffName, 
283
	        SortedSet<Date> dates,
284
            Map<Date, Long> registerCountMap,
285
            Map<Date, Double> saleQuantityMap,
286
            Map<Date, Double> saleAmountMap, 
287
            Map<Date, Map<String, Double>> productQuantityMap,
288
            Map<Date, Map<String, Double>> productAmountMap)
1901 vikas 289
	{
290
	    ByteArrayOutputStream baosXLS = new ByteArrayOutputStream();
291
 
292
		Workbook wb = new HSSFWorkbook();
293
 
294
	    Font font = wb.createFont();
295
	    font.setBoldweight(Font.BOLDWEIGHT_BOLD);
296
	    CellStyle style = wb.createCellStyle();
297
	    style.setFont(font);
298
 
299
	    CreationHelper createHelper = wb.getCreationHelper();
300
	    CellStyle dateCellStyle = wb.createCellStyle();
3315 vikas 301
	    dateCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("DD/MM/YYYY"));
1901 vikas 302
 
3315 vikas 303
	    createSummarySheet(mAffName, dates, registerCountMap, saleQuantityMap, saleAmountMap, wb, style, dateCellStyle);
304
	    createSaleDetailSheet(mAffName, dates, productQuantityMap, productAmountMap, wb, style, dateCellStyle);
1901 vikas 305
 
306
		// Write the workbook to the output stream
307
		try {
308
			wb.write(baosXLS);
309
			baosXLS.close();
310
		} catch (IOException e) {
3293 vikas 311
			log.error("Unable to get the byte array for the affiliate report", e);
1901 vikas 312
		}		
313
		return baosXLS;
314
	}
315
 
3315 vikas 316
    private void createSaleDetailSheet(String mAffName, SortedSet<Date> dates,
317
            Map<Date, Map<String, Double>> productQuantityMap,
318
            Map<Date, Map<String, Double>> productAmountMap, Workbook wb,
319
            CellStyle style, CellStyle dateCellStyle) {
320
        // Product Sales SHEET
321
        Sheet affSheet = wb.createSheet("Product Sales Report");
322
        short affSerialNo = 0;
323
 
324
        DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
325
 
326
        Row affTitleRow = affSheet.createRow(affSerialNo ++);
327
        Cell affTitleCell = affTitleRow.createCell(0);
328
        affTitleCell.setCellValue("Modelwise Sales Report");
329
        affTitleCell.setCellStyle(style);
330
        affSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 6));
331
 
332
        affSheet.createRow(affSerialNo ++);
333
        Row affNameRow = affSheet.createRow(affSerialNo ++);
334
        Cell affNameCell = affNameRow.createCell(0);
335
        affNameCell.setCellValue("Affiliate : " + mAffName);
336
        affNameCell.setCellStyle(style);
337
        affSheet.addMergedRegion(new CellRangeAddress(2, 2, 0, 6));
338
 
339
        Row affDateRangeRow = affSheet.createRow(affSerialNo ++);
340
        Cell affDateRangeCell = affDateRangeRow.createCell(0);
341
        affDateRangeCell.setCellValue("Date Range : " + df.format(startDate) + " - " + df.format(endDate));
342
        affDateRangeCell.setCellStyle(style);
343
        affSheet.addMergedRegion(new CellRangeAddress(3, 3, 0, 6));
344
 
345
        affSheet.createRow(affSerialNo ++);affSheet.createRow(affSerialNo ++);
346
 
347
        Row affHeaderRow = affSheet.createRow(affSerialNo++);
348
        affHeaderRow.createCell(0).setCellValue("Date");
349
        affHeaderRow.createCell(1).setCellValue("ProductName");
350
        affHeaderRow.createCell(2).setCellValue("Sales Count");
351
        affHeaderRow.createCell(3).setCellValue("Amount");
352
        for (int i=0; i<4 ;i++) {
353
            affHeaderRow.getCell(i).setCellStyle(style);
354
        }
355
 
3343 vikas 356
        Double totalQuantity = 0d;
357
        Double totalAmount = 0d;
3315 vikas 358
        for(Date date : dates) {
359
            if (!productQuantityMap.containsKey(date)) {
360
                continue;
361
            }
362
            for (Entry<String, Double> quantityEntry : productQuantityMap.get(date).entrySet()) {
363
                affSerialNo++;
364
                String prodName = quantityEntry.getKey();
365
                Double quantity = quantityEntry.getValue();
366
                Double amount = productAmountMap.get(date).get(prodName);
3343 vikas 367
                totalQuantity += quantity;
368
                totalAmount += amount;
3315 vikas 369
                Row commContentRow = affSheet.createRow(affSerialNo);
370
                commContentRow.createCell(0).setCellValue(date);
371
                commContentRow.getCell(0).setCellStyle(dateCellStyle);
372
                commContentRow.createCell(1).setCellValue(prodName);
373
                commContentRow.createCell(2).setCellValue(quantity);
374
                commContentRow.createCell(3).setCellValue(amount);
375
 
376
            }
377
        }
3343 vikas 378
        affSerialNo+=2;
379
        Row commContentRow = affSheet.createRow(affSerialNo);
380
        commContentRow.createCell(0).setCellValue("Total");
381
        commContentRow.createCell(1).setCellValue("");
382
        commContentRow.createCell(2).setCellValue(totalQuantity);
383
        commContentRow.createCell(3).setCellValue(totalAmount);
384
 
385
        for (int i = 0; i<4; i++) {
386
            affSheet.autoSizeColumn(i);
387
        }
3315 vikas 388
    }
389
 
390
    private void createSummarySheet(String mAffName, 
391
            SortedSet<Date> dates,
392
            Map<Date, Long> registerCountMap,
393
            Map<Date, Double> saleQuantityMap,
394
            Map<Date, Double> saleAmountMap, 
395
            Workbook wb, 
396
            CellStyle style,
397
            CellStyle dateCellStyle) 
398
    {
399
		// Summary SHEET
400
	    Sheet affSheet = wb.createSheet("Summary Report");
1901 vikas 401
	    short affSerialNo = 0;
3315 vikas 402
 
403
	    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
1901 vikas 404
 
405
	    Row affTitleRow = affSheet.createRow(affSerialNo ++);
406
	    Cell affTitleCell = affTitleRow.createCell(0);
3315 vikas 407
	    affTitleCell.setCellValue("Daily Stats Report");
1901 vikas 408
	    affTitleCell.setCellStyle(style);
409
	    affSheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 6));
410
 
411
	    affSheet.createRow(affSerialNo ++);
3315 vikas 412
	    Row affNameRow = affSheet.createRow(affSerialNo ++);
413
        Cell affNameCell = affNameRow.createCell(0);
414
        affNameCell.setCellValue("Affiliate : " + mAffName);
415
        affNameCell.setCellStyle(style);
416
        affSheet.addMergedRegion(new CellRangeAddress(2, 2, 0, 6));
417
 
418
        Row affDateRangeRow = affSheet.createRow(affSerialNo ++);
419
        Cell affDateRangeCell = affDateRangeRow.createCell(0);
420
        affDateRangeCell.setCellValue("Date Range : " + df.format(startDate) + " - " + df.format(endDate));
421
        affDateRangeCell.setCellStyle(style);
422
        affSheet.addMergedRegion(new CellRangeAddress(3, 3, 0, 6));
423
 
424
	    affSheet.createRow(affSerialNo ++);affSheet.createRow(affSerialNo ++);
1901 vikas 425
 
426
	    Row affHeaderRow = affSheet.createRow(affSerialNo++);
3315 vikas 427
	    affHeaderRow.createCell(0).setCellValue("Date");
428
	    affHeaderRow.createCell(1).setCellValue("New Registrations");
429
	    affHeaderRow.createCell(2).setCellValue("Sales Count");
430
	    affHeaderRow.createCell(3).setCellValue("Amount");
431
	    for (int i=0; i<4 ;i++) {
1901 vikas 432
	        affHeaderRow.getCell(i).setCellStyle(style);
433
	    }
434
 
3343 vikas 435
	    Double totalregisterCount = 0d;
436
        Double totalQuantity = 0d;
437
	    Double totalAmount = 0d;
438
        for(Date date : dates) {
3315 vikas 439
		    affSerialNo++;
1901 vikas 440
			Row commContentRow = affSheet.createRow(affSerialNo);
3315 vikas 441
			Long registerCount = registerCountMap.get(date);
442
			Double saleQuantity = saleQuantityMap.get(date);
443
			Double saleAmount = saleAmountMap.get(date);
444
			if (registerCount == null) {
445
			    registerCount = 0l;
2340 vikas 446
			}
3315 vikas 447
			if (saleQuantity == null) {
448
                saleQuantity = 0d;
449
            }
450
			if (saleAmount == null) {
451
                saleAmount = 0d;
452
            }
3343 vikas 453
			totalregisterCount += registerCount;
454
            totalQuantity += saleQuantity;
455
			totalAmount += saleAmount;
456
            commContentRow.createCell(0).setCellValue(date);
3315 vikas 457
			commContentRow.getCell(0).setCellStyle(dateCellStyle);
458
            commContentRow.createCell(1).setCellValue(registerCount);
459
			commContentRow.createCell(2).setCellValue(saleQuantity);
460
			commContentRow.createCell(3).setCellValue(saleAmount);
1901 vikas 461
		}
3343 vikas 462
        affSerialNo+=2;
463
        Row commContentRow = affSheet.createRow(affSerialNo);
464
        commContentRow.createCell(0).setCellValue("Total");
465
        commContentRow.createCell(1).setCellValue(totalregisterCount);
466
        commContentRow.createCell(2).setCellValue(totalQuantity);
467
        commContentRow.createCell(3).setCellValue(totalAmount);
468
 
3315 vikas 469
        for (int i = 0; i<4; i++) {
1901 vikas 470
            affSheet.autoSizeColumn(i);
471
        }
472
	}
473
 
474
	public String getErrorMsg() {
475
		return errorMsg;
476
	}
477
 
478
	public List<MasterAffiliate> getMasterAffiliates() {
479
        return masterAffiliates;
480
    }
2340 vikas 481
}