Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
32044 tejbeer 1
package com.spice.profitmandi.service;
2
 
3
import java.text.DecimalFormat;
4
import java.text.NumberFormat;
5
import java.time.Duration;
6
import java.time.LocalDate;
7
import java.time.LocalDateTime;
8
import java.time.LocalTime;
9
import java.util.ArrayList;
10
import java.util.Arrays;
11
import java.util.HashMap;
12
import java.util.HashSet;
13
import java.util.List;
14
import java.util.Locale;
15
import java.util.Map;
16
import java.util.Map.Entry;
17
import java.util.Set;
18
import java.util.stream.Collectors;
19
 
20
import javax.mail.internet.InternetAddress;
21
import javax.mail.internet.MimeMessage;
22
 
23
import org.apache.commons.io.output.ByteArrayOutputStream;
24
import org.apache.logging.log4j.LogManager;
25
import org.apache.logging.log4j.Logger;
26
import org.springframework.beans.factory.annotation.Autowired;
27
import org.springframework.core.io.ByteArrayResource;
28
import org.springframework.core.io.InputStreamSource;
29
import org.springframework.mail.javamail.JavaMailSender;
30
import org.springframework.mail.javamail.MimeMessageHelper;
31
import org.springframework.stereotype.Component;
32
 
33
import com.spice.profitmandi.common.model.CustomRetailer;
34
import com.spice.profitmandi.common.util.FileUtil;
35
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
36
import com.spice.profitmandi.dao.entity.fofo.RetailerFilter;
37
import com.spice.profitmandi.dao.entity.transaction.Loan;
38
import com.spice.profitmandi.dao.model.BillingDaysAvg;
39
import com.spice.profitmandi.dao.model.LastSaleDateModel;
40
import com.spice.profitmandi.dao.model.RetailerFilterModel;
41
import com.spice.profitmandi.dao.model.RetailerPeformanceFilterModel;
42
import com.spice.profitmandi.dao.repository.cs.CsService;
43
import com.spice.profitmandi.dao.repository.dtr.RetailerFilterRepository;
44
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
45
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
46
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
47
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
48
import com.spice.profitmandi.service.transaction.SDCreditServiceImpl;
49
import com.spice.profitmandi.service.user.RetailerService;
50
 
51
@Component
52
public class PerformanceServiceImpl implements PerformanceService {
53
 
54
 
55
    @Autowired
56
    private PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;
57
 
58
    @Autowired
59
    private OrderRepository orderRepository;
60
 
61
    @Autowired
62
    private FofoOrderRepository fofoOrderRepository;
63
 
64
    @Autowired
65
    private FofoOrderItemRepository fofoOrderItemRepository;
66
 
67
    @Autowired
68
    private SDCreditServiceImpl sdCreditServiceImpl;
69
 
70
    @Autowired
71
    private RetailerService retailerService;
72
 
73
    @Autowired
74
    private CsService csService;
75
 
76
    @Autowired
77
    private JavaMailSender mailSender;
78
 
79
    @Autowired
80
    private RetailerFilterRepository retailerFilterRepository;
81
 
82
 
83
    private static final Logger LOGGER = LogManager.getLogger(PerformanceServiceImpl.class);
84
 
85
 
86
    @Override
87
    public List<RetailerPeformanceFilterModel> getPerformance(RetailerFilterModel retailerFilter, Map<Integer, CustomRetailer> customRetailers) {
88
        LocalDateTime curDate = LocalDate.now().atStartOfDay();
89
        LocalDateTime startDate = curDate.minusMonths(3);
90
        List<RetailerPeformanceFilterModel> retailerPerPeformanceFilterModels = new ArrayList<RetailerPeformanceFilterModel>();
91
        DecimalFormat decimalFormatter = new DecimalFormat("0.#");
92
 
32096 tejbeer 93
        Map<Integer, List<Loan>> duedateMap = new HashMap<Integer, List<Loan>>();
94
 
95
        Map<Integer, List<Loan>> defaultdateMap = new HashMap<Integer, List<Loan>>();
96
 
32044 tejbeer 97
        Map<Integer, BillingDaysAvg> billingDeliverAvgMap = new HashMap<Integer, BillingDaysAvg>();
98
        Map<Integer, Long> lastPurchaseMap = new HashMap<Integer, Long>();
99
        Map<Integer, Long> lastSaleMap = new HashMap<Integer, Long>();
100
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<Integer, PartnerDailyInvestment>();
101
        Map<Integer, Double> secondaryPartner = new HashMap<Integer, Double>();
102
 
103
        Map<Integer, Double> tertiaryPartner = new HashMap<Integer, Double>();
104
 
105
 
106
        if (retailerFilter.isCredit()) {
107
            List<Loan> dueDateLoans = sdCreditServiceImpl.getDueDateCrossLoan();
108
            List<Loan> defaultLoans = sdCreditServiceImpl.getDefaultLoan();
109
 
110
            if (!defaultLoans.isEmpty()) {
32096 tejbeer 111
                defaultdateMap = defaultLoans.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));
32044 tejbeer 112
            }
32096 tejbeer 113
            if (!dueDateLoans.isEmpty()) {
114
                duedateMap = dueDateLoans.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));
115
            }
32044 tejbeer 116
        }
117
 
32096 tejbeer 118
 
32044 tejbeer 119
        if (retailerFilter.isBilling()) {
120
            List<BillingDaysAvg> billingDeliveryAvg = orderRepository.selectBillingToDeliverAvg(startDate, LocalDateTime.now());
121
            if (!billingDeliveryAvg.isEmpty()) {
122
                billingDeliverAvgMap = billingDeliveryAvg.stream().filter(x -> x.getAvg() > 1).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
123
            }
124
        }
125
 
126
 
127
        if (retailerFilter.getSecondaryDays() != null) {
128
            List<LastSaleDateModel> purchaseOrders = orderRepository.getLastOrders();
129
            for (LastSaleDateModel purchaseOrder : purchaseOrders) {
32091 tejbeer 130
                long daysBetween = Duration.between(purchaseOrder.getDateTime().plusDays(1), LocalDateTime.now()).toDays();
32044 tejbeer 131
                if (daysBetween >= retailerFilter.getSecondaryDays()) {
132
                    lastPurchaseMap.put(purchaseOrder.getFofoId(), daysBetween);
133
                }
134
            }
135
        }
136
 
137
 
138
        if (retailerFilter.getTertiaryDays() != null) {
139
            List<LastSaleDateModel> saleOrders = fofoOrderRepository.getLastTertiaryOrders();
140
            for (LastSaleDateModel saleOrder : saleOrders) {
32091 tejbeer 141
                long daysBetween = Duration.between(saleOrder.getDateTime().plusDays(1), LocalDateTime.now()).toDays();
32044 tejbeer 142
                if (daysBetween >= retailerFilter.getTertiaryDays()) {
143
                    lastSaleMap.put(saleOrder.getFofoId(), daysBetween);
144
                }
145
            }
146
        }
147
 
148
 
149
        if (retailerFilter.getInvestmentPct() != null) {
32091 tejbeer 150
            List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository.selectAll(LocalDate.now().minusDays(1));
32044 tejbeer 151
            partnerDailyInvestmentMap = partnerDailyInvestments.stream().filter(x -> (100 - retailerFilter.getInvestmentPct()) <= x.getShortPercentage()).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
152
        }
153
 
154
 
155
        if (retailerFilter.getMtdsPct() != null) {
156
            Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
157
            Map<Integer, Double> secondarylmtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
158
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1));
159
 
160
            Set<Integer> fofoIds = new HashSet<>();
161
            fofoIds.addAll(secondaryMtd.keySet());
162
            fofoIds.addAll(secondarylmtd.keySet());
163
 
32096 tejbeer 164
 
32044 tejbeer 165
            for (Integer fofoId : fofoIds) {
166
                double mtdVal = 0;
167
                double lmtdVal = 0;
168
                if (secondaryMtd.get(fofoId) != null) {
169
                    mtdVal = secondaryMtd.get(fofoId);
170
                }
171
                if (secondarylmtd.get(fofoId) != null) {
172
                    lmtdVal = secondarylmtd.get(fofoId);
173
                }
174
 
175
                double value = (mtdVal / lmtdVal) * 100;
176
                if (value <= retailerFilter.getMtdsPct()) {
177
                    secondaryPartner.put(fofoId, value);
178
                }
32095 tejbeer 179
 
180
 
32044 tejbeer 181
            }
32095 tejbeer 182
 
32044 tejbeer 183
        }
184
 
185
 
32093 tejbeer 186
        if (retailerFilter.getMtdtPct() != null) {
32044 tejbeer 187
            Map<Integer, Double> lmtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
188
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1), 0, false);
189
            Map<Integer, Double> mtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX), 0, false);
190
 
191
            Set<Integer> fofoIds = new HashSet<>();
192
            fofoIds.addAll(lmtdSale.keySet());
193
            fofoIds.addAll(mtdSale.keySet());
194
 
195
            for (Integer fofoId : fofoIds) {
196
                double mtdVal = 0;
197
                double lmtdVal = 0;
198
                if (mtdSale.get(fofoId) != null) {
199
                    mtdVal = mtdSale.get(fofoId);
200
                }
201
                if (lmtdSale.get(fofoId) != null) {
202
                    lmtdVal = lmtdSale.get(fofoId);
203
                }
204
 
205
                double value = (mtdVal / lmtdVal) * 100;
32094 tejbeer 206
                if (value <= retailerFilter.getMtdtPct()) {
32044 tejbeer 207
                    tertiaryPartner.put(fofoId, value);
208
                }
209
            }
210
 
211
 
212
        }
213
 
32091 tejbeer 214
        LOGGER.info("tertiaryPartner {}", tertiaryPartner);
215
 
216
        LOGGER.info("secondaryPartner {}", secondaryPartner);
217
 
218
 
32044 tejbeer 219
        NumberFormat numberformat = NumberFormat.getNumberInstance(new Locale("en", "IN"));
220
 
221
 
222
        for (Entry<Integer, CustomRetailer> customRetailerEntry : customRetailers.entrySet()) {
223
            int fofoId = customRetailerEntry.getKey();
224
            RetailerPeformanceFilterModel retailerPeformanceFilterModel = new RetailerPeformanceFilterModel();
225
            if (retailerFilter.isCredit()) {
32096 tejbeer 226
 
227
                if (!duedateMap.isEmpty()) {
32102 tejbeer 228
                    if (duedateMap.containsKey(fofoId)) {
229
                        retailerPeformanceFilterModel.setCredit("Due");
230
                    }
32044 tejbeer 231
                }
32096 tejbeer 232
                if (!defaultdateMap.isEmpty()) {
32102 tejbeer 233
                    if (defaultdateMap.containsKey(fofoId)) {
32096 tejbeer 234
 
32102 tejbeer 235
                        retailerPeformanceFilterModel.setCredit("Default");
236
                    }
237
 
32096 tejbeer 238
                }
32044 tejbeer 239
            }
240
 
241
            if (retailerFilter.isBilling()) {
242
                if (!billingDeliverAvgMap.isEmpty()) {
243
                    if (billingDeliverAvgMap.containsKey(fofoId)) {
244
                        retailerPeformanceFilterModel.setBilling(billingDeliverAvgMap.get(fofoId).getAvg());
245
                    }
246
                }
247
            }
248
 
249
            if (retailerFilter.getInvestmentPct() != null) {
250
 
251
                if (!partnerDailyInvestmentMap.isEmpty()) {
252
                    if (partnerDailyInvestmentMap.containsKey(fofoId)) {
253
                        retailerPeformanceFilterModel.setInvestment(100 - partnerDailyInvestmentMap.get(fofoId).getShortPercentage());
254
                    }
255
                }
256
 
257
            }
258
 
259
            if (retailerFilter.getSecondaryDays() != null) {
260
                if (!lastPurchaseMap.isEmpty()) {
261
                    if (lastPurchaseMap.containsKey(fofoId)) {
262
                        retailerPeformanceFilterModel.setSecondaryDays(lastPurchaseMap.get(fofoId));
263
                    }
264
                }
265
 
266
            }
267
 
268
 
269
            if (retailerFilter.getTertiaryDays() != null) {
270
                if (!lastSaleMap.isEmpty()) {
271
                    if (lastSaleMap.containsKey(fofoId)) {
272
                        retailerPeformanceFilterModel.setTertiaryDays(lastSaleMap.get(fofoId));
273
                    }
274
                }
275
            }
276
 
277
 
278
            if (retailerFilter.getMtdsPct() != null) {
279
                if (!secondaryPartner.isEmpty()) {
280
                    if (secondaryPartner.containsKey(fofoId)) {
281
                        retailerPeformanceFilterModel.setMtds(Double.valueOf(numberformat.format(secondaryPartner.get(fofoId))));
282
                    }
283
                }
284
            }
285
 
286
 
287
            if (retailerFilter.getMtdtPct() != null) {
288
                if (!tertiaryPartner.isEmpty()) {
289
                    if (tertiaryPartner.containsKey(fofoId)) {
290
                        retailerPeformanceFilterModel.setMtdt(Double.valueOf(numberformat.format(tertiaryPartner.get(fofoId))));
291
                    }
292
                }
293
            }
294
 
295
            if (retailerPeformanceFilterModel.getBilling() != null || retailerPeformanceFilterModel.getCredit() != null || retailerPeformanceFilterModel.getInvestment() != null || retailerPeformanceFilterModel.getSecondaryDays() != null || retailerPeformanceFilterModel.getTertiaryDays() != null || retailerPeformanceFilterModel.getMtds() != null || retailerPeformanceFilterModel.getMtdt() != null) {
296
 
297
                retailerPeformanceFilterModel.setFofoId(fofoId);
298
                retailerPerPeformanceFilterModels.add(retailerPeformanceFilterModel);
299
            }
300
 
301
 
302
        }
303
 
304
        return retailerPerPeformanceFilterModels;
305
    }
306
 
307
    public void sendPartnerPerformanceEmail(Map<Integer, RetailerPeformanceFilterModel> partnersPerformanceMap, RetailerFilterModel retailerFilterModel, Map<Integer, CustomRetailer> customRetailers) throws Exception {
308
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
309
 
310
        LOGGER.info("retailerFilterModel {}", retailerFilterModel);
311
        for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
312
 
313
            Set<Integer> fofoIds = storeGuyEntry.getValue();
314
            List<List<?>> rows = new ArrayList<>();
315
            List<String> headers = Arrays.asList("Partner Name", "Code", "Credit- Due/Default", "Billing To Deliver", "Investment- Lower Than " + retailerFilterModel.getInvestmentPct() + "%", "Last Secondary-" + retailerFilterModel.getSecondaryDays() + "days", "Last Tertiary-" + retailerFilterModel.getTertiaryDays() + "days", "MTD Secondary < LMTD-" + retailerFilterModel.getMtdsPct() + "%", "MTD Tertiary < LMTD-" + retailerFilterModel.getMtdtPct() + "%");
316
 
317
 
318
            LOGGER.info("headers {}", headers);
319
 
320
            for (Integer fofoId : fofoIds) {
321
                RetailerPeformanceFilterModel retailerPerformanceFilterModel = partnersPerformanceMap.get(fofoId);
322
 
323
                LOGGER.info("retailerPerformanceFilterModel {}", retailerPerformanceFilterModel);
324
 
325
                if (retailerPerformanceFilterModel != null) {
326
                    rows.add(Arrays.asList(customRetailers.get(fofoId).getBusinessName(), customRetailers.get(fofoId).getCode(), retailerPerformanceFilterModel.getCredit(), retailerPerformanceFilterModel.getBilling(), retailerPerformanceFilterModel.getInvestment(), retailerPerformanceFilterModel.getSecondaryDays(), retailerPerformanceFilterModel.getTertiaryDays(), retailerPerformanceFilterModel.getMtds(), retailerPerformanceFilterModel.getMtdt()));
327
                }
328
 
329
            }
330
            if (!rows.isEmpty()) {
331
                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
32046 tejbeer 332
                this.sendMailWithAttachment(mailSender, new String[]{storeGuyEntry.getKey()}, null, "Partner Performance", "PFA", "PartnerPerformance.csv", new ByteArrayResource(baos.toByteArray()));
32044 tejbeer 333
            }
334
 
335
        }
336
 
337
 
338
    }
339
 
340
    public void sendMailWithAttachment(JavaMailSender mailSender, String[] emailTo, String[] cc, String subject, String body, String fileName, InputStreamSource inputStreamSource) throws Exception {
341
        MimeMessage message = mailSender.createMimeMessage();
342
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
343
        helper.setSubject(subject);
344
        helper.setText(body);
345
        if (cc != null) {
346
            helper.setCc(cc);
347
        }
348
        helper.setTo(emailTo);
349
        helper.addAttachment(fileName, inputStreamSource);
350
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "SmartDukaan Care");
351
        helper.setFrom(senderAddress);
352
        mailSender.send(message);
353
    }
354
 
355
 
356
    public RetailerFilterModel getRetailerFilterModel() {
357
        List<RetailerFilter> retailerFilters = retailerFilterRepository.selectAll();
358
 
359
        RetailerFilterModel retailerFilterModel = new RetailerFilterModel();
360
 
361
        for (RetailerFilter retailerFilter : retailerFilters) {
362
            if (retailerFilter.getName().equals("BillingToDeliverAvg")) {
363
                retailerFilterModel.setBilling(true);
364
            }
365
 
366
            if (retailerFilter.getName().equals("credit due/default")) {
367
                retailerFilterModel.setCredit(true);
368
            }
369
            if (retailerFilter.getName().equals("Investment")) {
370
                retailerFilterModel.setInvestmentPct(retailerFilter.getValue());
371
            }
372
            if (retailerFilter.getName().equals("Last Secondary")) {
373
                retailerFilterModel.setSecondaryDays(retailerFilter.getValue());
374
            }
375
            if (retailerFilter.getName().equals("Last Tertiary")) {
376
                retailerFilterModel.setTertiaryDays(retailerFilter.getValue());
377
            }
378
            if (retailerFilter.getName().equals("Secondary")) {
379
                retailerFilterModel.setMtdsPct(20);
380
            }
381
            if (retailerFilter.getName().equals("Tertiary")) {
382
                retailerFilterModel.setMtdtPct(20);
383
            }
384
 
385
 
386
        }
387
        return retailerFilterModel;
388
    }
389
 
390
 
391
}