Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
27391 tejbeer 1
package com.spice.profitmandi.web.controller;
2
 
29943 amit.gupta 3
import com.jcraft.jsch.*;
29900 amit.gupta 4
import com.spice.profitmandi.common.enumuration.MessageType;
27391 tejbeer 5
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
6
import com.spice.profitmandi.common.model.CustomRetailer;
27876 amit.gupta 7
import com.spice.profitmandi.common.model.ProfitMandiConstants;
29900 amit.gupta 8
import com.spice.profitmandi.common.model.SendNotificationModel;
29904 amit.gupta 9
import com.spice.profitmandi.common.util.FormattingUtils;
27876 amit.gupta 10
import com.spice.profitmandi.common.web.util.ResponseSender;
35501 ranu 11
import com.spice.profitmandi.dao.entity.catalog.BrandCatalog;
27391 tejbeer 12
import com.spice.profitmandi.dao.entity.catalog.Offer;
13
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
14
import com.spice.profitmandi.dao.enumuration.catalog.ItemCriteriaType;
30651 amit.gupta 15
import com.spice.profitmandi.dao.enumuration.catalog.OfferSchemeType;
27391 tejbeer 16
import com.spice.profitmandi.dao.model.CreateOfferRequest;
34176 tejus.loha 17
import com.spice.profitmandi.dao.model.ItemCriteriaPayout;
35501 ranu 18
import com.spice.profitmandi.dao.model.TodayOfferModel;
34552 amit.gupta 19
import com.spice.profitmandi.dao.repository.catalog.*;
27391 tejbeer 20
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
29926 amit.gupta 21
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
29900 amit.gupta 22
import com.spice.profitmandi.service.NotificationService;
29785 amit.gupta 23
import com.spice.profitmandi.service.authentication.RoleManager;
33043 amit.gupta 24
import com.spice.profitmandi.service.catalog.BrandsService;
34176 tejus.loha 25
import com.spice.profitmandi.service.offers.ItemCriteria;
27876 amit.gupta 26
import com.spice.profitmandi.service.offers.OfferService;
35501 ranu 27
import com.spice.profitmandi.service.offers.TodayOfferService;
27391 tejbeer 28
import com.spice.profitmandi.service.user.RetailerService;
29
import com.spice.profitmandi.web.model.LoginDetails;
30
import com.spice.profitmandi.web.util.CookiesProcessor;
31
import com.spice.profitmandi.web.util.MVCResponseSender;
29943 amit.gupta 32
import org.apache.commons.io.FileUtils;
33
import org.apache.commons.io.output.ByteArrayOutputStream;
34
import org.apache.logging.log4j.LogManager;
35
import org.apache.logging.log4j.Logger;
36
import org.springframework.beans.factory.annotation.Autowired;
32868 amit.gupta 37
import org.springframework.beans.factory.annotation.Value;
29943 amit.gupta 38
import org.springframework.cache.CacheManager;
39
import org.springframework.core.io.InputStreamResource;
40
import org.springframework.http.HttpHeaders;
41
import org.springframework.http.HttpStatus;
42
import org.springframework.http.ResponseEntity;
32204 amit.gupta 43
import org.springframework.mock.web.MockHttpServletRequest;
44
import org.springframework.mock.web.MockHttpServletResponse;
29943 amit.gupta 45
import org.springframework.stereotype.Controller;
35501 ranu 46
import org.springframework.transaction.annotation.Transactional;
29943 amit.gupta 47
import org.springframework.ui.Model;
48
import org.springframework.web.bind.annotation.*;
49
import org.springframework.web.multipart.MultipartFile;
32204 amit.gupta 50
import org.springframework.web.servlet.View;
51
import org.springframework.web.servlet.ViewResolver;
29943 amit.gupta 52
import org.xhtmlrenderer.swing.Java2DRenderer;
27391 tejbeer 53
 
29943 amit.gupta 54
import javax.imageio.ImageIO;
55
import javax.servlet.http.HttpServletRequest;
56
import java.awt.*;
57
import java.awt.image.BufferedImage;
58
import java.io.ByteArrayInputStream;
59
import java.io.File;
60
import java.io.FileNotFoundException;
61
import java.io.InputStream;
33713 tejus.loha 62
import java.time.Instant;
63
import java.time.LocalDate;
64
import java.time.LocalDateTime;
65
import java.time.YearMonth;
35501 ranu 66
import java.util.List;
35205 amit 67
import java.util.*;
29943 amit.gupta 68
import java.util.stream.Collectors;
69
 
27391 tejbeer 70
@Controller
35458 amit 71
@Transactional(rollbackFor = Throwable.class)
27391 tejbeer 72
public class OfferController {
32505 amit.gupta 73
    private static final Logger LOGGER = LogManager.getLogger(OfferController.class);
74
    private static final String IMAGE_REMOTE_DIR = "/var/www/dtrdashboard/uploads/campaigns/";
75
    private static final String IMAGE_STATIC_SERVER_URL = "https://images.smartdukaan.com/uploads/campaigns";
76
    @Autowired
77
    UserAccountRepository userAccountRepository;
78
    @Autowired
79
    RoleManager roleManager;
80
    @Autowired
81
    private OfferRepository offerRepository;
82
    @Autowired
83
    private OfferMarginRepository offerMarginRepository;
84
    @Autowired
85
    private FofoStoreRepository fofoStoreRepository;
86
    @Autowired
87
    private ResponseSender responseSender;
88
    @Autowired
89
    private ViewResolver viewResolver;
90
    @Autowired
91
    private ItemRepository itemRepository;
92
    @Autowired
93
    private MVCResponseSender mvcResponseSender;
94
    @Autowired
95
    private RetailerService retailerService;
96
    @Autowired
97
    private NotificationService notificationService;
98
    @Autowired
99
    private CookiesProcessor cookiesProcessor;
100
    @Autowired
101
    private OfferService offerService;
102
    @Autowired
103
    private CacheManager oneDayCacheManager;
27391 tejbeer 104
 
33043 amit.gupta 105
    @Autowired
35857 amit 106
    private CacheManager redisCacheManager;
107
 
108
    @Autowired
109
    private CacheManager redisShortCacheManager;
110
 
111
    @Autowired
33043 amit.gupta 112
    BrandsService brandsService;
34553 amit.gupta 113
 
34552 amit.gupta 114
    @Autowired
115
    private CatalogRepository catalogRepository;
33043 amit.gupta 116
 
35501 ranu 117
    @Autowired
118
    TodayOfferService todayOfferService;
119
 
32505 amit.gupta 120
    @RequestMapping(value = "/getCreateOffer", method = RequestMethod.GET)
121
    public String getCreateOffer(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {
122
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
123
        List<Integer> fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId())
124
                .collect(Collectors.toList());
27391 tejbeer 125
 
33713 tejus.loha 126
        Set<String> brands = brandsService.getBrandsToDisplay(3).stream().map(x -> x.getName()).collect(Collectors.toSet());
32505 amit.gupta 127
        brands.addAll(itemRepository.selectAllBrands(ProfitMandiConstants.LED_CATEGORY_ID));
33615 amit.gupta 128
        brands.addAll(itemRepository.selectAllBrands(ProfitMandiConstants.SMART_WATCH_CATEGORY_ID));
32505 amit.gupta 129
        //Lets allow demo
130
        brands.add("Live Demo");
27391 tejbeer 131
 
32505 amit.gupta 132
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
27876 amit.gupta 133
 
32505 amit.gupta 134
        Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> customRetailerMap.get(x))
135
                .filter(x -> x != null).collect(Collectors.toList()).stream()
136
                .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
32204 amit.gupta 137
 
32505 amit.gupta 138
        model.addAttribute("customRetailersMap", customRetailersMap);
139
        model.addAttribute("itemCriteriaType", ItemCriteriaType.values());
140
        model.addAttribute("brands", brands);
141
        model.addAttribute("partnerCategories", PartnerType.values());
142
        model.addAttribute("warehouseRegion", ProfitMandiConstants.WAREHOUSE_MAP);
143
        return "scheme_offer";
27391 tejbeer 144
 
32505 amit.gupta 145
    }
29926 amit.gupta 146
 
32505 amit.gupta 147
    @RequestMapping(value = "/createOffer", method = RequestMethod.POST)
148
    public String createOffer(HttpServletRequest request, @RequestBody CreateOfferRequest createOfferRequest,
149
                              Model model) throws Exception {
150
        LOGGER.info("createOfferRequest [{}]", createOfferRequest);
151
        offerService.addOfferService(createOfferRequest);
32868 amit.gupta 152
        oneDayCacheManager.getCache("allOffers").evict(YearMonth.from(createOfferRequest.getStartDate()));
32505 amit.gupta 153
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
154
        return "response";
27391 tejbeer 155
 
32505 amit.gupta 156
    }
27391 tejbeer 157
 
32505 amit.gupta 158
    @RequestMapping(value = "/offers/published", method = RequestMethod.GET)
159
    public String getPublishedOffers(HttpServletRequest request, @RequestParam int fofoId, Model model)
160
            throws Exception {
161
        LOGGER.info("Published");
162
        offerService.getPublishedOffers(fofoId, YearMonth.from(LocalDateTime.now()));
163
        return "scheme_offer/published";
27391 tejbeer 164
 
32505 amit.gupta 165
    }
27391 tejbeer 166
 
32868 amit.gupta 167
    @Value("${prod}")
168
    private boolean isProd;
169
 
32505 amit.gupta 170
    @RequestMapping(value = "/offer/active/{offerId}", method = RequestMethod.GET)
171
    public String activateOffer(HttpServletRequest request, @PathVariable(name = "offerId") String offerIdsString,
172
                                Model model, @RequestParam(defaultValue = "true") boolean active)
173
            throws ProfitMandiBusinessException, Exception {
174
        List<Integer> offerIds = Arrays.stream(offerIdsString.split(",")).map(x -> Integer.parseInt(x))
175
                .collect(Collectors.toList());
176
        List<Offer> offers = offerRepository.selectAllByIds(offerIds);
32868 amit.gupta 177
 
178
        //Consider only offers that have opposite status
179
        offers = offers.stream().filter(x -> x.isActive() != active).collect(Collectors.toList());
180
 
181
        Set<YearMonth> yearMonthsToEvict = new HashSet<>();
32505 amit.gupta 182
        for (Offer offer : offers) {
32868 amit.gupta 183
            offer.setActive(active);
184
            yearMonthsToEvict.add(YearMonth.from(offer.getStartDate()));
32505 amit.gupta 185
        }
32868 amit.gupta 186
        //Evict caches
187
        for (YearMonth ymToEvict : yearMonthsToEvict) {
35857 amit 188
            redisCacheManager.getCache("catalog.published_yearmonth").evict(ymToEvict);
32868 amit.gupta 189
            oneDayCacheManager.getCache("allOffers").evict(ymToEvict);
32505 amit.gupta 190
        }
35857 amit 191
        redisShortCacheManager.getCache("publishedOffersWithAchievement").clear();
32868 amit.gupta 192
        if (active) {
193
            for (Offer offer : offers) {
32505 amit.gupta 194
                this.sendNotification(offer);
195
            }
196
        }
32868 amit.gupta 197
 
198
 
32505 amit.gupta 199
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
200
        return "response";
201
    }
27391 tejbeer 202
 
35857 amit 203
    @RequestMapping(value = "/offers/publishAll", method = RequestMethod.POST)
204
    public ResponseEntity<?> publishAllUnpublished(@RequestParam YearMonth yearMonth)
205
            throws ProfitMandiBusinessException, Exception {
206
        List<Offer> published = offerService.publishAllUnpublished(yearMonth);
207
        if (!published.isEmpty()) {
208
            redisCacheManager.getCache("catalog.published_yearmonth").evict(yearMonth);
209
            oneDayCacheManager.getCache("allOffers").evict(yearMonth);
210
            redisShortCacheManager.getCache("publishedOffersWithAchievement").clear();
211
            for (Offer offer : published) {
212
                this.sendNotification(offer);
213
            }
214
        }
215
        return responseSender.ok(published.size() + " offers published");
216
    }
217
 
218
    @RequestMapping(value = "/offer/delete/{offerId}", method = RequestMethod.DELETE)
219
    public ResponseEntity<?> deleteOffer(@PathVariable int offerId) throws ProfitMandiBusinessException {
220
        offerService.deleteOffer(offerId);
221
        return responseSender.ok(true);
222
    }
223
 
32505 amit.gupta 224
    @RequestMapping(value = "/offer/testimage/{offerId}", method = RequestMethod.GET)
225
    public String testOffer(HttpServletRequest request, @PathVariable int offerId, Model model,
226
                            @RequestParam(defaultValue = "true") boolean active) throws ProfitMandiBusinessException, Exception {
227
        Offer offer = offerRepository.selectById(offerId);
228
        // model.addAttribute("response1", mvcResponseSender.createResponseString(true));
229
        // return "response";
230
        CreateOfferRequest createOfferRequest = offerService.getCreateOfferRequest(offer);
231
        Map<String, Object> model1 = new HashMap<>();
232
        model1.put("offer", createOfferRequest);
233
        model1.put("lessThan", "<");
234
        String htmlContent = this.getContentFromTemplate("offer_margin_detail_notify", model1);
235
        model.addAttribute("response1", htmlContent);
236
        return "response";
237
    }
29900 amit.gupta 238
 
32505 amit.gupta 239
    private void sendNotification(Offer offer) throws Exception {
240
        if (!YearMonth.from(offer.getStartDate()).equals(YearMonth.now())) {
241
            return;
242
        }
243
        String fileName = "offer-" + offer.getId() + ".png";
32868 amit.gupta 244
        //String htmlFileName = fileName.replace("png", "html");
32505 amit.gupta 245
        CreateOfferRequest createOfferRequest = offerService.getCreateOfferRequest(offer);
34620 amit.gupta 246
        boolean isLiveDemo = createOfferRequest.getTargetSlabs().stream()
247
                .map(x -> x.getItemCriteriaPayouts())
248
                .flatMap(List::stream)
249
                .map(ItemCriteriaPayout::getItemCriteria)
250
                .map(ItemCriteria::getCatalogIds)
251
                .flatMap(List::stream)
252
                .anyMatch(catalogId -> catalogRepository.selectCatalogById(catalogId).getBrand().equals("Live Demo"));
253
        if (!isLiveDemo) {
254
            SendNotificationModel sendNotificationModel = new SendNotificationModel();
255
            sendNotificationModel.setCampaignName("SchemeOffer");
256
            sendNotificationModel.setTitle(offer.getName());
257
            sendNotificationModel.setMessage(createOfferRequest.getSchemeType().name() + " of select models, "
258
                    + FormattingUtils.formatDateMonth(offer.getStartDate()) + " to "
259
                    + FormattingUtils.formatDateMonth(offer.getEndDate()));
260
            sendNotificationModel.setType("url");
261
            String imageUrl = IMAGE_STATIC_SERVER_URL + "/" + "image" + LocalDate.now() + "/" + fileName;
262
            sendNotificationModel.setImageUrl(imageUrl);
263
            sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");
264
            sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));
265
            sendNotificationModel.setMessageType(MessageType.scheme);
266
            //Map<Integer, List<Offer>> offersMap = offerRepository.selectAllPublishedMapByPartner(YearMonth.now());
29900 amit.gupta 267
 
34620 amit.gupta 268
            Map<String, InputStream> fileStreamsMap = new HashMap<>();
269
            Map<String, Object> model = new HashMap<>();
270
            model.put("offer", createOfferRequest);
271
            String htmlContent = this.getContentFromTemplate("offer_margin_detail_notify", model);
272
            LOGGER.info("this.getContentFromTemplate {}", htmlContent);
273
            fileStreamsMap.put(fileName, this.getImageBuffer(htmlContent));
274
            // fileStreamsMap.put(htmlFileName, new
275
            // ByteArrayInputStream(htmlContent.getBytes()));
276
            List<Integer> fofoIds = null;
277
            if (isProd) {
278
                this.uploadFile(fileStreamsMap);
279
            }
280
 
281
            List<Integer> fofoIdSet = new ArrayList<>(offerRepository.getEligibleFofoIds(offer));
282
            //LOGGER.info(fofoIdSet);
283
            List<Integer> userIds = userAccountRepository.selectUserIdsByRetailerIds(new ArrayList<>(fofoIdSet));
284
            sendNotificationModel.setUserIds(userIds);
285
            notificationService.sendNotification(sendNotificationModel);
286
            sendWhatsapp(offer, fofoIds, imageUrl);
32868 amit.gupta 287
        }
32505 amit.gupta 288
    }
27876 amit.gupta 289
 
32505 amit.gupta 290
    private void sendWhatsapp(Offer offer, List<Integer> fofoIds, String imageUrl) throws Exception {
35205 amit 291
        offerService.sendWhatsapp(offer, fofoIds, imageUrl);
32505 amit.gupta 292
    }
27391 tejbeer 293
 
32505 amit.gupta 294
    private InputStream asInputStream(BufferedImage bi) throws Exception {
295
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
296
        ImageIO.write(bi, "png", baos);
297
        return new ByteArrayInputStream(baos.toByteArray());
27391 tejbeer 298
 
32505 amit.gupta 299
    }
27391 tejbeer 300
 
32505 amit.gupta 301
    private ChannelSftp setupJsch() throws JSchException {
302
        JSch jsch = new JSch();
33471 amit.gupta 303
        Session jschSession = jsch.getSession("root", "172.105.58.16");
32505 amit.gupta 304
        // Session jschSession = jsch.getSession("root", "173.255.254.24");
305
        LOGGER.info("getClass().getResource(\"id_rsa\") {}",
306
                getClass().getClassLoader().getResource("id_rsa").getPath());
307
        jsch.addIdentity(getClass().getClassLoader().getResource("id_rsa").getPath());
308
        // jschSession.setPassword("spic@2015static0");
309
        jschSession.setConfig("StrictHostKeyChecking", "no");
310
        jschSession.connect();
311
        return (ChannelSftp) jschSession.openChannel("sftp");
312
    }
30426 tejbeer 313
 
32505 amit.gupta 314
    private void fileUpload(ChannelSftp channelSftp, Map<String, InputStream> streamsFileMap, String destinationPath)
315
            throws SftpException, FileNotFoundException {
27391 tejbeer 316
 
32505 amit.gupta 317
        channelSftp.cd(destinationPath);
318
        String folderName = "image" + LocalDate.now();
27391 tejbeer 319
 
32505 amit.gupta 320
        channelSftp.cd(destinationPath);
321
        SftpATTRS attrs = null;
27391 tejbeer 322
 
32505 amit.gupta 323
        // check if the directory is already existing
324
        try {
325
            attrs = channelSftp.stat(folderName);
326
        } catch (Exception e) {
327
            System.out.println(destinationPath + "/" + folderName + " not found");
328
        }
27391 tejbeer 329
 
32505 amit.gupta 330
        // else create a directory
331
        if (attrs == null) {
332
            channelSftp.mkdir(folderName);
333
            channelSftp.chmod(0755, ".");
334
        }
335
        channelSftp.cd(folderName);
27391 tejbeer 336
 
32505 amit.gupta 337
        for (Map.Entry<String, InputStream> streamsFileEntry : streamsFileMap.entrySet()) {
338
            channelSftp.put(streamsFileEntry.getValue(), streamsFileEntry.getKey(), ChannelSftp.OVERWRITE);
339
        }
27391 tejbeer 340
 
32505 amit.gupta 341
    }
29926 amit.gupta 342
 
32505 amit.gupta 343
    private void uploadFile(Map<String, InputStream> fileStreamsMap) throws Exception {
344
        ChannelSftp channelSftp = setupJsch();
345
        channelSftp.connect();
346
        this.fileUpload(channelSftp, fileStreamsMap, IMAGE_REMOTE_DIR + "");
347
        channelSftp.exit();
348
    }
27391 tejbeer 349
 
32505 amit.gupta 350
    private InputStream getImageBuffer(String html) throws Exception {
29900 amit.gupta 351
 
32505 amit.gupta 352
        String fileName = "/tmp/" + Instant.now().toEpochMilli();
353
        FileUtils.writeStringToFile(new File(fileName), html, "UTF-8");
354
        String address = "file:" + fileName;
355
        Java2DRenderer renderer = new Java2DRenderer(address, 400);
356
        RenderingHints hints = new RenderingHints(RenderingHints.KEY_COLOR_RENDERING,
357
                RenderingHints.VALUE_COLOR_RENDER_QUALITY);
358
        hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
359
        hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
360
        hints.add(new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC));
361
        renderer.setRenderingHints(hints);
362
        BufferedImage img = renderer.getImage();
363
        ByteArrayOutputStream os = new ByteArrayOutputStream();
364
        ImageIO.write(img, "png", os);
365
        return new ByteArrayInputStream(os.toByteArray());
366
    }
29926 amit.gupta 367
 
32505 amit.gupta 368
    private String getContentFromTemplate(String template, Map<String, Object> model) throws Exception {
369
        View resolvedView = viewResolver.resolveViewName(template, Locale.US);
370
        MockHttpServletResponse mockResp = new MockHttpServletResponse();
371
        MockHttpServletRequest req = new MockHttpServletRequest();
372
        LOGGER.info("Resolved view ->  {}, {}, {}, {}", resolvedView, model, req, mockResp);
373
        resolvedView.render(model, req, mockResp);
374
        return mockResp.getContentAsString();
375
    }
29926 amit.gupta 376
 
32505 amit.gupta 377
    @RequestMapping(value = "/offerHistory", method = RequestMethod.GET)
378
    public String getPaginatedOffers(HttpServletRequest request, @RequestParam YearMonth yearMonth, Model model)
379
            throws ProfitMandiBusinessException {
30017 amit.gupta 380
 
32505 amit.gupta 381
        List<CreateOfferRequest> publishedOffers = offerService.getAllOffers(yearMonth).values().stream()
382
                .sorted(Comparator.comparing(CreateOfferRequest::getId).reversed()).collect(Collectors.toList());
383
        model.addAttribute("offers", publishedOffers);
384
        model.addAttribute("yearMonth", yearMonth);
385
        model.addAttribute("currentMonth", yearMonth.equals(YearMonth.now()));
29926 amit.gupta 386
 
32505 amit.gupta 387
        return "offer_history";
388
    }
30723 amit.gupta 389
 
32505 amit.gupta 390
    @RequestMapping(value = "/offer-details", method = RequestMethod.GET)
391
    public String schemeDetails(HttpServletRequest request, @RequestParam int offerId, Model model)
392
            throws ProfitMandiBusinessException {
393
        CreateOfferRequest createOfferRequest = offerService.getOffer(0, offerId);
29900 amit.gupta 394
 
32505 amit.gupta 395
        model.addAttribute("offer", createOfferRequest);
396
        return "offer-details";
397
    }
29926 amit.gupta 398
 
32505 amit.gupta 399
    @RequestMapping(value = "/offer/process/{offerId}", method = RequestMethod.GET)
400
    public ResponseEntity<?> processOfferRequest(HttpServletRequest request, @PathVariable int offerId, Model model)
401
            throws Exception {
402
        CreateOfferRequest createOfferRequest = offerService.getOffer(0, offerId);
403
        if (!createOfferRequest.isActive()) {
404
            throw new ProfitMandiBusinessException("Offer not active", "Offer not active", "Offer not active");
405
        }
406
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {
407
            offerService.processSellin(createOfferRequest);
408
        } else if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
409
            offerService.processActivationtOffer(createOfferRequest);
410
        }
411
        return responseSender.ok(true);
412
    }
29926 amit.gupta 413
 
32505 amit.gupta 414
    @RequestMapping(value = "/offerDownload", method = RequestMethod.GET)
415
    public ResponseEntity<?> dowloadOfferSummary(HttpServletRequest request, @RequestParam int offerId, Model model)
416
            throws Exception {
417
        final HttpHeaders headers = new HttpHeaders();
418
        headers.set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
419
        headers.set("Content-disposition", "inline; filename=offer-" + offerId + ".csv");
420
        CreateOfferRequest createOfferRequest = offerService.getOffer(0, offerId);
33999 tejus.loha 421
        ByteArrayOutputStream baos = offerService.createCSVOfferReport(createOfferRequest);
32505 amit.gupta 422
        final InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
423
        final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
424
        return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
425
    }
29900 amit.gupta 426
 
32505 amit.gupta 427
    @RequestMapping(value = "/offerById", method = RequestMethod.GET)
428
    public String offerById(HttpServletRequest request, int offerId, Model model) throws ProfitMandiBusinessException {
429
        Offer offer = offerRepository.selectById(offerId);
430
        model.addAttribute("offer", offer);
431
        return "offer-edit";
29900 amit.gupta 432
 
32505 amit.gupta 433
    }
29900 amit.gupta 434
 
34176 tejus.loha 435
    @RequestMapping(value = "/published-offers", method = RequestMethod.GET)
436
    public String publishedOffersOnMonthBefore(HttpServletRequest request, @RequestParam int yearMonth, @RequestParam(required = false, defaultValue = "") String brandFilter, Model model)
32505 amit.gupta 437
            throws ProfitMandiBusinessException {
34176 tejus.loha 438
        LOGGER.info("publishedOffersCalled");
32505 amit.gupta 439
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
440
        int fofoId = loginDetails.getFofoId();
441
        List<CreateOfferRequest> createOffers = offerService.getPublishedOffers(fofoId,
442
                YearMonth.from(LocalDate.now()).minusMonths(yearMonth));
29900 amit.gupta 443
 
34617 amit.gupta 444
        List<CreateOfferRequest> publishedOffers = null;
445
        if (!brandFilter.isEmpty()) {
446
            publishedOffers = createOffers.stream()
34176 tejus.loha 447
                    .filter(createOffer -> createOffer.getTargetSlabs().stream()
448
                            .map(x -> x.getItemCriteriaPayouts())
449
                            .flatMap(List::stream)
450
                            .map(ItemCriteriaPayout::getItemCriteria)
451
                            .map(ItemCriteria::getBrands)
452
                            .flatMap(List::stream)
453
                            .anyMatch(brand -> brand.equals(brandFilter)))
454
                    .collect(Collectors.toList());
34617 amit.gupta 455
        } else {
456
            publishedOffers = createOffers.stream().filter(createOffer -> createOffer.getTargetSlabs().stream()
34557 amit.gupta 457
                    .map(x -> x.getItemCriteriaPayouts())
458
                    .flatMap(List::stream)
459
                    .map(ItemCriteriaPayout::getItemCriteria)
34559 amit.gupta 460
                    .map(ItemCriteria::getCatalogIds)
34557 amit.gupta 461
                    .flatMap(List::stream)
34559 amit.gupta 462
                    .noneMatch(catalogId -> catalogRepository.selectCatalogById(catalogId).getBrand().equals("Live Demo"))).collect(Collectors.toList());
34176 tejus.loha 463
        }
29926 amit.gupta 464
 
34176 tejus.loha 465
        model.addAttribute("publishedOffers", publishedOffers);
466
 
32505 amit.gupta 467
        return "published-offers";
468
    }
29926 amit.gupta 469
 
32505 amit.gupta 470
    @PostMapping(value = "/offers/upload")
471
    public String uploadOffers(HttpServletRequest request, @RequestPart("file") MultipartFile targetFile, Model model)
472
            throws Exception {
473
        offerService.createOffers(targetFile.getInputStream());
474
        model.addAttribute("response1", true);
475
        return "response";
476
    }
29926 amit.gupta 477
 
32505 amit.gupta 478
    @RequestMapping(value = "/getOfferMargins", method = RequestMethod.GET)
479
    public String getOfferMargins(HttpServletRequest request,
480
                                  @RequestParam(name = "offerId", defaultValue = "0") int offerId, Model model) throws Exception {
481
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
482
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
483
        CreateOfferRequest createOfferRequest = offerService.getOffer(isAdmin ? 0 : loginDetails.getFofoId(), offerId);
29900 amit.gupta 484
 
32505 amit.gupta 485
        model.addAttribute("offer", createOfferRequest);
35415 amit 486
        model.addAttribute("isAdmin", isAdmin);
29900 amit.gupta 487
 
32505 amit.gupta 488
        return "offer_margin_detail_partner";
30470 amit.gupta 489
 
32505 amit.gupta 490
    }
29900 amit.gupta 491
 
35501 ranu 492
    @RequestMapping(value = "/todayOffer")
493
    public String todayOffer(HttpServletRequest request, Model model, @RequestParam(name = "fofoId", defaultValue = "0") int fofoId) throws ProfitMandiBusinessException {
494
 
495
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
496
        if (fofoId == 0) {
497
            fofoId = loginDetails.getFofoId();
498
        }
499
        List<BrandCatalog> allBrands = brandsService.getBrandsToDisplay(3);
500
 
501
        // 1. IDs to exclude entirely
502
        List<Integer> excludedIds = Arrays.asList(132, 133, 28, 17, 125);
503
 
504
        // 2. Brands that must come first (in this specific order)
505
        List<String> priorityOrder = Arrays.asList("Samsung", "Oppo", "Vivo", "Xiaomi", "Realme");
506
 
507
        List<BrandCatalog> sortedBrands = allBrands.stream()
508
                .filter(brand -> !excludedIds.contains(brand.getId())) // Remove excluded
509
                .sorted((b1, b2) -> {
510
                    // Get the index of the brand name in our priority list
511
                    int index1 = priorityOrder.indexOf(b1.getName());
512
                    int index2 = priorityOrder.indexOf(b2.getName());
513
 
514
                    // If brand is NOT in priority list, give it a high index (move to bottom)
515
                    int p1 = (index1 != -1) ? index1 : Integer.MAX_VALUE;
516
                    int p2 = (index2 != -1) ? index2 : Integer.MAX_VALUE;
517
 
518
                    if (p1 != p2) {
519
                        return Integer.compare(p1, p2); // Sort by priority first
520
                    }
521
 
522
                    // If both are "Others", sort them alphabetically
523
                    return b1.getName().compareToIgnoreCase(b2.getName());
524
                })
525
                .collect(Collectors.toList());
526
 
527
        model.addAttribute("brands", sortedBrands);
528
        model.addAttribute("fofoId", fofoId);
529
        model.addAttribute("date", FormattingUtils.format(LocalDateTime.now()));
530
 
531
        return "today-offer";
532
    }
533
 
534
    @RequestMapping(value = "/todayOfferList")
535
    public String todayOfferList(HttpServletRequest request, Model model, @RequestParam String brand, @RequestParam(defaultValue = "0", required = false) int fofoId) throws ProfitMandiBusinessException {
536
 
537
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
538
        if (fofoId == 0) {
539
            fofoId = loginDetails.getFofoId();
540
        }
541
 
542
        List<String> brands = brandsService.getBrandsToDisplay(3).stream().map(x -> x.getName()).collect(Collectors.toList());
543
 
544
        List<TodayOfferModel> todayOfferModels = todayOfferService.findAllTodayOffer(brand, fofoId);
545
 
546
        List<TodayOfferModel> groupedOffers = todayOfferService.groupSameOffers(todayOfferModels);
547
        model.addAttribute("brands", brands);
35505 ranu 548
        model.addAttribute("fofoId", fofoId);
35501 ranu 549
        model.addAttribute("todayOfferModels", todayOfferModels);
550
        model.addAttribute("groupedOffers", groupedOffers);
551
 
552
 
553
        return "today-offer-list";
554
    }
555
 
556
    @RequestMapping(value = "/todayFofoOffer")
557
    public String todayFofoOffer(HttpServletRequest request, Model model, @RequestParam(name = "fofoId", defaultValue = "0") int fofoId) throws ProfitMandiBusinessException {
558
 
559
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
560
        if (fofoId == 0) {
561
            fofoId = loginDetails.getFofoId();
562
        }
563
        List<BrandCatalog> allBrands = brandsService.getBrandsToDisplay(3);
564
 
565
        // 1. IDs to exclude entirely
566
        List<Integer> excludedIds = Arrays.asList(132, 133, 28, 17, 125);
567
 
568
        // 2. Brands that must come first (in this specific order)
569
        List<String> priorityOrder = Arrays.asList("Samsung", "Oppo", "Vivo", "Xiaomi", "Realme");
570
 
571
        List<BrandCatalog> sortedBrands = allBrands.stream()
572
                .filter(brand -> !excludedIds.contains(brand.getId())) // Remove excluded
573
                .sorted((b1, b2) -> {
574
                    // Get the index of the brand name in our priority list
575
                    int index1 = priorityOrder.indexOf(b1.getName());
576
                    int index2 = priorityOrder.indexOf(b2.getName());
577
 
578
                    // If brand is NOT in priority list, give it a high index (move to bottom)
579
                    int p1 = (index1 != -1) ? index1 : Integer.MAX_VALUE;
580
                    int p2 = (index2 != -1) ? index2 : Integer.MAX_VALUE;
581
 
582
                    if (p1 != p2) {
583
                        return Integer.compare(p1, p2); // Sort by priority first
584
                    }
585
 
586
                    // If both are "Others", sort them alphabetically
587
                    return b1.getName().compareToIgnoreCase(b2.getName());
588
                })
589
                .collect(Collectors.toList());
590
 
591
        model.addAttribute("brands", sortedBrands);
592
        model.addAttribute("fofoId", fofoId);
593
        model.addAttribute("date", FormattingUtils.format(LocalDateTime.now()));
594
 
595
        return "today-fofo-offer";
596
    }
597
 
35886 amit 598
    // ===== Offer Partner & Target Management (Admin Only) =====
599
 
600
    @RequestMapping(value = "/offer/partners", method = RequestMethod.GET)
601
    public String getOfferPartners(HttpServletRequest request, @RequestParam int offerId, Model model) throws Exception {
602
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
603
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
604
            throw new ProfitMandiBusinessException("Unauthorized", "Unauthorized", "");
605
        }
606
        CreateOfferRequest offer = offerService.getOffer(0, offerId);
607
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
608
 
35888 amit 609
        // Partners are stored in partner_criteria JSON, not in offer_partners table
610
        List<Integer> partnerFofoIds = offer.getPartnerCriteria() != null
611
                ? offer.getPartnerCriteria().getFofoIds() : new ArrayList<>();
612
        if (partnerFofoIds == null) partnerFofoIds = new ArrayList<>();
613
 
35886 amit 614
        List<Integer> allFofoIds = fofoStoreRepository.selectActiveStores().stream()
615
                .map(x -> x.getId()).collect(Collectors.toList());
616
        Map<Integer, CustomRetailer> allRetailersMap = allFofoIds.stream()
617
                .map(id -> customRetailerMap.get(id))
618
                .filter(x -> x != null)
619
                .collect(Collectors.toMap(CustomRetailer::getPartnerId, x -> x));
620
 
621
        model.addAttribute("offer", offer);
622
        model.addAttribute("offerId", offerId);
35888 amit 623
        model.addAttribute("partnerFofoIds", partnerFofoIds);
35886 amit 624
        model.addAttribute("customRetailerMap", customRetailerMap);
625
        model.addAttribute("allRetailersMap", allRetailersMap);
626
        return "offer_partners";
627
    }
628
 
629
    @RequestMapping(value = "/offer/removePartners", method = RequestMethod.POST)
630
    public ResponseEntity<?> removePartnersFromOffer(HttpServletRequest request,
631
            @RequestParam int offerId, @RequestParam List<Integer> fofoIds,
632
            @RequestParam(required = false, defaultValue = "false") boolean createNewOffer,
633
            @RequestParam(required = false) List<Integer> targets) throws Exception {
634
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
635
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
636
            throw new ProfitMandiBusinessException("Unauthorized", "Unauthorized", "");
637
        }
638
        Offer offer = offerRepository.selectById(offerId);
639
        YearMonth ym = YearMonth.from(offer.getStartDate());
640
 
641
        offerService.removePartnersFromOffer(offerId, fofoIds);
642
 
643
        Integer newOfferId = null;
644
        String message;
645
        if (createNewOffer && targets != null && !targets.isEmpty()) {
646
            newOfferId = offerService.cloneOfferForPartners(offerId, fofoIds, targets);
647
            message = "Partner(s) removed from Offer #" + offerId + ". New Offer #" + newOfferId + " created (Unpublished).";
648
        } else {
649
            message = "Partner(s) removed from Offer #" + offerId + ".";
650
        }
651
 
652
        oneDayCacheManager.getCache("allOffers").evict(ym);
653
        redisCacheManager.getCache("catalog.published_yearmonth").evict(ym);
654
        redisShortCacheManager.getCache("publishedOffersWithAchievement").clear();
655
 
656
        Map<String, Object> response = new HashMap<>();
657
        response.put("message", message);
658
        response.put("newOfferId", newOfferId);
659
        response.put("yearMonth", ym.toString());
660
        return responseSender.ok(response);
661
    }
662
 
663
    @RequestMapping(value = "/offer/addPartners", method = RequestMethod.POST)
664
    public ResponseEntity<?> addPartnersToOffer(HttpServletRequest request,
665
            @RequestParam int offerId, @RequestParam List<Integer> fofoIds) throws Exception {
666
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
667
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
668
            throw new ProfitMandiBusinessException("Unauthorized", "Unauthorized", "");
669
        }
670
        offerService.addPartnersToOffer(offerId, fofoIds);
671
 
672
        Offer offer = offerRepository.selectById(offerId);
673
        YearMonth ym = YearMonth.from(offer.getStartDate());
674
        oneDayCacheManager.getCache("allOffers").evict(ym);
675
        redisCacheManager.getCache("catalog.published_yearmonth").evict(ym);
676
        redisShortCacheManager.getCache("publishedOffersWithAchievement").clear();
677
 
678
        Map<String, Object> response = new HashMap<>();
679
        response.put("message", "Partner(s) added to Offer #" + offerId + ".");
680
        response.put("yearMonth", ym.toString());
681
        return responseSender.ok(response);
682
    }
683
 
684
    @RequestMapping(value = "/offer/updateTargets", method = RequestMethod.POST)
685
    public ResponseEntity<?> updateOfferTargets(HttpServletRequest request,
686
            @RequestParam int offerId, @RequestParam List<Integer> targets) throws Exception {
687
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
688
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
689
            throw new ProfitMandiBusinessException("Unauthorized", "Unauthorized", "");
690
        }
691
        offerService.updateOfferTargets(offerId, targets);
692
 
693
        Offer offer = offerRepository.selectById(offerId);
694
        YearMonth ym = YearMonth.from(offer.getStartDate());
695
        oneDayCacheManager.getCache("allOffers").evict(ym);
696
        redisCacheManager.getCache("catalog.published_yearmonth").evict(ym);
697
        redisShortCacheManager.getCache("publishedOffersWithAchievement").clear();
698
 
699
        return responseSender.ok("Targets updated for Offer #" + offerId);
700
    }
701
 
27895 amit.gupta 702
}