Subversion Repositories SmartDukaan

Rev

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