Rev 32855 | Rev 33119 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.spice.profitmandi.web.controller;import com.google.gson.Gson;import com.jcraft.jsch.*;import com.spice.profitmandi.common.enumuration.MessageType;import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;import com.spice.profitmandi.common.model.CustomRetailer;import com.spice.profitmandi.common.model.ProfitMandiConstants;import com.spice.profitmandi.common.model.SendNotificationModel;import com.spice.profitmandi.common.util.FileUtil;import com.spice.profitmandi.common.util.FormattingUtils;import com.spice.profitmandi.common.web.util.ResponseSender;import com.spice.profitmandi.dao.entity.catalog.Offer;import com.spice.profitmandi.dao.entity.fofo.PartnerType;import com.spice.profitmandi.dao.enumuration.catalog.ItemCriteriaType;import com.spice.profitmandi.dao.enumuration.catalog.OfferSchemeType;import com.spice.profitmandi.dao.model.CreateOfferRequest;import com.spice.profitmandi.dao.model.OfferRowModel;import com.spice.profitmandi.dao.repository.catalog.ItemRepository;import com.spice.profitmandi.dao.repository.catalog.OfferMarginRepository;import com.spice.profitmandi.dao.repository.catalog.OfferPartnerRepository;import com.spice.profitmandi.dao.repository.catalog.OfferRepository;import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;import com.spice.profitmandi.dao.repository.dtr.Mongo;import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;import com.spice.profitmandi.dao.repository.fofo.PartnerTypeChangeService;import com.spice.profitmandi.service.NotificationService;import com.spice.profitmandi.service.authentication.RoleManager;import com.spice.profitmandi.service.offers.OfferService;import com.spice.profitmandi.service.user.RetailerService;import com.spice.profitmandi.service.whatsapp.WhatsappMessageType;import com.spice.profitmandi.web.model.LoginDetails;import com.spice.profitmandi.web.util.CookiesProcessor;import com.spice.profitmandi.web.util.MVCResponseSender;import org.apache.commons.io.FileUtils;import org.apache.commons.io.output.ByteArrayOutputStream;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.apache.velocity.app.VelocityEngine;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.cache.CacheManager;import org.springframework.core.io.InputStreamResource;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.mock.web.MockHttpServletRequest;import org.springframework.mock.web.MockHttpServletResponse;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.View;import org.springframework.web.servlet.ViewResolver;import org.xhtmlrenderer.swing.Java2DRenderer;import javax.imageio.ImageIO;import javax.servlet.http.HttpServletRequest;import javax.transaction.Transactional;import java.awt.*;import java.awt.image.BufferedImage;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.InputStream;import java.time.*;import java.util.List;import java.util.*;import java.util.stream.Collectors;@Controller@Transactional(rollbackOn = Throwable.class)public class OfferController {private static final Logger LOGGER = LogManager.getLogger(OfferController.class);private static final String IMAGE_REMOTE_DIR = "/var/www/dtrdashboard/uploads/campaigns/";private static final String IMAGE_STATIC_SERVER_URL = "https://images.smartdukaan.com/uploads/campaigns";@AutowiredUserAccountRepository userAccountRepository;@AutowiredRoleManager roleManager;@Autowiredprivate OfferRepository offerRepository;@Autowiredprivate OfferMarginRepository offerMarginRepository;@Autowiredprivate FofoStoreRepository fofoStoreRepository;@Autowiredprivate ResponseSender responseSender;@Autowiredprivate ViewResolver viewResolver;@Autowiredprivate OfferPartnerRepository offerPartnerRepository;@Autowiredprivate ItemRepository itemRepository;@Autowiredprivate MVCResponseSender mvcResponseSender;@Autowiredprivate Gson gson;@Autowiredprivate RetailerService retailerService;@Autowiredprivate Mongo mongoClient;@Autowiredprivate NotificationService notificationService;@Autowiredprivate CookiesProcessor cookiesProcessor;@Autowiredprivate OfferService offerService;@Autowiredprivate CacheManager thirtyMinsTimeOutCacheManager;@Autowiredprivate CacheManager oneDayCacheManager;@Autowiredprivate PartnerTypeChangeService partnerTypeChangeService;@Autowiredprivate com.spice.profitmandi.dao.repository.dtr.UserRepository dtrUserRepository;@Autowiredprivate VelocityEngine velocityEngine;@RequestMapping(value = "/getCreateOffer", method = RequestMethod.GET)public String getCreateOffer(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);List<Integer> fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toList());Set<String> brands = mongoClient.getMongoBrands(loginDetails.getFofoId(), null, 3).stream().map(x -> (String) x.get("name")).collect(Collectors.toSet());brands.addAll(itemRepository.selectAllBrands(ProfitMandiConstants.LED_CATEGORY_ID));//Lets allow demobrands.add("Live Demo");Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));model.addAttribute("customRetailersMap", customRetailersMap);model.addAttribute("itemCriteriaType", ItemCriteriaType.values());model.addAttribute("brands", brands);model.addAttribute("partnerCategories", PartnerType.values());model.addAttribute("warehouseRegion", ProfitMandiConstants.WAREHOUSE_MAP);return "scheme_offer";}@RequestMapping(value = "/createOffer", method = RequestMethod.POST)public String createOffer(HttpServletRequest request, @RequestBody CreateOfferRequest createOfferRequest,Model model) throws Exception {LOGGER.info("createOfferRequest [{}]", createOfferRequest);offerService.addOfferService(createOfferRequest);oneDayCacheManager.getCache("allOffers").evict(YearMonth.from(createOfferRequest.getStartDate()));model.addAttribute("response1", mvcResponseSender.createResponseString(true));return "response";}@RequestMapping(value = "/offers/published", method = RequestMethod.GET)public String getPublishedOffers(HttpServletRequest request, @RequestParam int fofoId, Model model)throws Exception {LOGGER.info("Published");offerService.getPublishedOffers(fofoId, YearMonth.from(LocalDateTime.now()));return "scheme_offer/published";}@Value("${prod}")private boolean isProd;@RequestMapping(value = "/offer/active/{offerId}", method = RequestMethod.GET)public String activateOffer(HttpServletRequest request, @PathVariable(name = "offerId") String offerIdsString,Model model, @RequestParam(defaultValue = "true") boolean active)throws ProfitMandiBusinessException, Exception {List<Integer> offerIds = Arrays.stream(offerIdsString.split(",")).map(x -> Integer.parseInt(x)).collect(Collectors.toList());List<Offer> offers = offerRepository.selectAllByIds(offerIds);//Consider only offers that have opposite statusoffers = offers.stream().filter(x -> x.isActive() != active).collect(Collectors.toList());Set<YearMonth> yearMonthsToEvict = new HashSet<>();for (Offer offer : offers) {offer.setActive(active);yearMonthsToEvict.add(YearMonth.from(offer.getStartDate()));}//Evict cachesfor (YearMonth ymToEvict : yearMonthsToEvict) {oneDayCacheManager.getCache("catalog.published_yearmonth").evict(ymToEvict);oneDayCacheManager.getCache("allOffers").evict(ymToEvict);}if (active) {for (Offer offer : offers) {this.sendNotification(offer);}}model.addAttribute("response1", mvcResponseSender.createResponseString(true));return "response";}@RequestMapping(value = "/offer/testimage/{offerId}", method = RequestMethod.GET)public String testOffer(HttpServletRequest request, @PathVariable int offerId, Model model,@RequestParam(defaultValue = "true") boolean active) throws ProfitMandiBusinessException, Exception {Offer offer = offerRepository.selectById(offerId);// model.addAttribute("response1", mvcResponseSender.createResponseString(true));// return "response";CreateOfferRequest createOfferRequest = offerService.getCreateOfferRequest(offer);Map<String, Object> model1 = new HashMap<>();model1.put("offer", createOfferRequest);model1.put("lessThan", "<");String htmlContent = this.getContentFromTemplate("offer_margin_detail_notify", model1);model.addAttribute("response1", htmlContent);return "response";}private void sendNotification(Offer offer) throws Exception {if (!YearMonth.from(offer.getStartDate()).equals(YearMonth.now())) {return;}String fileName = "offer-" + offer.getId() + ".png";//String htmlFileName = fileName.replace("png", "html");CreateOfferRequest createOfferRequest = offerService.getCreateOfferRequest(offer);SendNotificationModel sendNotificationModel = new SendNotificationModel();sendNotificationModel.setCampaignName("SchemeOffer");sendNotificationModel.setTitle(offer.getName());sendNotificationModel.setMessage(createOfferRequest.getSchemeType().name() + " of select models, "+ FormattingUtils.formatDateMonth(offer.getStartDate()) + " to "+ FormattingUtils.formatDateMonth(offer.getEndDate()));sendNotificationModel.setType("url");String imageUrl = IMAGE_STATIC_SERVER_URL + "/" + "image" + LocalDate.now() + "/" + fileName;sendNotificationModel.setImageUrl(imageUrl);sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));sendNotificationModel.setMessageType(MessageType.scheme);Map<Integer, List<Offer>> offersMap = offerRepository.selectAllPublishedMapByPartner(YearMonth.now());Map<String, InputStream> fileStreamsMap = new HashMap<>();Map<String, Object> model = new HashMap<>();model.put("offer", createOfferRequest);String htmlContent = this.getContentFromTemplate("offer_margin_detail_notify", model);LOGGER.info("this.getContentFromTemplate {}", htmlContent);fileStreamsMap.put(fileName, this.getImageBuffer(htmlContent));// fileStreamsMap.put(htmlFileName, new// ByteArrayInputStream(htmlContent.getBytes()));List<Integer> fofoIds = null;if (isProd) {this.uploadFile(fileStreamsMap);}if (createOfferRequest.getPartnerCriteria().getRegionIds().size() > 0|| createOfferRequest.getPartnerCriteria().getFofoIds().size() > 0|| createOfferRequest.getPartnerCriteria().getPartnerTypes().size() > 0|| createOfferRequest.getPartnerCriteria().getExcludeFofoIds().size() > 0) {fofoIds = offersMap.entrySet().stream().filter(x -> x.getValue().contains(offer)).map(x -> x.getKey()).collect(Collectors.toList());List<Integer> userIds = userAccountRepository.selectUserIdsByRetailerIds(fofoIds);sendNotificationModel.setUserIds(userIds);notificationService.sendNotification(sendNotificationModel);} else {notificationService.sendNotificationToAll(sendNotificationModel);}this.sendWhatsapp(offer, fofoIds, imageUrl);}private void sendWhatsapp(Offer offer, List<Integer> fofoIds, String imageUrl) throws Exception {if (fofoIds == null) {fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toList());}final List<Integer> finalFofoIds = fofoIds;//List<String> mobileNumbers = retailerService.getAllFofoRetailers().entrySet().stream().filter(x -> finalFofoIds.contains(x.getKey())).map(x -> x.getValue().getMobileNumber()).collect(Collectors.toList());List<String> mobileNumbers = new ArrayList<>();mobileNumbers.add("9911565032");String message = "%s\n" +"On %s of select models\n" +"From %s to %s\n" +"\n" +"Happy Selling\n" +"Team Smartdukaan";//TV's mobilefor (String mobileNumber : mobileNumbers) {notificationService.sendWhatsappMediaMessage(String.format(message, offer.getName(),offer.getSchemeType().toString(), FormattingUtils.formatDate(offer.getStartDate()),FormattingUtils.formatDate(offer.getEndDate())), mobileNumber, imageUrl, "offer-" + offer.getId() + ".png", WhatsappMessageType.IMAGE);}}private InputStream asInputStream(BufferedImage bi) throws Exception {ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(bi, "png", baos);return new ByteArrayInputStream(baos.toByteArray());}private ChannelSftp setupJsch() throws JSchException {JSch jsch = new JSch();Session jschSession = jsch.getSession("root", "192.168.179.131");// Session jschSession = jsch.getSession("root", "173.255.254.24");LOGGER.info("getClass().getResource(\"id_rsa\") {}",getClass().getClassLoader().getResource("id_rsa").getPath());jsch.addIdentity(getClass().getClassLoader().getResource("id_rsa").getPath());// jschSession.setPassword("spic@2015static0");jschSession.setConfig("StrictHostKeyChecking", "no");jschSession.connect();return (ChannelSftp) jschSession.openChannel("sftp");}private void fileUpload(ChannelSftp channelSftp, Map<String, InputStream> streamsFileMap, String destinationPath)throws SftpException, FileNotFoundException {channelSftp.cd(destinationPath);String folderName = "image" + LocalDate.now();channelSftp.cd(destinationPath);SftpATTRS attrs = null;// check if the directory is already existingtry {attrs = channelSftp.stat(folderName);} catch (Exception e) {System.out.println(destinationPath + "/" + folderName + " not found");}// else create a directoryif (attrs == null) {channelSftp.mkdir(folderName);channelSftp.chmod(0755, ".");}channelSftp.cd(folderName);for (Map.Entry<String, InputStream> streamsFileEntry : streamsFileMap.entrySet()) {channelSftp.put(streamsFileEntry.getValue(), streamsFileEntry.getKey(), ChannelSftp.OVERWRITE);}}private void uploadFile(Map<String, InputStream> fileStreamsMap) throws Exception {ChannelSftp channelSftp = setupJsch();channelSftp.connect();this.fileUpload(channelSftp, fileStreamsMap, IMAGE_REMOTE_DIR + "");channelSftp.exit();}private InputStream getImageBuffer(String html) throws Exception {String fileName = "/tmp/" + Instant.now().toEpochMilli();FileUtils.writeStringToFile(new File(fileName), html, "UTF-8");String address = "file:" + fileName;Java2DRenderer renderer = new Java2DRenderer(address, 400);RenderingHints hints = new RenderingHints(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));hints.add(new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC));renderer.setRenderingHints(hints);BufferedImage img = renderer.getImage();ByteArrayOutputStream os = new ByteArrayOutputStream();ImageIO.write(img, "png", os);return new ByteArrayInputStream(os.toByteArray());}private String getContentFromTemplate(String template, Map<String, Object> model) throws Exception {View resolvedView = viewResolver.resolveViewName(template, Locale.US);MockHttpServletResponse mockResp = new MockHttpServletResponse();MockHttpServletRequest req = new MockHttpServletRequest();LOGGER.info("Resolved view -> {}, {}, {}, {}", resolvedView, model, req, mockResp);resolvedView.render(model, req, mockResp);return mockResp.getContentAsString();}@RequestMapping(value = "/offerHistory", method = RequestMethod.GET)public String getPaginatedOffers(HttpServletRequest request, @RequestParam YearMonth yearMonth, Model model)throws ProfitMandiBusinessException {List<CreateOfferRequest> publishedOffers = offerService.getAllOffers(yearMonth).values().stream().sorted(Comparator.comparing(CreateOfferRequest::getId).reversed()).collect(Collectors.toList());model.addAttribute("offers", publishedOffers);model.addAttribute("yearMonth", yearMonth);model.addAttribute("currentMonth", yearMonth.equals(YearMonth.now()));return "offer_history";}@RequestMapping(value = "/offer-details", method = RequestMethod.GET)public String schemeDetails(HttpServletRequest request, @RequestParam int offerId, Model model)throws ProfitMandiBusinessException {CreateOfferRequest createOfferRequest = offerService.getOffer(0, offerId);model.addAttribute("offer", createOfferRequest);return "offer-details";}@RequestMapping(value = "/offer/process/{offerId}", method = RequestMethod.GET)public ResponseEntity<?> processOfferRequest(HttpServletRequest request, @PathVariable int offerId, Model model)throws Exception {CreateOfferRequest createOfferRequest = offerService.getOffer(0, offerId);if (!createOfferRequest.isActive()) {throw new ProfitMandiBusinessException("Offer not active", "Offer not active", "Offer not active");}if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {offerService.processSellin(createOfferRequest);} else if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {offerService.processActivationtOffer(createOfferRequest);}return responseSender.ok(true);}@RequestMapping(value = "/offerDownload", method = RequestMethod.GET)public ResponseEntity<?> dowloadOfferSummary(HttpServletRequest request, @RequestParam int offerId, Model model)throws Exception {List<List<?>> listOfRows = new ArrayList<>();final HttpHeaders headers = new HttpHeaders();headers.set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");headers.set("Content-disposition", "inline; filename=offer-" + offerId + ".csv");CreateOfferRequest createOfferRequest = offerService.getOffer(0, offerId);Collection<OfferRowModel> offerRowModels = offerRepository.getOfferRows(createOfferRequest);ByteArrayOutputStream baos = null;if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {for (OfferRowModel offerRowModel : offerRowModels) {CustomRetailer customRetailer = retailerService.getFofoRetailer(offerRowModel.getFofoId());listOfRows.add(Arrays.asList(createOfferRequest.getId(), createOfferRequest.getName(),createOfferRequest.getTargetType(), createOfferRequest.getSchemeType(),createOfferRequest.getBrandShareTerms(), createOfferRequest.getSellinPercentage(),"--", createOfferRequest.getItemCriteriaString(),createOfferRequest.getStartDate(), createOfferRequest.getEndDate(),createOfferRequest.getCreatedOn(), customRetailer.getPartnerId(), customRetailer.getBusinessName(),customRetailer.getCode(), offerRowModel.getTotalBasePurchaseValue(), offerRowModel.getAchievedTarget(),offerRowModel.getPayoutPurchaseValue(), offerRowModel.getPayout(), offerRowModel.getPayoutType(), offerRowModel.getFinalPayout(), String.join(", ", offerRowModel.getEligibleImeis())));}baos = FileUtil.getCSVByteStream(Arrays.asList("Id", "Name", "Target Type", "Scheme Type", "Brand %", "Sellin %", "Partner Criteria","Item Criteria", "Start", "End", "Created", "Partner Id", "Partner Name", "Partner Code","Base Purchase", "Achieved Target", "Eligible Purchase", "Slab Amount", "Slab Amount Type", "Payout Value(Rs.)","Eligible IMEIs", "Billing Pending Imeis"), listOfRows);} else {for (OfferRowModel offerRowModel : offerRowModels) {CustomRetailer customRetailer = retailerService.getFofoRetailer(offerRowModel.getFofoId());listOfRows.add(Arrays.asList(createOfferRequest.getId(), createOfferRequest.getName(),createOfferRequest.getTargetType(), createOfferRequest.getSchemeType(),createOfferRequest.getBrandShareTerms(), createOfferRequest.getSellinPercentage(),createOfferRequest.getPartnerCriteriaString(), createOfferRequest.getItemCriteriaString(),createOfferRequest.getStartDate(), createOfferRequest.getEndDate(),createOfferRequest.getCreatedOn(), customRetailer.getPartnerId(), customRetailer.getBusinessName(),customRetailer.getCode(),offerRowModel.getTotalSale(),offerRowModel.getEligibleSale(),offerRowModel.getPayoutTargetAchieved(),offerRowModel.getPayoutValue(),offerRowModel.getPayoutType(),offerRowModel.getPayoutValueDp(), offerRowModel.getFinalPayout(),String.join(", ", offerRowModel.getEligibleImeis()),String.join(", ", offerRowModel.getBaseCriteria())));}baos = FileUtil.getCSVByteStream(Arrays.asList("Id", "Name", "Target Type", "Scheme Type", "Brand %", "Sellin %", "Partner Criteria","Item Criteria", "Start", "End", "Created", "Partner Id", "Partner Name", "Partner Code","Total Value","Eligible Value","Payout Target Achieved", "Payout Amount", "Payout Amount Type","Payout Value DP", "Amount to be credited", "Eligible Activated Imeis"), listOfRows);}final InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);}@RequestMapping(value = "/offerById", method = RequestMethod.GET)public String offerById(HttpServletRequest request, int offerId, Model model) throws ProfitMandiBusinessException {Offer offer = offerRepository.selectById(offerId);model.addAttribute("offer", offer);return "offer-edit";}@RequestMapping(value = "/published-offers/{yearMonth}", method = RequestMethod.GET)public String publishedOffersOnMonthBefore(HttpServletRequest request, @PathVariable int yearMonth, Model model)throws ProfitMandiBusinessException {LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);int fofoId = loginDetails.getFofoId();List<CreateOfferRequest> createOffers = offerService.getPublishedOffers(fofoId,YearMonth.from(LocalDate.now()).minusMonths(yearMonth));model.addAttribute("publishedOffers", createOffers);return "published-offers";}@PostMapping(value = "/offers/upload")public String uploadOffers(HttpServletRequest request, @RequestPart("file") MultipartFile targetFile, Model model)throws Exception {offerService.createOffers(targetFile.getInputStream());model.addAttribute("response1", true);return "response";}@RequestMapping(value = "/getOfferMargins", method = RequestMethod.GET)public String getOfferMargins(HttpServletRequest request,@RequestParam(name = "offerId", defaultValue = "0") int offerId, Model model) throws Exception {LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());CreateOfferRequest createOfferRequest = offerService.getOffer(isAdmin ? 0 : loginDetails.getFofoId(), offerId);model.addAttribute("offer", createOfferRequest);return "offer_margin_detail_partner";}}