Rev 35530 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.smartdukaan.cron.scheduled;import com.google.auth.oauth2.GoogleCredentials;import com.google.common.collect.Lists;import com.google.gson.Gson;import com.razorpay.Payment;import com.smartdukaan.cron.itelImeiActivation.ItelImeiActivationNewService;import com.smartdukaan.cron.itelImeiActivation.ItelImeiActivationService;import com.smartdukaan.cron.itelImeiActivation.TecnoImeiActivation;import com.smartdukaan.cron.migrations.RunOnceTasks;import com.smartdukaan.cron.scheduled.ambreports.AbmReportSender;import com.smartdukaan.cron.scheduled.runnables.PurchaseMigration;import com.spice.profitmandi.common.enumuration.*;import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;import com.spice.profitmandi.common.model.*;import com.spice.profitmandi.common.services.ReporticoService;import com.spice.profitmandi.common.services.mandii.MandiiService;import com.spice.profitmandi.common.util.FileUtil;import com.spice.profitmandi.common.util.FormattingUtils;import com.spice.profitmandi.common.util.PdfUtils;import com.spice.profitmandi.common.util.Utils;import com.spice.profitmandi.common.util.Utils.Attachment;import com.spice.profitmandi.common.web.client.RestClient;import com.spice.profitmandi.dao.Interface.Campaign;import com.spice.profitmandi.dao.cart.CartService;import com.spice.profitmandi.dao.cart.SmartCartService;import com.spice.profitmandi.dao.entity.auth.AuthUser;import com.spice.profitmandi.dao.entity.auth.PartnerCollectionRemark;import com.spice.profitmandi.dao.entity.catalog.*;import com.spice.profitmandi.dao.entity.catalog.Offer;import com.spice.profitmandi.dao.entity.cs.NonSdBuying;import com.spice.profitmandi.dao.entity.cs.Position;import com.spice.profitmandi.dao.entity.cs.Ticket;import com.spice.profitmandi.dao.entity.dtr.*;import com.spice.profitmandi.dao.entity.dtr.User;import com.spice.profitmandi.dao.entity.fofo.*;import com.spice.profitmandi.dao.entity.inventory.*;import com.spice.profitmandi.dao.entity.logistics.AST;import com.spice.profitmandi.dao.entity.logistics.ASTRepository;import com.spice.profitmandi.dao.entity.transaction.*;import com.spice.profitmandi.dao.entity.user.*;import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;import com.spice.profitmandi.dao.entity.warehouse.WarehouseScan;import com.spice.profitmandi.dao.enumuration.auth.CollectionRemark;import com.spice.profitmandi.dao.enumuration.catalog.StockTransactionType;import com.spice.profitmandi.dao.enumuration.cs.EscalationType;import com.spice.profitmandi.dao.enumuration.dtr.RefferalStatus;import com.spice.profitmandi.dao.enumuration.fofo.Gateway;import com.spice.profitmandi.dao.enumuration.fofo.PaymentStatus;import com.spice.profitmandi.dao.enumuration.fofo.ReturnType;import com.spice.profitmandi.dao.enumuration.fofo.ScanType;import com.spice.profitmandi.dao.enumuration.inventory.CatalogMovingEnum;import com.spice.profitmandi.dao.enumuration.inventory.VendorCatalogPricingStatus;import com.spice.profitmandi.dao.enumuration.transaction.CreditRisk;import com.spice.profitmandi.dao.enumuration.transaction.LoanReferenceType;import com.spice.profitmandi.dao.enumuration.transaction.PriceDropImeiStatus;import com.spice.profitmandi.dao.enumuration.transaction.SchemePayoutStatus;import com.spice.profitmandi.dao.model.*;import com.spice.profitmandi.dao.repository.GenericRepository;import com.spice.profitmandi.dao.repository.auth.AuthRepository;import com.spice.profitmandi.dao.repository.auth.NonSdBuyingRepository;import com.spice.profitmandi.dao.repository.auth.PartnerCollectionRemarkRepository;import com.spice.profitmandi.dao.repository.catalog.*;import com.spice.profitmandi.dao.repository.cs.CsService;import com.spice.profitmandi.dao.repository.cs.PartnerRegionRepository;import com.spice.profitmandi.dao.repository.cs.PositionRepository;import com.spice.profitmandi.dao.repository.cs.TicketRepository;import com.spice.profitmandi.dao.repository.dtr.*;import com.spice.profitmandi.dao.repository.fofo.*;import com.spice.profitmandi.dao.repository.inventory.*;import com.spice.profitmandi.dao.repository.logistics.WarehouseProviderRepository;import com.spice.profitmandi.dao.repository.transaction.*;import com.spice.profitmandi.dao.repository.trialOnboarding.TrialFormRepository;import com.spice.profitmandi.dao.repository.user.AddressRepository;import com.spice.profitmandi.dao.repository.user.LoiFormRepository;import com.spice.profitmandi.dao.repository.user.UserRepository;import com.spice.profitmandi.dao.repository.warehouse.*;import com.spice.profitmandi.dao.service.LiquidationService;import com.spice.profitmandi.dao.service.PurSaleService;import com.spice.profitmandi.dao.service.SidbiService;import com.spice.profitmandi.dao.service.biuedart.BluedartAuthService;import com.spice.profitmandi.dao.service.biuedart.BluedartService;import com.spice.profitmandi.dao.service.solr.FofoSolr;import com.spice.profitmandi.service.*;import com.spice.profitmandi.service.integrations.CCAvenuePaymentService;import com.spice.profitmandi.service.integrations.RazorpayPaymentService;import com.spice.profitmandi.service.integrations.bharti.model.BAGInsuranceModel;import com.spice.profitmandi.service.integrations.gstpro.GstProAuthService;import com.spice.profitmandi.service.integrations.gstpro.GstProService;import com.spice.profitmandi.service.integrations.pinelabs.dto.*;import com.spice.profitmandi.service.integrations.psismart.PsiSmartService;import com.spice.profitmandi.service.integrations.smartping.SmartPingService;import com.spice.profitmandi.service.integrations.toffee.ToffeeService;import com.spice.profitmandi.service.inventory.*;import com.spice.profitmandi.service.offers.OfferService;import com.spice.profitmandi.service.order.OrderService;import com.spice.profitmandi.service.pricecircular.PriceCircularService;import com.spice.profitmandi.service.pricing.PriceDropService;import com.spice.profitmandi.service.recharge.provider.OxigenRechargeProviderService;import com.spice.profitmandi.service.recharge.provider.ThinkWalnutDigitalRechargeProviderService;import com.spice.profitmandi.service.scheme.SchemeService;import com.spice.profitmandi.service.serviceConfig.ServiceConfigService;import com.spice.profitmandi.service.transaction.CreditBlockedExceptionPartnersRepository;import com.spice.profitmandi.service.transaction.CreditNoteService;import com.spice.profitmandi.service.transaction.SDCreditService;import com.spice.profitmandi.service.transaction.TransactionService;import com.spice.profitmandi.service.transaction.invoicing.InvoiceService;import com.spice.profitmandi.service.user.RetailerService;import com.spice.profitmandi.service.user.StoreTimelineTatService;import com.spice.profitmandi.service.wallet.CommonPaymentService;import com.spice.profitmandi.service.wallet.WalletService;import com.spice.profitmandi.service.warehouse.PurchaseOrderService;import com.spice.profitmandi.service.warehouse.WarehouseInventoryService;import com.spice.profitmandi.service.warehouse.WarehouseService;import in.shop2020.model.v1.order.OrderStatus;import in.shop2020.model.v1.order.WalletReferenceType;import org.apache.commons.io.output.ByteArrayOutputStream;import org.apache.commons.lang.StringUtils;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.HttpHostConnectException;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.hibernate.SessionFactory;import org.json.JSONObject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.io.ByteArrayResource;import org.springframework.core.io.InputStreamSource;import org.springframework.mail.javamail.JavaMailSender;import org.springframework.mail.javamail.MimeMessageHelper;import org.springframework.stereotype.Component;import org.springframework.transaction.annotation.Transactional;import javax.mail.MessagingException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import java.io.*;import java.math.BigDecimal;import java.math.RoundingMode;import java.nio.file.Files;import java.nio.file.Paths;import java.sql.Timestamp;import java.text.DecimalFormat;import java.time.*;import java.time.format.DateTimeFormatter;import java.time.temporal.ChronoField;import java.time.temporal.ChronoUnit;import java.util.*;import java.util.Map.Entry;import java.util.stream.Collectors;import java.util.stream.Stream;import static java.util.stream.Collectors.*;@Component@Transactional(rollbackFor = {Throwable.class, ProfitMandiBusinessException.class})public class ScheduledTasks {@Value("${oxigen.recharge.enquiry.url}")private String oxigenRechargeEnquiryUrl;@AutowiredPurchaseMigration purchaseMigration;@AutowiredSmartPingService smartPingService;@Autowiredprivate ASTRepository astRepository;@Autowiredprivate ServiceConfigService serviceConfigService;@Autowiredprivate TecnoImeiActivation tecnoImeiActivation;private static final DateTimeFormatter leadTimeFormatter = DateTimeFormatter.ofPattern("d LLL, hh:mm a");@Autowiredprivate PartnerRegionRepository partnerRegionRepository;@Autowiredprivate EmployeeAttendanceRepository employeeAttendanceRepository;@AutowiredVivoImeiActivationService vivoImeiActivationService;@AutowiredItelImeiActivationService itelImeiActivationService;@Autowiredprivate PartnerTypeChangeService partnerTypeChangeService;@Autowiredprivate LeadRepository leadRepository;@Autowiredprivate AuthRepository authRepository;@Autowiredprivate PriceDropService priceDropService;@Autowiredprivate FranchiseeVisitRepository franchiseeVisitRepository;@Autowiredprivate FranchiseeActivityRepository franchiseeActivityRepository;@Autowiredprivate HdfcPaymentRepository hdfcPaymentRepository;@Autowiredprivate CsService csService;@Autowiredprivate SaholicInventoryService saholicInventoryService;@Autowiredprivate InsurancePolicyRepository insurancePolicyRepository;@Autowiredprivate ToffeeService toffeeService;@Value("${oxigen.recharge.auth.key}")private String oxigenRechargeAuthKey;@Value("${oxigen.recharge.validation.url}")private String oxigenRechargeValidationUrl;@Value("${oxigen.recharge.validation.auth.key}")private String oxigenRechargeValidationAuthKey;@Value("${think.walnut.digital.recharge.transaction.mobile.url}")private String thinkWalnutDigitalRechargeTransactionMobileUrl;@Value("${think.walnut.digital.recharge.transaction.dth.url}")private String thinkWalnutDigitalRechargeTransactionDthUrl;@Value("${think.walnut.digital.recharge.enquiry.url}")private String thinkWalnutDigitalRechargeEnquiryUrl;@Value("${think.walnut.digital.recharge.balance.url}")private String thinkWalnutDigitalRechargeBalanceUrl;@Value("${think.walnut.digital.recharge.username}")private String thinkWalnutDigitalRechargeUserName;@Value("${think.walnut.digital.recharge.password}")private String thinkWalnutDigitalRechargePassword;@Value("${think.walnut.digital.recharge.auth.key}")private String thinkWalnutDigitalRechargeAuthKey;@Autowiredprivate PurchaseRepository purchaseRepository;@Autowiredprivate PriceDropIMEIRepository priceDropIMEIRepository;@AutowiredPriceDropRepository priceDropRepository;@Autowiredprivate PartnerTypeChangeRepository partnerTypeChangeRepository;@Autowiredprivate SchemeService schemeService;@Autowiredprivate ServiceConfigRepository serviceConfigRepository;@Autowiredprivate RetailerBlockBrandsRepository retailerBlockBrandsRepository;@Autowiredprivate LiquidationService liquidationService;private static final String[] STOCK_AGEING_MAIL_LIST = new String[]{"uday.singh@smartudkaan.com", "mohinder.mutreja@smartdukaan.com", "ankit.bhatia@smartdukaan.com", "tarun.verma@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "manish.gupta1@smartdukaan.com"};private static final String[] ITEMWISE_PENDING_INDENT_MAIL_LIST = new String[]{"kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com", "uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "niranjan.kala@smartdukaan.com"};private static final String[] INDENT_TERTIARY_MAIL_LIST = new String[]{"uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "nishant.ohri@smartdukaan.com", "vinay.p@smartdukaan.com", "deena.nath@smartdukaan.com", "shobhit.tandon@smartdukaan.com", "ritesh.chauhan1@smartdukaan.com"};private static final String[] EMPLOYEE_ATTENDANCE_MAIL_LIST = new String[]{"sm@smartdukaan.com", "sm@smartdukaan.com"};private List<OrderStatus> orderStatusList = Arrays.asList(OrderStatus.SUBMITTED_FOR_PROCESSING);@Autowiredprivate ReporticoService reporticoService;@Autowiredprivate PartnerInvestmentService partnerInvestmentService;@Autowiredprivate PositionRepository positionRepository;@Autowiredprivate FofoOrderItemRepository fofoOrderItemRepository;@Autowiredprivate NotificationService notificationService;@Autowiredprivate PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;@Autowiredprivate SchemeInOutRepository schemeInOutRepository;@Autowiredprivate RechargeTransactionRepository rechargeTransactionRepository;@Autowiredprivate CustomerAddressRepository customerAddressRepository;@Autowiredprivate RechargeProviderCreditWalletHistoryRepository rechargeProviderCreditWalletHistoryRepository;@Autowiredprivate FofoLineItemRepository fofoLineItemRepository;@Autowiredprivate FofoOrderRepository fofoOrderRepository;@Autowiredprivate UserWalletHistoryRepository userWalletHistoryRepository;@Autowiredprivate UserWalletRepository userWalletRepository;@Autowiredprivate InventoryItemRepository inventoryItemRepository;@Autowiredprivate WalletService walletService;@Autowiredprivate ThinkWalnutDigitalRechargeProviderService thinkWalnutDigitalRechargeProviderService;@Autowiredprivate OxigenRechargeProviderService oxigenRechargeProviderService;@Autowiredprivate RechargeProviderRepository rechargeProviderRepository;@Autowiredprivate ScanRecordRepository scanRecordRepository;@Autowiredprivate DailyRechargeRepository dailyRechargeRepository;@Autowiredprivate FofoStoreRepository fofoStoreRepository;@Value("${prod}")private boolean prod;@Autowiredprivate StateGstRateRepository stateGstRateRepository;@Autowiredprivate RetailerService retailerService;@Autowiredprivate BrandsRepository brandsRepository;@Autowiredprivate TransactionService transactionService;@Autowiredprivate ItemRepository itemRepository;@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate OrderService orderService;@Autowiredprivate SchemeRepository schemeRepository;@Autowiredprivate SchemeItemRepository schemeItemRepository;@Autowiredprivate JavaMailSender mailSender;@Autowiredprivate PartnerTargetRepository partnerTargetRepository;@Autowired@Qualifier(value = "googleMailSender")private JavaMailSender googleMailSender;@Autowiredprivate InventoryService inventoryService;@Autowiredprivate AddressRepository addressRepository;@Autowiredprivate RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;@Autowiredprivate Mongo mongoClient;@Autowiredprivate DeviceRepository deviceRepository;@Autowiredprivate PushNotificationRepository pushNotificationRepository;@Autowiredprivate NotificationCampaignRepository notificationCampaignRepository;@Autowiredprivate CurrentInventorySnapshotRepository currentInventorySnapshotRepository;@Autowiredprivate FocusedModelRepository focusedModelRepository;@Autowiredprivate UserAccountRepository userAccountRepository;@Autowiredprivate UserRepository userUserRepository;@Autowiredprivate com.spice.profitmandi.dao.repository.dtr.UserRepository dtrUserRepository;@Autowiredprivate UserCampaignRepository userCampaignRepository;@Autowiredprivate Gson gson;@Autowiredprivate TicketRepository ticketRepository;@Autowiredprivate RefferalRepository refferalRepository;@Autowiredprivate PartnerProblemRepository partnerProblemRepository;@Autowiredprivate PendingOrderRepository pendingOrderRepository;@Autowiredprivate PendingOrderItemRepository pendingOrderItemRepository;@Value("${razorpay.account.keyId}")private String keyId;@Value("${razorpay.account.keySecret}")private String keySecret;@Autowiredprivate RazorpayPaymentService razorPaymentService;@Autowiredprivate RazorPayRepository razorPayRepository;@Autowiredprivate PendingOrderService pendingOrderService;@Autowiredprivate CustomerRepository customerRepository;@Autowiredprivate RestClient restClient;@Autowiredprivate MandiiService mandiiService;@AutowiredCreditAccountRepository creditAccountRepository;@AutowiredCustomerOfferRepository customerOfferRepository;@AutowiredCustomerOfferItemRepository customerOfferItemRepository;@Autowiredprivate FofoSolr fofoSolr;private static final Logger LOGGER = LogManager.getLogger(ScheduledTasks.class);private String FCM_URL = "https://fcm.googleapis.com/v1/projects/api-project-309385327230/messages:send";private String FCM_SCOPED = "https://www.googleapis.com/auth/cloud-platform";@Autowiredprivate TagListingRepository tagListingRepository;@Autowiredprivate RunOnceTasks runOnceTasks;public void generateDailyRecharge() {List<RechargeProviderCreditWalletHistory> allCreditHistory = rechargeProviderCreditWalletHistoryRepository.selectAll(0, 2000);List<RechargeProvider> rechargeProviders = rechargeProviderRepository.selectAll();rechargeProviders.stream().forEach(x -> x.setAmount(0));rechargeProviders.stream().forEach(x -> {Map<LocalDate, List<RechargeProviderCreditWalletHistory>> dateWiseProviderCreditsMap = allCreditHistory.stream().filter(z -> z.getProviderId() == x.getId()).collect(groupingBy(x1 -> x1.getReceiveTimestamp().toLocalDate()));LOGGER.info("dateWiseProviderCreditsMap -{}", dateWiseProviderCreditsMap);LocalDate endDate = LocalDate.now().plusDays(1);float previousDayClosing = 0;LocalDate date = LocalDate.of(2018, 4, 6);while (date.isBefore(endDate)) {List<RechargeTransaction> dateWiseRechargeTransactions = rechargeTransactionRepository.selectAllBetweenTimestamp(Arrays.asList(RechargeStatus.values()), date.atStartOfDay(), date.plusDays(1).atStartOfDay());List<RechargeTransaction> successfulTransactions = dateWiseRechargeTransactions.stream().filter(y -> y.getStatus().equals(RechargeStatus.SUCCESS)).collect(Collectors.toList());float dailyAmount = 0;float totalCommission = 0;for (RechargeTransaction rechargeTransaction : successfulTransactions) {if (rechargeTransaction.getProviderId() == x.getId()) {dailyAmount += rechargeTransaction.getAmount();totalCommission += rechargeTransaction.getCommission();}}List<RechargeProviderCreditWalletHistory> rechargeHistoryList = dateWiseProviderCreditsMap.get(date);float dailyWalletRecharge = 0;if (rechargeHistoryList != null) {for (RechargeProviderCreditWalletHistory rechargeProviderCreditWalletHistory : rechargeHistoryList) {if (rechargeProviderCreditWalletHistory.getProviderId() == x.getId()) {dailyWalletRecharge += rechargeProviderCreditWalletHistory.getAmount();}}}if (dailyAmount > 0 || dailyWalletRecharge > 0) {DailyRecharge dailyRecharge = null;try {dailyRecharge = dailyRechargeRepository.selectByProviderIdAndCreateDate(x.getId(), date);} catch (Exception e) {LOGGER.info("Could not find Recharge entry");}if (dailyRecharge == null) {dailyRecharge = new DailyRecharge();dailyRecharge.setCreateDate(date);}dailyRecharge.setOpeningBalance(previousDayClosing);dailyRecharge.setProviderId(x.getId());dailyRecharge.setWalletRechargeAmount(dailyWalletRecharge);dailyRecharge.setTotalAmount(dailyAmount);dailyRecharge.setTotalCommission(totalCommission);float closingBalance = dailyRecharge.getOpeningBalance() + dailyWalletRecharge - dailyAmount;dailyRecharge.setClosingBalance(closingBalance);dailyRechargeRepository.persist(dailyRecharge);x.setAmount(x.getAmount() + dailyRecharge.getClosingBalance() - dailyRecharge.getOpeningBalance());previousDayClosing = dailyRecharge.getClosingBalance();}date = date.plusDays(1);}rechargeProviderRepository.persist(x);});LOGGER.info("finished generating daily recharge");}public void reconcileRecharge() throws Exception {LocalDateTime fromDate = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(30);LocalDateTime toDate = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);List<RechargeStatus> nonSuccessRechargeStatuses = new ArrayList<>(Arrays.asList(RechargeStatus.values()));LOGGER.info("nonSuccessRechargeStatuses {} ", nonSuccessRechargeStatuses);nonSuccessRechargeStatuses.remove(RechargeStatus.SUCCESS);nonSuccessRechargeStatuses.remove(RechargeStatus.FAILED);RechargeCredential thinkWalnutDigitalRechargeEnquiryCredential = new RechargeCredential();thinkWalnutDigitalRechargeEnquiryCredential.setRechargeUrl(thinkWalnutDigitalRechargeEnquiryUrl);thinkWalnutDigitalRechargeEnquiryCredential.setRechargeUserName(thinkWalnutDigitalRechargeUserName);thinkWalnutDigitalRechargeEnquiryCredential.setRechargePassword(thinkWalnutDigitalRechargePassword);thinkWalnutDigitalRechargeEnquiryCredential.setRechargeAuthKey(thinkWalnutDigitalRechargeAuthKey);Map<String, RechargeStatus> requestRechargeStatusChanged = new HashMap<>();List<RechargeTransaction> rechargeTransactions = rechargeTransactionRepository.selectAllBetweenTimestamp(nonSuccessRechargeStatuses, fromDate, toDate);for (RechargeTransaction rechargeTransaction : rechargeTransactions) {try {int providerId = rechargeTransaction.getProviderId();if (providerId == 1) {oxigenRechargeProviderService.doCheckStatusRequest(oxigenRechargeEnquiryUrl, oxigenRechargeAuthKey, rechargeTransaction);} else if (providerId == 2) {thinkWalnutDigitalRechargeProviderService.doCheckStatusRequest(thinkWalnutDigitalRechargeEnquiryCredential, rechargeTransaction);}if (rechargeTransaction.getStatus().equals(RechargeStatus.SUCCESS) || rechargeTransaction.getStatus().equals(RechargeStatus.FAILED)) {requestRechargeStatusChanged.put(rechargeTransaction.getRequestId(), rechargeTransaction.getStatus());}} catch (Exception e) {LOGGER.info("Could not check status for Request {}", rechargeTransaction.getRequestId());}}LOGGER.info("Reconcile recharge ran successfully");}public void processActivation() throws Exception {schemeService.processActivation();}// TemporaryMethodpublic void migrateInvoice() {List<FofoOrder> fofoOrders = fofoOrderRepository.selectFromSaleDate(LocalDateTime.now().minusDays(3));Map<Integer, List<FofoOrder>> partnerOrdersMap = new HashMap<>();partnerOrdersMap = fofoOrders.stream().collect(groupingBy(FofoOrder::getFofoId, Collectors.toList()));for (List<FofoOrder> orderList : partnerOrdersMap.values()) {int sequence = 0;String prefix = "";List<FofoOrder> sortedList = orderList.stream().sorted((x1, x2) -> x1.getId() - x2.getId()).collect(Collectors.toList());for (FofoOrder order : sortedList) {LOGGER.info("Order Id is {}, partner Id is {}", order.getId(), order.getFofoId());if (!order.getInvoiceNumber().contains("SEC")) {sequence = Integer.parseInt(order.getInvoiceNumber().split("/")[1]);prefix = order.getInvoiceNumber().split("/")[0];} else {sequence += 1;String invoiceNumber = prefix + "/" + sequence;order.setInvoiceNumber(invoiceNumber);fofoOrderRepository.persist(order);}}}}@Autowiredprivate ReporticoCacheTableRepository reporticoCacheTableRepository;public void processSchemeOut(List<String> invoiceNumbers) throws Exception {for (String invoiceNumber : invoiceNumbers) {System.out.println("Invoice Number - " + invoiceNumber);FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);//orderService.reverseScheme(fofoOrder);schemeService.processSchemeOut(fofoOrder.getId(), fofoOrder.getFofoId());}}public void processSchemeIn(List<String> invoiceNumbers) throws Exception {for (String invoiceNumber : invoiceNumbers) {System.out.println("Invoice Number - " + invoiceNumber);Purchase purchase = purchaseRepository.selectByPurchaseReference(invoiceNumber);schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());}}public void processScheme(LocalDateTime startDate, LocalDateTime endDate, boolean dryRun) throws Exception {LOGGER.info("Started execution at {}", LocalDateTime.now());System.out.println("InventoryId\tSerialNumber\tItem Id\tScheme Id\tScheme Name\tScheme Type\tAmount Type\tDP\tTaxable\tScheme Amount\tAmount Paid");try {List<Purchase> purchases = purchaseRepository.selectAllBetweenPurchaseDate(startDate, endDate);for (Purchase purchase : purchases) {schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());}List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(startDate, endDate);for (FofoOrder fofoOrder : fofoOrders) {schemeService.processSchemeOut(fofoOrder.getId(), fofoOrder.getFofoId());}} catch (Exception e) {e.printStackTrace();throw e;}List<UserWalletHistory> uwhs = userWalletHistoryRepository.selectAllByDateType(LocalDate.now().atStartOfDay(), endDate, Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT));System.out.println("Amount\tReference\tReferenceType\tTimestamp\tDescription");for (UserWalletHistory uwh : uwhs) {System.out.println(String.format("%d\t%d\t%s\t%s\t%s", uwh.getAmount(), uwh.getReference(), uwh.getReferenceType(), uwh.getTimestamp().toString(), uwh.getDescription()));}LOGGER.info("Schemes processed successfully.");if (dryRun) {throw new Exception();}}public void processRechargeCashback() throws Throwable {LocalDateTime cashbackTime = LocalDateTime.now();int referenceId = (int) Timestamp.valueOf(cashbackTime).getTime() / 1000;List<RechargeTransaction> pendingTransactions = rechargeTransactionRepository.getPendingCashBackRehargeTransactions();Map<Object, Double> totalRetailerCashbacks = pendingTransactions.stream().collect(groupingBy(x -> x.getRetailerId(), Collectors.summingDouble(x -> x.getCommission())));for (Entry<Object, Double> totalRetailerCashback : totalRetailerCashbacks.entrySet()) {int retailerId = (Integer) totalRetailerCashback.getKey();float amount = totalRetailerCashback.getValue().floatValue();if (Math.round(amount) > 0) {walletService.addAmountToWallet(retailerId, referenceId, WalletReferenceType.CASHBACK, "Recharge Cashback", Math.round(amount), LocalDateTime.now());}}for (RechargeTransaction rt : pendingTransactions) {rt.setCashbackTimestamp(cashbackTime);rt.setCashbackReference(referenceId);rechargeTransactionRepository.persist(rt);}LOGGER.info("Cashbacks for Recharge processed Successfully");}public void rollOutUpgardedMarginsNextMonth(List<Integer> fofoIds) throws Exception {LocalDate startOfPreviousMonth = LocalDate.now().with(ChronoField.DAY_OF_MONTH, 1).minusMonths(1);List<FofoStore> stores;if (fofoIds == null || fofoIds.isEmpty()) {stores = fofoStoreRepository.selectActiveStores();} else {stores = fofoStoreRepository.selectByRetailerIds(fofoIds);}for (FofoStore store : stores) {this.rolloutMarginForStoreOnMonth(store, startOfPreviousMonth);}}public void rolloutMarginForStoreOnMonth(FofoStore store, LocalDate startOfMonth) throws ProfitMandiBusinessException {int fofoId = store.getId();// Check if there's a manual partner type change on day 1 of the monthPartnerTypeChange day1Change = partnerTypeChangeRepository.selectPartnerType(fofoId, startOfMonth);if (day1Change != null && day1Change.getSource() == PartnerTypeSource.MANUAL) {LOGGER.info("Manual partner type upgrade detected for code {} to {}", store.getCode(), day1Change.getPartnerType());List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startOfMonth.atStartOfDay(), startOfMonth.plusMonths(1).atStartOfDay(), 0, 0);for (FofoOrder fofoOrder : fofoOrders) {schemeService.processSchemeOut(fofoOrder.getId(), fofoId);}return;}// Existing logic for calculated upgradesPartnerType startOfPreviousMonthPartnerType = partnerTypeChangeService.getTypeOnDate(fofoId, startOfMonth);PartnerType todayPartnerType = partnerTypeChangeService.getTypeOnMonth(fofoId, YearMonth.from(startOfMonth));if (!startOfPreviousMonthPartnerType.nextPartnerTypes().contains(todayPartnerType)) {return;}if (!startOfPreviousMonthPartnerType.equals(todayPartnerType)) {LOGGER.info("Partner Type has been changed for code {} from {} to {}", store.getCode(), startOfPreviousMonthPartnerType, todayPartnerType);List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startOfMonth.atStartOfDay(), startOfMonth.plusMonths(1).atStartOfDay(), 0, 0);for (FofoOrder fofoOrder : fofoOrders) {schemeService.processSchemeOut(fofoOrder.getId(), fofoId);}}}public void rollOutUpgardedMargins(List<Integer> fofoIds) throws Exception {LocalDate today = LocalDate.now();LocalDate yesterday = today.minusDays(1);int upgradedCount = 0;List<FofoStore> stores;if (fofoIds == null || fofoIds.isEmpty()) {stores = fofoStoreRepository.selectActiveStores();} else {stores = fofoStoreRepository.selectByRetailerIds(fofoIds);}// Bulk fetch partner types to avoid N+1 queriesMap<Integer, PartnerType> yesterdayTypeMap = partnerTypeChangeService.getTypesForFofoIds(fofoIds, yesterday);Map<Integer, PartnerType> todayTypeMap = partnerTypeChangeService.getTypesForFofoIds(fofoIds, today);StringBuilder sb = new StringBuilder();for (FofoStore store : stores) {int fofoId = store.getId();PartnerType yesterdayPartnerType = yesterdayTypeMap.get(fofoId);PartnerType todayPartnerType = todayTypeMap.get(fofoId);if (yesterdayPartnerType == null || todayPartnerType == null) {continue;}if (!yesterdayPartnerType.nextPartnerTypes().contains(todayPartnerType)) {continue;}if (!yesterdayPartnerType.equals(todayPartnerType)) {upgradedCount++;sb.append(String.format("Partner Type has been changed for code %s from %s to %s", store.getCode(), yesterdayPartnerType.toString(), todayPartnerType.toString()));sb.append("<br>");LOGGER.info("Partner Type has been changed for code {} from {} to {}", store.getCode(), yesterdayPartnerType, todayPartnerType);List<FofoOrder> fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, yesterday.withDayOfMonth(1).atStartOfDay(), yesterday.atStartOfDay(), 0, 0);for (FofoOrder fofoOrder : fofoOrders) {schemeService.processSchemeOut(fofoOrder.getId(), fofoId);}}}if (upgradedCount > 0) {sendMailOfHtmlFormat(googleMailSender, new String[]{"amit.gupta@smartdukaan.com", "tarun.verma@smartdukaan.com", "neeraj.gupta@smartdukaan.com"}, sb.toString(), null, "Few Partners Category have been Upgraded");} else {sendMailOfHtmlFormat(googleMailSender, new String[]{"amit.gupta@smartdukaan.com", "tarun.verma@smartdukaan.com", "neeraj.gupta@smartdukaan.com"}, sb.toString(), null, "No partners Category have been upgraded today");}}@Autowiredprivate PartnerStatsService partnerStatsService;// Temporary Methodpublic void fetchParnterStats() throws Exception {Map<Integer, PartnerDetailModel> partnerStats = partnerStatsService.getAllPartnerStats();ObjectOutputStream oos = null;FileOutputStream fout = null;try {// fout = new FileOutputStream("/tmp/partnerStat.tmp", false);fout = new FileOutputStream("/var/www/partner_stats/partnerStat.tmp", false);oos = new ObjectOutputStream(fout);oos.writeObject(partnerStats);} catch (Exception ex) {ex.printStackTrace();} finally {if (oos != null) {oos.close();}}ReporticoCacheTable reporticoCacheTable = reporticoCacheTableRepository.selectByTableName("partnerStat");if (reporticoCacheTable == null) {reporticoCacheTable = new ReporticoCacheTable();reporticoCacheTable.setTableName("partnerStat");reporticoCacheTable.setLastCreatedTimestamp(LocalDateTime.now());reporticoCacheTableRepository.persist(reporticoCacheTable);} else {reporticoCacheTable.setLastCreatedTimestamp(LocalDateTime.now());}}public void processPriceDrop() throws Exception {List<PriceDrop> priceDrops = priceDropRepository.selectAllByDatesBetween(LocalDateTime.now(), LocalDateTime.now().minusYears(1));for (PriceDrop priceDrop : priceDrops) {if (priceDrop.getDropAmount() > 0) {priceDropService.processPriceDrop(priceDrop.getId(), true);}}}@AutowiredCreditNoteService creditNoteService;public void sendCreditNote(YearMonth yearMonth) throws Exception {creditNoteService.issueMonthlyMarginsCN(yearMonth);}@AutowiredBrandAgeingLimitRepository brandAgeingLimitRepository;@AutowiredAgeingService ageingService;@AutowiredRbmTargetService rbmTargetService;public void sendMailForAgeingAlert() throws Exception {//brandAgeingLimitRepository.selectAll();Map<String, AgeingModel> ageingModelMap = ageingService.getAllAgeingForSecondary();System.out.println(ageingModelMap.size());List<PartnerAgeingModel> partnerAgeingModels = ageingService.getAllAgeingForTertiary();ByteArrayOutputStream byteArrayOutputStream = FileUtil.getCSVByteStream(Arrays.asList("InventoryItemId", "Serial Number", "Item Id", "Brand", "Model Name", "ModelNumber", "Color", "Exceed Days", "Last ScanType", "Supplier Name", "Current Warehouse", "First Warehouse", "Invoice Number", "Invoice Date"), ageingModelMap.values().stream().map(x -> Arrays.asList(x.getInventoryItemId(), x.getSerialNumber(), x.getItemId(), x.getBrand(), x.getModelName(), x.getModelNumber(), x.getColor(), x.getExceedDays(), x.getLastScanType(), x.getSupplierName(), x.getCurrentWarehouse(), x.getFirstWarehouse(), x.getInvoiceNumber(), FormattingUtils.formatDate(x.getInvoiceDate()))).collect(Collectors.toList()));ByteArrayOutputStream byteArrayOutputStream2 = FileUtil.getCSVByteStream(Arrays.asList("InventoryItemId", "Serial Number", "Item Id", "Brand", "Model Name", "ModelNumber", "Color", "Partner Id", "Partner Code", "Partner Name", "Activation Type", "City", "State", "Billing Date", "Exceed Days", "Max Ageing", "Activation Date"), partnerAgeingModels.stream().map(x -> Arrays.asList(x.getInventoryItemId(), x.getSerialNumber(), x.getItemId(), x.getBrand(), x.getModelName(), x.getModelNumber(), x.getColor(), x.getFofoId(), x.getFofoCode(), x.getFofoName(), x.getActivationType(), x.getFofoCity(), x.getFofoState(), FormattingUtils.formatDate(x.getBillingDate()), x.getExceedDays(), x.getMaxAgeingDays(), x.getActivationDate())).collect(Collectors.toList()));Attachment attachment1 = new Attachment("secondary-alert.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));Attachment attachment2 = new Attachment("tertiary-alert.csv", new ByteArrayResource(byteArrayOutputStream2.toByteArray()));String mailSubject = "Stock ageing Alert";Utils.sendMailWithAttachments(mailSender, new String[]{"deena.nath@smartdukaan.com"}, null, mailSubject, "PFA", attachment1, attachment2);}public void rejectPriceDropsOfApprovedImeis() throws ProfitMandiBusinessException {priceDropService.rejectPriceDropsOfApprovedImeis();}public void processDeductions() {sidbiService.processDeductions();}public void resetHardLimit() throws ProfitMandiBusinessException {sdCreditService.resetHardLimit();}public void testInvoiceFormat() throws ProfitMandiBusinessException {InvoicePdfModel invoicePdfModel = orderService.getInvoicePdfModel(560280);//System.out.println(InvoiceFormatter.buildInvoiceLines(invoicePdfModel, InvoiceFormatter.WIDTH_80MM));}public void sendTrialExpiry() {List<FofoStore> stores = fofoStoreRepository.selectAllTrial();List<FofoStore> twoDaysToExpiry = stores.stream().filter(x -> x.getTrialEnd().minusDays(2).equals(LocalDate.now())).collect(Collectors.toList());List<FofoStore> fiveDaysToExpiry = stores.stream().filter(x -> x.getTrialEnd().minusDays(5).equals(LocalDate.now())).collect(Collectors.toList());List<FofoStore> expiredToday = stores.stream().filter(x -> x.getTrialEnd().equals(LocalDate.now())).collect(Collectors.toList());List<FofoStore> expired = stores.stream().filter(x -> x.getTrialEnd().isAfter(LocalDate.now())).collect(Collectors.toList());}/*public void processCashDiscount() throws ProfitMandiBusinessException {System.out.println("processing cash discount");List<Loan> loansSettledYesterday = loanRepository.selectLoansSettledOn(LocalDate.now().minusDays(1));loansSettledYesterday.addAll(loanRepository.selectLoansSettledOn(LocalDate.now()));Map<Integer, List<Loan>> partnerSettledLoans = loansSettledYesterday.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));for (Entry<Integer, List<Loan>> partnerLoans : partnerSettledLoans.entrySet()) {List<Loan> fullCdLoans = partnerLoans.getValue().stream().filter(x -> x.getInvoiceNumber() != null && x.getDays() <= ProfitMandiConstants.LOAN_PARTIAL_CREDIT_DAYS).collect(toList());List<Loan> partialCdLoans = partnerLoans.getValue().stream().filter(x -> x.getInvoiceNumber() != null && x.getDays() > ProfitMandiConstants.LOAN_PARTIAL_CREDIT_DAYS &&x.getDays() <= ProfitMandiConstants.LOAN_FULL_CREDIT_DAYS).collect(toList());//List<Loan> noCdLoans = loanRepository.selectLoansDueByDays()//for (Loan fullCdLoan : fullCdLoans) {LOGGER.info("FullCdLoan - {}", fullCdLoan);schemeService.processFullCD(fullCdLoan.getInvoiceNumber());}for (Loan partialCdLoan : partialCdLoans) {schemeService.processPartialCD(partialCdLoan.getInvoiceNumber());}*//*for (Loan noCdLoan : noCdLoans) {schemeService.processNoCD(noCdLoan.getInvoiceNumber());}*//*}}*/private class SaleRoles {private List<String> l1;private List<String> l2;public SaleRoles() {l1 = new ArrayList<>();l2 = new ArrayList<>();}public List<String> getL1() {return l1;}public List<String> getL2() {return l2;}}private class FofoReportingModel {private String code;private int fofoId;private String businessName;private String territoryManager;private String regionalManager;private String businessManager;public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getBusinessName() {return businessName;}public void setBusinessName(String businessName) {this.businessName = businessName;}public String getTerritoryManager() {return territoryManager;}public void setTerritoryManager(String territoryManager) {this.territoryManager = territoryManager;}public String getRegionalManager() {return regionalManager;}public void setRegionalManager(String regionalManager) {this.regionalManager = regionalManager;}private ScheduledTasks getOuterType() {return ScheduledTasks.this;}@Overridepublic String toString() {return "FofoReportingModel{" + "code='" + code + '\'' + ", fofoId=" + fofoId + ", businessName='" + businessName + '\'' + ", territoryManager='" + territoryManager + '\'' + ", regionalManager='" + regionalManager + '\'' + ", businessManager='" + businessManager + '\'' + '}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;FofoReportingModel that = (FofoReportingModel) o;return fofoId == that.fofoId && Objects.equals(code, that.code) && Objects.equals(businessName, that.businessName) && Objects.equals(territoryManager, that.territoryManager) && Objects.equals(regionalManager, that.regionalManager) && Objects.equals(businessManager, that.businessManager);}@Overridepublic int hashCode() {return Objects.hash(code, fofoId, businessName, territoryManager, regionalManager, businessManager);}public String getBusinessManager() {return businessManager;}public void setBusinessManager(String businessManager) {this.businessManager = businessManager;}public int getFofoId() {return fofoId;}public void setFofoId(int fofoId) {this.fofoId = fofoId;}}@AutowiredWarehouseInventoryItemRepository warehouseInventoryItemRepository;@AutowiredOfferService offerService;@AutowiredPurchaseReturnItemRepository purchaseReturnItemRepository;@AutowiredBrandRegionMappingRepository brandRegionMappingRepository;@AutowiredStandAlone standAlone;@AutowiredItelImeiActivationNewService itelImeiActivationNewService;public void checkItelImeiActivationNew(LocalDate date, Integer day) throws Exception {try {itelImeiActivationNewService.checkItelImeiActivationNew(date, day);} catch (Throwable e) {throw new Exception(e);}}@AutowiredPurchaseReturnService purchaseReturnService;@AutowiredJavaMailSender javaMailSender;@AutowiredOfferPayoutRepository offerPayoutRepository;@AutowiredOfferRepository offerRepository;@AutowiredBluedartAuthService bluedartAuthService;@AutowiredBluedartService bluedartService;@AutowiredTransactionRelatedTasks transactionRelatedTasks;@AutowiredPsiSmartService psiSmartService;private void migrateValentine() throws ProfitMandiBusinessException {List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(LocalDate.now().atStartOfDay(), LocalDateTime.now());for (FofoOrder fofoOrder : fofoOrders) {orderService.processScratchOffer(fofoOrder);}}@AutowiredInvoiceService invoiceService;@AutowiredWarehouseService warehouseService;@AutowiredGenericRepository genericRepository;@AutowiredPriceCircularService priceCircularService;/*@AutowiredRedisCacheManager redisFortnightlyCacheManage;*/@AutowiredGstProAuthService gstProAuthService;@AutowiredGstProService gstProService;@AutowiredWarehouseProviderRepository warehouseProviderRepository;@AutowiredLoiFormRepository loiFormRepository;@AutowiredPartnerOnBoardingPanelRepository partnerOnBoardingPanelRepository;@AutowiredStoreTimelineTatService storeTimelineTatService;@AutowiredPartnerDealerRepository partnerDealerRepository;@AutowiredPurSaleService purSaleService;@AutowiredCatalogRepository catalogRepository;private void rolloutOppoPayout() throws Exception {//List<Integer> schemeIds = Arrays.asList(5540, 5542, 5544,5918, 5919, 5920, 5921, 5922);List<Integer> schemeIds = Arrays.asList(5540, 5542, 5544, 5545, 5550, 5555, 5556, 5557, 5564, 5565, 5566, 5567, 5569, 5570, 5582, 5590, 5592, 5593, 5594,5595, 5598, 5602, 5604, 5605, 5606, 5607, 5608, 5611, 5618, 5620, 5621, 5622, 5623, 5624, 5625, 5626, 5629, 5631,5633, 5634, 5635, 5637, 5644, 5649, 5655, 5659, 5662, 5668, 5672, 5674, 5679, 5683, 5684, 5685, 5688, 5689, 5690,5692, 5694, 5697, 5699, 5700, 5706, 5718, 5729, 5730, 5754, 5756, 5758, 5759, 5761, 5762, 5766, 5769, 5771, 5772,5773, 5774, 5775, 5776, 5781, 5782, 5783, 5786, 5788, 5790, 5795, 5800, 5803, 5804, 5807, 5809, 5815, 5816, 5819,5820, 5821, 5822, 5823, 5824, 5825, 5826, 5827, 5828, 5829, 5830, 5832, 5833, 5834, 5835, 5836, 5837, 5839, 5840,5841, 5842, 5843, 5844, 5845, 5846, 5847, 5848, 5849, 5850, 5851, 5852, 5853, 5854, 5855, 5857, 5859, 5860, 5863,5864, 5866, 5869, 5870, 5871, 5872, 5873, 5874, 5875, 5877, 5878, 5879, 5880, 5885, 5888, 5889, 5891, 5892, 5894,5899, 5901, 5903, 5905, 5908, 5910, 5913, 5916, 5917, 5918, 5919, 5920, 5921, 5922, 5923, 5924, 5925, 5926, 5927,5928, 5929, 5930, 5931, 5932, 5933, 5934, 5935, 5936, 5938, 5939, 5940, 5941, 5942, 5943, 5944, 5945, 5946, 5947,5948, 5949, 5950, 5951, 5952, 5953, 5954, 5955, 5956, 5957, 5958, 5959, 5960, 5961, 5962, 5963, 5964, 5965, 5966,5967, 5968, 5969, 5970, 5971, 5972, 5973, 5974, 5975, 5976, 5977, 5979, 5980, 5981, 5982, 5983, 5984, 5985, 5986,5987, 5989, 5990, 5991, 5992, 5996, 5997, 5998, 5999, 6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6010,6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6026, 6028, 6029, 6030,6031, 6032, 6033, 6034, 6035, 6036, 6037, 6038, 6039, 6040, 6041, 6042, 6043, 6044, 6045, 6046, 6047, 6048, 6049,6050, 6051, 6052, 6053, 6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 6062, 6063, 6064, 6065, 6066, 6067, 6068,6069, 6070, 6071, 6072, 6073, 6078, 6079, 6080, 6081, 6082, 6083, 6084, 6085, 6086, 6087, 6088, 6089, 6091, 6092,6093, 6094, 6095, 6098, 6102);Map<Integer, List<SchemeInOut>> inventoryItemSiosMap = schemeInOutRepository.selectBySchemeIds(new HashSet<>(schemeIds)).stream().collect(Collectors.groupingBy(x -> x.getInventoryItemId()));Map<Integer, InventoryItem> inventoryItemMap = inventoryItemRepository.selectByIds(inventoryItemSiosMap.keySet()).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));Set<Integer> itemIds = itemRepository.selectAllByBrand("Oppo", 10006).stream().map(x -> x.getId()).collect(toSet());List<InventoryItem> filteredInventoryItems = inventoryItemMap.values().stream().filter(x -> itemIds.contains(x.getItemId())).collect(Collectors.toList());Map<Integer, List<InventoryItem>> purchaseInventoryItemsMap = filteredInventoryItems.stream().filter(x -> x.getCreateTimestamp().isAfter(YearMonth.now().atDay(1).atStartOfDay())).collect(Collectors.groupingBy(x -> x.getPurchaseId()));List<Purchase> purchases = purchaseRepository.selectAllByIds(new ArrayList<>(purchaseInventoryItemsMap.keySet()));for (Purchase purchase : purchases) {String invoiceNumber = purchase.getPurchaseReference();LocalDateTime billingTime = orderRepository.selectByInvoiceNumber(invoiceNumber).get(0).getBillingTimestamp();if (billingTime.isAfter(YearMonth.now().atDay(1).atStartOfDay())) {schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());}}for (InventoryItem filteredInventoryItem : filteredInventoryItems) {//System.out.println("Serial Number is - " + filteredInventoryItem.getSerialNumber());List<ScanRecord> scanRecords = scanRecordRepository.selectByInventoryItemId(filteredInventoryItem.getId());ScanRecord scanRecord = scanRecords.stream().filter(x -> x.getType().equals(ScanType.SALE)).findFirst().orElse(null);if (scanRecord == null) {continue;}schemeService.processSchemeOut(scanRecord.getOrderId(), scanRecord.getFofoId());}}@AutowiredAbmReportSender abmReportSender;public void sendOverDueReport() {List<Loan> loans = loanRepository.selectAllActiveLoan();Map<Integer, List<Loan>> partnerLoansMap = loans.stream().filter(x -> x.isOverdue()).collect(Collectors.groupingBy(x -> x.getFofoId()));//sdCreditService.getDueDateCrossLoan()partnerLoansMap.entrySet().stream().forEach(x -> {x.getKey();x.getValue().size();});}@AutowiredOnBoardingRelatedSchelduleTask onBoardingRelatedSchelduleTask;@AutowiredMigrations migrations;/*@AutowiredBenowService benowService;*/@AutowiredTrialFormRepository trialFormRepository;@AutowiredCreditBlockedExceptionPartnersRepository creditBlockedExceptionPartnersRepository;@AutowiredSDCreditService sdCreditService;@Autowiredcom.spice.profitmandi.service.integrations.pinelabs.PinelabsAffordabilityService pinelabsAffordabilityService;@Autowiredcom.spice.profitmandi.service.integrations.pinelabs.PinelabsAuthService pinelabsAuthService;public void testAffordability() {Money orderAmount = new Money("1000000", "INR");Money discountAmount = new Money("0", "INR");List<ProductDetails> productDetails = Arrays.asList(new ProductDetails(orderAmount, discountAmount, "Alpha_2"));OfferDiscoveryRequest offerDiscoveryRequest = new com.spice.profitmandi.service.integrations.pinelabs.dto.OfferDiscoveryRequest(orderAmount, productDetails, new AffordabilityIssuer("12345678"));OfferDiscoveryResponse offerDiscoveryResponse = pinelabsAffordabilityService.discoverOffers(offerDiscoveryRequest);System.out.println(offerDiscoveryResponse);}public void test() throws Exception {System.out.println(pinelabsAuthService.getAccessToken());testAffordability();//System.out.println(trialFormRepository.selectByEmailOrMobile("9990381568"));/*CreditBlockedExceptionPartner creditBlockedExceptionPartner = creditBlockedExceptionPartnersRepository.select(175139430);System.out.println(creditBlockedExceptionPartner);*///this.updatePartnerLimit(175139595);//this.releaseBlockedLimit();//sdCreditService.resetHardLimit();//migrations.migrateSerialInvoiceMap();//runOnceTasks.checkRewardsEligibility();//hybridEncryptor.getJwt();/*System.out.printf("Date|Transaction Id|Serial Number|Sale Amount|Swipe Payout|Discount Payout%n");for(int i=0;i<10;i++){benowService.parseBenowTransaction(LocalDate.now().minusDays(i));}*///onBoardingRelatedSchelduleTask.onboardingEventDelays();//runOnceTasks.migrateLimit();866009067657118//TODO -- Sales Return Pending//runOnceTasks.moveSaleReturnScanToDoa("866009067657118");//runOnceTasks.sendCreditExposureReport();//runOnceTasks.moveDoaScanToSaleReturn("868770072438608");//runOnceTasks.purchasePolicy();//purSaleService.moreThen10DaysEgedStockReport();//System.out.println(schemeService.testRedis(1, 2L));//System.out.println(schemeService.testRedis(1, null));// abmReportSender.sendAbmSmartCartReport();//this.sendOverDueReport();/*List<Integer> orderIds = Arrays.asList(1929879,1932372,1932377,1932386,1932396,1935221,1935563,1935564,1945144,1955256,1955271,1955294,1961255,1961256,1972821,1972823,1972824,1972825,1972826,1974250,1974252,1974253,1974254,1974255,1974256,1974242,1974244,1974245,1974246,1974247,1974248,1976610,1978095,1978136,1978130,1978174,1978156,1978158,1978167,1978169,1978160,1978179,1978175,1978180,1978201,1978200,1978202,1978192,1978198,1978207,1978204,1978457,1979781,1979783,1979784,1979787,1982412,1982413,1986531,1986532,1986533,1991006,1991628,1991629,2016001,2018921,2042948,2047031,2058500,2058522,2058519,2058520,2058546,2058559,2058568,2058575,2058574,2058598,2058594,2058618,2058633,2066491,2067110,2067113,2067118,2067120,2067123,2067132,2067125,2067127,2069974,2069970,2069976,2069985,2069987);for (Integer orderId : orderIds) {System.out.println("Refund Started - " + orderId);orderRepository.refundOrder(orderId, "vinay.p", "Long awaited cancellation", OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY);System.out.println("Refund Ended");}*///System.out.println(warehouseSupplierInvoiceRepository.selectWarehouseItemAgeing(LocalDateTime.now().minusDays(10), LocalDateTime.now(), null, 0, null));/*Offer offer = offerRepository.selectById(6820);offerService.sendWhatsapp(offer, Arrays.asList(175140233),"https://images.smartdukaan.com/uploads/campaigns/image2025-09-24/offer-6820.png");*//*List<String> invoices = Arrays.asList("NSDLNOI16527","NSDLNOI16366", "NSDLNOI16394", "NSDLNOI16460");List<Loan> loans = new ArrayList<>();for (String invoice : invoices) {loans.add(loanRepository.selectLoanByInvoice(invoice));}loans.stream().sorted(Comparator.comparing(x->x.getCreatedOn())).forEach(x-> {try {sdCreditService.settleLoan(x);} catch (ProfitMandiBusinessException e) {throw new RuntimeException(e);}});*///Utils.sendMailWithAttachments(googleMailSender, new String[]{"amit.gupta@smartdukaan.com"}, null, "DTDC AWb", "PFA");*/}private void releaseBlockedLimit() throws ProfitMandiBusinessException {List<Loan> blockedLoans = loanRepository.selectAllBlockedLoans();for (Loan blockedLoan : blockedLoans) {LoanTransaction loanTransaction = loanTransactionRepository.selectByLoanId(blockedLoan.getId());int transactionId = loanTransaction.getTransactionId();List<UserWalletHistory> userWalletHistory = walletService.getAllByReference(blockedLoan.getFofoId(), transactionId, WalletReferenceType.PURCHASE);int amount = userWalletHistory.get(userWalletHistory.size() - 1).getAmount();int loanAmount = blockedLoan.getIntialAmount().intValue();if (loanAmount > -amount) {sdCreditService.settleBlockedLoan(transactionId, loanAmount + amount);}}}@AutowiredLoanTransactionRepository loanTransactionRepository;private void fixBlockedCredit() throws ProfitMandiBusinessException {List<Loan> unsettledBlockedLoans = loanRepository.selectAllActiveLoan().stream().filter(x -> x.getFreeDays() >= 365).collect(toList());//unsettledBlockedLoans = unsettledBlockedLoans.stream().filter(x -> x.getId() == 52310).collect(toList());for (Loan unsettledBlockedLoan : unsettledBlockedLoans) {LoanTransaction loanTransaction = loanTransactionRepository.selectByLoanId(unsettledBlockedLoan.getId());if (loanTransaction == null) {System.out.println("Cant find Transaction Id for Loan - " + unsettledBlockedLoan.getId() + "-- Created On ->" + unsettledBlockedLoan.getCreatedOn());continue;}List<Order> processedOrders = orderRepository.selectAllByTransactionId(loanTransaction.getTransactionId()).stream().filter(x -> !x.getStatus().equals(OrderStatus.SUBMITTED_FOR_PROCESSING)).collect(toList());List<OrderStatus> processedOrderIds = processedOrders.stream().map(x -> x.getStatus()).collect(Collectors.toList());System.out.println("processedOrderIds " + processedOrderIds);//if(unsettledBlockedLoan !=null) continue;double limitToRelease = processedOrders.stream().collect(Collectors.summingDouble(x -> x.getWalletAmount()));sdCreditService.releaseBlockedLimit(unsettledBlockedLoan, limitToRelease);}}public static byte[] toByteArray(InputStream input) throws IOException {ByteArrayOutputStream buffer = new ByteArrayOutputStream();int nRead;byte[] data = new byte[16384];while ((nRead = input.read(data, 0, data.length)) != -1) {buffer.write(data, 0, nRead);}return buffer.toByteArray();}private void whatsappTest() throws Exception {//liquidationService.processBids(ProfitMandiConstants.BID_CRON_ENUM.TODAY);Utils.sendMailWithAttachments(googleMailSender, new String[]{"ranu.rajput@smartdukaan.com"}, null, "Test Mail", "Mail is working");}private void debitLoanAmountFromWallet() {List l1 = Arrays.asList(1234, 1420, 2694, 8129, 12182, 12880, 16289, 16462, 16551, 16625, 16819, 17606, 18902, 19152, 19663, 22409, 22410, 23924, 24058, 24206, 24215, 24220, 24459, 25977, 30585, 31590);l1.addAll(Arrays.asList(11849, 12702, 14554, 14643, 19166, 19638, 32824, 33467, 33954, 34017, 34514, 35128, 35229, 35355, 36007, 36351, 36435, 36586, 36608, 36612, 36665, 37076, 37495, 37678, 38519, 38563, 38638, 38690, 38815, 38840, 39015, 39084, 39142, 39379, 39384, 39586, 39636, 39657, 39755, 39788, 39908, 40054, 40220, 40534, 41731, 41962, 42692));l1.addAll(Arrays.asList());}public void test4() throws Exception {List<Integer> offerIds = Arrays.asList(2882, 2881, 2880, 2879, 2878, 2877, 2876, 2875, 2874, 2873, 2872, 2871, 2870, 2869, 2868, 2867, 2866, 2865, 2864, 2863, 2862, 2861, 2860, 2859, 2858, 2857, 2856, 2855, 2854, 2853, 2852, 2851, 2850, 2849, 2847, 2846, 2845, 2844, 2843, 2842, 2841, 2840, 2839, 2838, 2837, 2836, 2835, 2834, 2833, 2832, 2831, 2830, 2829, 2828, 2827, 2826, 2825, 2824, 2823, 2822, 2821, 2820, 2819, 2818, 2817, 2816, 2815, 2814, 2813, 2812, 2811, 2810, 2809, 2808, 2807, 2806, 2805, 2804, 2803, 2802, 2801, 2800, 2799, 2798, 2797, 2796, 2795, 2794, 2793, 2792, 2791, 2790, 2789, 2788, 2787, 2786, 2785, 2784, 2783, 2782, 2781, 2780, 2777, 2776, 2775, 2774, 2773, 2772, 2771, 2770, 2769, 2768, 2767, 2766, 2765, 2764, 2763, 2762, 2761, 2760, 2759, 2758, 2757, 2756, 2755, 2754, 2753, 2752, 2751, 2750, 2749, 2748, 2747, 2746, 2745, 2744, 2723, 2722, 2721, 2720, 2719, 2718, 2717, 2716, 2715, 2714, 2713, 2712, 2711, 2710, 2709, 2708, 2707, 2706, 2705, 2704, 2703, 2702, 2701, 2700, 2699, 2698, 2697, 2696, 2695, 2694, 2693, 2692, 2691, 2690, 2494, 2493, 2492, 2491, 2490, 2489, 2488, 2487, 2486, 2485, 2484, 2483, 2482, 2481, 2480, 2479, 2478, 2477, 2476, 2475, 2474, 2473, 2472, 2471, 2470, 2469, 2466, 2465, 2464, 2463, 2462, 2461, 2460, 2459, 2458, 2457, 2456, 2455, 2454, 2453, 2452, 2451, 2450, 2449, 2448, 2447, 2446, 2445, 2444, 2443, 2442, 2441, 2440, 2439, 2407, 2406, 2405, 2404, 2403, 2402, 2401, 2400, 2399, 2398, 2397, 2396, 2395, 2394, 2393, 2392, 2391, 2390, 2389, 2388, 2387, 2386, 2385, 2384, 2383, 2382, 2381, 2117, 2116, 2115, 2114, 2113, 2112, 2111, 2110, 2109, 2108, 2107, 2106, 2105, 2104, 2103, 2102, 2101, 2100, 2099, 2098, 2077);for (Integer offerId : offerIds) {Offer fromOffer = offerRepository.selectById(offerId);CreateOfferRequest createOfferRequest = offerService.getCreateOfferRequest(fromOffer);System.out.println("Processing offer Id " + fromOffer);offerService.processActivationtOffer(createOfferRequest);}this.processSidbiDeductions();}public void test3() throws Exception {List<Long> payoutIds = Arrays.asList();List<OfferPayout> offerPayouts = offerPayoutRepository.selectAllByIds(payoutIds);Map<Integer, List<OfferPayout>> offerPayoutMap = offerPayouts.stream().collect(groupingBy(x -> (int) x.getOfferId()));for (Entry<Integer, List<OfferPayout>> offerPayoutEntry : offerPayoutMap.entrySet()) {int offerId = offerPayoutEntry.getKey();List<OfferPayout> offerPayoutList = offerPayoutEntry.getValue();Map<Integer, List<OfferPayout>> partnerOfferPayoutMap = offerPayoutList.stream().collect(groupingBy(x -> (int) x.getFofoId()));for (Entry<Integer, List<OfferPayout>> partnerOfferPayoutEntry : partnerOfferPayoutMap.entrySet()) {int fofoId = partnerOfferPayoutEntry.getKey();List<OfferPayout> partnerPayouts = partnerOfferPayoutEntry.getValue();float amount = 0;for (OfferPayout offerPayout : partnerPayouts) {amount += offerPayout.getAmount();offerPayout.setStatus(SchemePayoutStatus.REJECTED);offerPayout.setRejectTimestamp(LocalDateTime.now());}walletService.rollbackAmountFromWallet(fofoId, amount, offerId,WalletReferenceType.ADDITIONAL_SCHEME, "Imeis returned - " + partnerPayouts.size() + "pc(s)", LocalDateTime.now());}}}public void test1() throws Exception {System.out.println("Hello from test");//this.calculateInterestAccured();//sendMailOfHtmlFormat(javaMailSender, new String[]{"amit.gupta@smartdukaan.com"}, "hello", null, "Hello");//priceDropService.rejectPriceDropsOfApprovedImeis();//Create return//this.updatePartnerLimit();//creditNoteService.sendCnMails(YearMonth.now().minusMonths(2));//orderService.createMissingScratchOffers();LocalDateTime debitNoteDate = LocalDate.of(2024, Month.APRIL, 30).atStartOfDay();Map<Integer, Set<String>> fofoIdImeiReturnMap = new LinkedHashMap<>();/*fofoIdImeiReturnMap.put(175139690, new HashSet<>(Arrays.asList("862054078463472","863862077158219","866202075810858","866202077654494","866335072023651","866518078002718")));fofoIdImeiReturnMap.put(175139414, new HashSet<>(Arrays.asList("356494471684303","356494471857164","356494472062590","861753065078075","863511068904178","863511069732933","864179068109203","864179068112504","864259078789978","866202076254130","866202076254775","866657078259165","866657078272846","867492065809718","867907071107955","868565073021423","868565073022223","868565073386347")));fofoIdImeiReturnMap.put(175139603, new HashSet<>(Arrays.asList("350886063151961","356412387787135","357594162824701","357594162874771","860600078193972","863862077025350","863862077875796","863967075815072","866335073794995","866335074287874","869116067546048")));fofoIdImeiReturnMap.put(175139657, new HashSet<>(Arrays.asList("350933415734746","354324787135850","354324788766356","354990352512960","354990352580181","358142881241184","866611064207332","869116067600464")));fofoIdImeiReturnMap.put(175139223, new HashSet<>(Arrays.asList("350210770983048","350210771169027","350210771179844","350210771180784","863975067090596","866611060326797","868565075758196","869452074016992","869452074609515","869452074609556","869452074976674","869452074978654")));fofoIdImeiReturnMap.put(175139557, new HashSet<>(Arrays.asList("861977073551795","861977073552678","861977074486819","862046062571245","862046067278226","862046067734921","862046067756866","864468070394741","864468071225506","864468071668341","864468073604740","864468074854625","866993074734475")));fofoIdImeiReturnMap.put(175139079, new HashSet<>(Arrays.asList("862046068861921","862282079169299","865388071283496","866335072007753","866335073946256","866518073601712","866518077425993","866518078760471","868938062675394","868938062690799","868938064895552")));fofoIdImeiReturnMap.put(175139711, new HashSet<>(Arrays.asList("861753065266498","861888066009099","864468073703369","866993071640154","869116062800465")));fofoIdImeiReturnMap.put(175139488, new HashSet<>(Arrays.asList("862054076866114","862054076866650","866335071879079","866335077875998","866335077876095","866518078758939","868938062692878")));fofoIdImeiReturnMap.put(175138934, new HashSet<>(Arrays.asList("862054072810231","862054072823150","862054076867674","862054078659590","863862075768456","863862077158193","863975064472490","863975064473233","865388071160033","865610079408035","866335072117370","866335073899471","866335074306153","866335075664477","868938062669876","868938062677895","868938062685997")));fofoIdImeiReturnMap.put(4149607 , new HashSet<>(Arrays.asList("864468073415741","864468075548523","864468075549927","864468079499426","866657074106022","868938062686656","868938062696978","868938062699352","868938064895198","868938066363799")));fofoIdImeiReturnMap.put(175139138, new HashSet<>(Arrays.asList("862286066217631","864259076533691","864468073358842","864487061610014","864487061675918","866083066080028","866518078760950","866518078768979","866657075343848","868544061108518","868544061138432","869116065510848","869116065519781","869452074116891","869452074972939")));fofoIdImeiReturnMap.put(175139608, new HashSet<>(Arrays.asList("350201087552063","350201087559944","350201087635660","350201087649760","350201087843140","350201088470224","350201088696687","350201088697180","354324783756923","354324786101366","355472822024008","355472822025625","860388068055779","860388068262219","866518078762337","866518078767534","868544061141493","868544061141774","868544061141816","868938064895719","868938066360910")));fofoIdImeiReturnMap.put(175139731, new HashSet<>(Arrays.asList("860600079214413","861753063502217","861753065084172","861753065084636","863975064472094","863975064473076","863975064477218","864468074456462","865883068726994","866657074641481","866657078016946","868938062699832","868938062700754")));fofoIdImeiReturnMap.put(175138958, new HashSet<>(Arrays.asList("863862075766393","864179064784108","866202075811732","866202076252654","866202078005571","868544060277439")));fofoIdImeiReturnMap.put(175139612, new HashSet<>(Arrays.asList("864468073474946","864468073477808","864468075031082","864468075280689","864468075745723","864468079481747","864468079483123","866657074538125","866657074538141","866657074573106","867467071856465","867467071875465","867467071891223","867467071913845","867467072729125","867467072760088")));fofoIdImeiReturnMap.put(175139479, new HashSet<>(Arrays.asList("863975062106595","863975064472672","863975064472870","863975064472953","863975064482333","863975064483570","863975064484719","863975064662694","863975064666455","863975064668931","863975067090257","863975067090810","863975067230218","863975067232230","866186062852892","866186062853973","866186062855051","866186062855077","866186063250773","866186063251094","866186063251219","866186063251318")));fofoIdImeiReturnMap.put(175139245, new HashSet<>(Arrays.asList("354324787133962","354324787569397","354324787602750","863816078139719","863816078448318","866335070534139")));fofoIdImeiReturnMap.put(175139324, new HashSet<>(Arrays.asList("863718060410316","863862075060755","865610074109257","866518078844457","866518079735159")));fofoIdImeiReturnMap.put(175139576, new HashSet<>(Arrays.asList("354324789013261","861128071288044","862736064686138","863718062236859","863816074642674","863816074646691","864259078939631","867467071870367","867467072760625","868565073047048")));fofoIdImeiReturnMap.put(175139150, new HashSet<>(Arrays.asList("860492060436217","861977073052257","862054073026738","862054073052056","863862077158938","866993074147710","867907071407074","868938060257450","868956064835055")));fofoIdImeiReturnMap.put(175139463, new HashSet<>(Arrays.asList("862181066909552","863816077757719","863816078448516","864214068977273","866335070447936","866335071699212","866335071699592","866335071700291")));fofoIdImeiReturnMap.put(175139722, new HashSet<>(Arrays.asList("358250293364682","358250294683627","358250295102007","861858064421273","861888066009537","864214068983198","864259078491112","864259078787733","865883068445694","866335072878930","866518078371014","868492068014968","868565072254660","868565073401468","868565073465661")));fofoIdImeiReturnMap.put(168311083, new HashSet<>(Arrays.asList("863718064506176","864468070873488","865883068175572","866335071204435","866335072093738","866518077064313","866657077386209","866657077862282","868938061427359")));fofoIdImeiReturnMap.put(175139691, new HashSet<>(Arrays.asList("863718061338714","863718061339258")));fofoIdImeiReturnMap.put(175139395, new HashSet<>(Arrays.asList("860492060436910","861220079009850","862054077288730","863511068660374","863718060300574","863718060617936","866335072874111","869452070894897")));fofoIdImeiReturnMap.put(175139621, new HashSet<>(Arrays.asList("351240553452191","351240553483527","351240553502920","354990353485570","860492062979750","860492062980998","864214068585274","864214068784398","864214068795378","864214068946534","864214068946757","864214068982075","868938061418754","868938061427391","868938062623139")));fofoIdImeiReturnMap.put(175139638, new HashSet<>(Arrays.asList("863862077159191","866518078780438","866518079750471","868428060238049","868938061532836","868938062619517")));fofoIdImeiReturnMap.put(175139313, new HashSet<>(Arrays.asList("350837023070346","350837023075022","350837023075568","350837023075782","352256988699643","862054076944275","863862075060359","863862075520055","864468075575948","865388072943635","868938060248574","868938061422830","868938062630894","869116061122184","869452070893717","869452073157912","869452074054373","869452075220890")));fofoIdImeiReturnMap.put(175139513, new HashSet<>(Arrays.asList("861977073670355","863718060618439","864468075204986","868024064295935","868024065473754","868024065567811","868024065763972","868956063947893")));fofoIdImeiReturnMap.put(175139524, new HashSet<>(Arrays.asList("350933416006946","350933416007944","351115165469199","351115165471237","351115167775437","351115167778431","351115167784413","351688420101625","355300592141142","358250295005267","358250295284607","359197386833520","359197386864947","862054073974671","862054073979597","862054074261730","862054074425954","862054074426036","864468073609384","866518078777392","868544060023239","868938060253772","868938060258516","868938061419018")));fofoIdImeiReturnMap.put(175139359, new HashSet<>(Arrays.asList("358250293060942","358250293061387","863718063044252","863862077160991","866335072536793","866335072536975","866335072537130","866335072726691","866335072726733","866335073628532","866335073925250","866335073925292","866335073926233","866335075267156")));fofoIdImeiReturnMap.put(175139397, new HashSet<>(Arrays.asList("861977073659010","863511069721050","864468071611101","864468074432844","864468074435284")));fofoIdImeiReturnMap.put(175139677, new HashSet<>(Arrays.asList("351115165472839","351115165476095","351115165476251","351115165477739","351115165483430","351115165485377","351115165486516","351115165487191","351115166897992","351115166898438","351115166900416","351115166900879","351115166902438","351115166903816","351115166903857","351115166903915","351115166904475","351115166905753","351115166906454","351115166906595","351115166907015","351115166907759","351115166907957","351115166908872","351115166909813","864259078771372","864468075692644","864468079730101","864468079736744","866657076858687","868565073398649","869116061118042","869116061261081")));fofoIdImeiReturnMap.put(175139460, new HashSet<>(Arrays.asList("860492061918494","862054079983072","862054079983171","866335070533032","866518078995119","866518079014993","868938060095017")));fofoIdImeiReturnMap.put(175139585, new HashSet<>(Arrays.asList("358250293614706","358250293614904","358250294602908","358250294603120","358250295002181","861977074487718","863718061173699","863816078050254","865883068445777","866335070453439","866335070526812","866335071204351","866518078640293","869116067596803")));fofoIdImeiReturnMap.put(175139726, new HashSet<>(Arrays.asList("861858064489411","863718063927654","864468073702221","864468073928784","864468074193149","865883068445819","866657078378742","866657078498904","867949078179850","867949078180494","868544060023197")));fofoIdImeiReturnMap.put(175139532, new HashSet<>(Arrays.asList("863718060615096","863718060615617","863718060727537","863816077797897","866335073405139","868565072217287","868565072264560","868956065132510")));fofoIdImeiReturnMap.put(175139462, new HashSet<>(Arrays.asList("865610074119819","865610074120536","866335072878658","866335072882098","866335073617030")));fofoIdImeiReturnMap.put(175139259, new HashSet<>(Arrays.asList("350210771180644","355300593052348","860492061918213","861858064422651","864259078402572","864259078924310","866335070769719","866335071700556","866335071742558","866657073553208","867949078178530","867949078692472","868024065518616","868024065619091","869116067492540")));fofoIdImeiReturnMap.put(175139344, new HashSet<>(Arrays.asList("350115571135781","354990352587723","358250293362843","358250293363148","862736064732510","865610070849617","865610070851290","866518078899998","868938062623378","868956065234613")));fofoIdImeiReturnMap.put(175139602, new HashSet<>(Arrays.asList("861128070090482","868565072242160","868565072243044","868565072261004","868565073051644")));fofoIdImeiReturnMap.put(175139605, new HashSet<>(Arrays.asList("861515075217922","861515076369466","863816074206397","863816075080072","864259078661755","864468075627368","867467071860541","868565072177903","868565073075726","868565073401625","868938060248012","868938066709652","869452074088611","869452074609234")));fofoIdImeiReturnMap.put(175139640, new HashSet<>(Arrays.asList("358250293363429","358250293363684","861753065277792","863511069733998","864214068943713","864259078496574","864259078518773","864487060042870","864487060050352","865883069366170","866518079782391","867949078692639","867949078692852","868273068551617","868938066464571","869452073150115")));fofoIdImeiReturnMap.put(175139346, new HashSet<>(Arrays.asList("356494471614953","860600076022215","861765072074616","861977070097412","864468074885181","864468076046105","865610073263139","865883065558994","866335075002538","866657079093605","867907070983216")));fofoIdImeiReturnMap.put(175139489, new HashSet<>(Arrays.asList("354324789015209","354324789081797","861515075189824","861515075575501","861977070268997","864468072790144","864468072983921","864468075233225","866657077951960","869452071082492","869452071982378","869452074617070")));fofoIdImeiReturnMap.put(175139508, new HashSet<>(Arrays.asList("861515075367024","864468072781283","864468074453386","864468075200448","864468076050669","866083062293849")));fofoIdImeiReturnMap.put(175139716, new HashSet<>(Arrays.asList("350832440575209","358250295571425","860600076019492","861753063494373","861753063501151","864468073696100","864468074855689","865883065542311","865883067956030","866202075825450","866202077663297","866335073632591","866657078023769")));fofoIdImeiReturnMap.put(175139727, new HashSet<>(Arrays.asList("355300592353325","355300593005387","861765072344258","862046060196128","864468073908604","864468073910121","864468073911269","867437074118411","868024064300099","868024065464977","868024065468218","869116065414389")));fofoIdImeiReturnMap.put(175139521, new HashSet<>(Arrays.asList("860600071402594","860600071416719","861888064397496","861977073658616","864468070509587","864468073866406","866335074999056","866657077949642","866657078406964","866993072229072","867437070891698")));fofoIdImeiReturnMap.put(175139523, new HashSet<>(Arrays.asList("354324785409950","354324788632830","354990352587939","358250295736085","358250295805187","358311601935629","863967076359575","866657074163502","867907070986318","869452071963378","869452074611750")));fofoIdImeiReturnMap.put(175139697, new HashSet<>(Arrays.asList("862282078030112","862282078867117","863975067709930","863975068443810","864468072828860","864468073705786","864468075276489","864468075277685","865610073830739","866335073264577","866518079802116","866657074518903","866657077949980","868565073058664","868938060985639","869116065613949")));fofoIdImeiReturnMap.put(175139622, new HashSet<>(Arrays.asList("358250293381926","358250293382304","358250293382601","358250294076046","358250294078109","358250294078463","358250294602064","358250294602429","358250294603062","358250294603203")));fofoIdImeiReturnMap.put(175139699, new HashSet<>(Arrays.asList("863718064441317","865610074942897","866202077653173","866202077653553","866335072262671","866335073632211","866335074805519")));fofoIdImeiReturnMap.put(175139741, new HashSet<>(Arrays.asList("861515071386101","861515074123402","861515074124186","861977073047752","861977073658574","864468075082804","864468076049869","865883065542139","865883067957111","866518070599679","866518079800672","866657078018587","866657078270162","866657079236220")));fofoIdImeiReturnMap.put(175139114, new HashSet<>(Arrays.asList("861888066708856","861977074487692","866335070051217","866335070517274","866993074145631")));fofoIdImeiReturnMap.put(175139531, new HashSet<>(Arrays.asList("863816077976194","863816079685710","866335070997336","866335074729354","866335075514698")));fofoIdImeiReturnMap.put(175139386, new HashSet<>(Arrays.asList("350210771192805","358250295053846","860388068563434","863862077333374","864468075193221","864562077193757","864718076084310","866202077464092","866202077742190","866518077001513","868565079682020","868956065252516")));fofoIdImeiReturnMap.put(175139452, new HashSet<>(Arrays.asList("350835033581484","350835034344999","350835035973283","350886063052599","351115165490559","351115165492290","351115165492811","354324788947428","354996630411503","354996631256261","355480685142494","355480686969416","359197386860549","861977073020494","862046067791525","862054077982977","866335072889499","867467072712048","868938062127511")));fofoIdImeiReturnMap.put(175139306, new HashSet<>(Arrays.asList("863718064547394","864718076075516","864718076083478","866202077463631","866202077470057")));fofoIdImeiReturnMap.put(175139733, new HashSet<>(Arrays.asList("350210771180008","861515071845668","861888067164877","866335070489094","866518076378276","868565072242269")));fofoIdImeiReturnMap.put(175138824, new HashSet<>(Arrays.asList("862054078573478","863862074697490","863862075442375","864468074485545","866335070216315","866657078016169","866657078449402","869116065542247")));fofoIdImeiReturnMap.put(175139511, new HashSet<>(Arrays.asList("862054075642557","862054075643530","862054076379357","862054077978934","863816078158016","868938062108974")));fofoIdImeiReturnMap.put(175139701, new HashSet<>(Arrays.asList("863862078258331","866611061131790")));fofoIdImeiReturnMap.put(175139552, new HashSet<>(Arrays.asList("861753065084958","866202075814439","866202075825633","866202075864194","866202076138754","866202076252811","866202077646870","866202077651094","866202077653876","866202077659956","866202077660293","866202077663339","866202078006397","866202078006611","866202078008914","866657078023280")));fofoIdImeiReturnMap.put(175139499, new HashSet<>(Arrays.asList("351115165467359","351115166905951","355358277809813","355358277814052","356049795822532","358250290682060","863862075504950","864468073944906","864468076048721","866657079234365")));fofoIdImeiReturnMap.put(175139630, new HashSet<>(Arrays.asList("357349229650288","358250290499184","358250294552947","358250294590301","860946078570556","860946078571059","861977073552215","861977073657790","861977073657832","861977073658731","861977074660850","862054075627517","862054075632756","862054075642979","862054076374879","863967071220830")));fofoIdImeiReturnMap.put(175139720, new HashSet<>(Arrays.asList("865388072300075","866335073071691","866335073073697","866335073390398")));fofoIdImeiReturnMap.put(175138854, new HashSet<>(Arrays.asList("50115570082950","351688420279827","351688420575703","354324788647382","357594162666201","359333606194530","863862075760198")));fofoIdImeiReturnMap.put(175139569, new HashSet<>(Arrays.asList("350201087565545","350201087948386","350201087949087","350210771180081","351088890316094","351088890318454","351088896121530","351088896127776","351088896127958","351088896133410","351088896133832","352476512881224","352476512979242","354448512964985","357888147926932","357888147928292","357888147928557","357888147929050","357888147929795","357888147933094","861128070182420","861753065277115","863511069713933","866657077333680","868273068567092","868565072301768","869116062743905","869452071985157","869452073161393")));fofoIdImeiReturnMap.put(175139610, new HashSet<>(Arrays.asList("862736063981738","863718063044617","866335072870176","866335072870598")));fofoIdImeiReturnMap.put(175139366, new HashSet<>(Arrays.asList("354324783144864","354324788632608","354889661849990","354990353239423","863967070558271","864718076129396","866657077789543","866657078285368","866657078508066","869116060977828","869116061054429","869116061208546")));fofoIdImeiReturnMap.put(175139412, new HashSet<>(Arrays.asList("351115165488595","351115165491318","351115165491359","351115165491458","351115165492332","355358278026573","355358278081610","861888063460717","861977073052018","863816078633919","865883069477035","866335074538870","866993071639594")));fofoIdImeiReturnMap.put(175139504, new HashSet<>(Arrays.asList("862054072660792","862054075971873","862054076312374","862054077948630","863816075363171","863862075442334","864718075894230","868938062122017","868938065268932","869452071940632","869452073034897","869452073158233","869452073158498","869452074159735")));fofoIdImeiReturnMap.put(175139201, new HashSet<>(Arrays.asList("863718061956671","863862075497734","863862075596915","864718076078510","864718076134834","866335070211639","866611060437032","866611061133812")));fofoIdImeiReturnMap.put(175139362, new HashSet<>(Arrays.asList("350201087545646","350201087547048","350201087547709","350201087548764","350201087597043","350201087597167","350201087597464","350201087597787","350201087598165","350201087600789","863718062929271","865883069477191","865883069477530","866335071174133","866518078023870","866518078243072","868938061053494")));fofoIdImeiReturnMap.put(175139661, new HashSet<>(Arrays.asList("860946077691031","861977074661155","862054073218855","866335070523694","867940069973476","868938062656477")));*/fofoIdImeiReturnMap.put(175139556, new HashSet<>(Arrays.asList("863718063534013", "866335072895173", "866335073390810")));fofoIdImeiReturnMap.put(175139721, new HashSet<>(Arrays.asList("358250294549067", "865883067508138", "866993072210619")));/*fofoIdImeiReturnMap.put(175139455, new HashSet<>(Arrays.asList("358293804087913","866518078020694","866518078021650","866518078243676","866518078571936")));fofoIdImeiReturnMap.put(175138674, new HashSet<>(Arrays.asList("351115165482275","359197386868583","862054074428875","862054077945693","862054078556879","863967070559535","863975068705671","863975068705770","864468076196124","866186064235971","866186066185117","866186066186917","866518073607370","866518079641514","868938060476456","868938060501535","868938060717990","868938062656931")));fofoIdImeiReturnMap.put(175139559, new HashSet<>(Arrays.asList("863718069016890","863816078879256","864468075283881","866335073245436","866335073403571","866657074268327","868024065473853","868956065899993","869452070362895","869452074030274")));fofoIdImeiReturnMap.put(175139575, new HashSet<>(Arrays.asList("354324786659199","860388067452035","861220078009919","863816078878134","863862075841154","865388070857498","867907071407116")));fofoIdImeiReturnMap.put(175139686, new HashSet<>(Arrays.asList("866657078019106","866657078032869")));*///this.processOrdersToRebill(fofoIdImeiReturnMap, debitNoteDate);purchaseReturnService.fixReturns(fofoIdImeiReturnMap, debitNoteDate);}private void processOrdersToRebill(Map<Integer, Set<String>> fofoIdImeiReturnMap, LocalDateTime debitNoteDate) throws Exception {for (Entry<Integer, Set<String>> fofoIdImeiReturnEntry : fofoIdImeiReturnMap.entrySet()) {int fofoId = fofoIdImeiReturnEntry.getKey();Set<String> imeis = fofoIdImeiReturnEntry.getValue();List<InventoryItem> inventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId, imeis, true);for (InventoryItem inventoryItem : inventoryItems) {//inventoryItem.getId();purchaseReturnService.returnInventoryItem(fofoId, true, inventoryItem.getId(), ReturnType.GOOD);//Approve returnPurchaseReturnItem purchaseReturnItem = purchaseReturnItemRepository.selectByInventoryItemId(inventoryItem.getId());purchaseReturnItem.setStatus(PurchaseReturnStatus.APPROVED);purchaseReturnItem.setApproveTimestamp(LocalDateTime.now());}Map<Purchase, List<InventoryItem>> purchaseInventoryItemsMap = purchaseReturnService.getPurchaseMapForApprovedReturns(fofoId);int walletAmount = walletService.getWalletAmount(fofoId);List<DebitNote> debitNotes = purchaseReturnService.generateDebitNotes(purchaseInventoryItemsMap);int walletDiff = walletAmount - walletService.getWalletAmount(fofoId);if (walletDiff > 0) {int reference = walletService.getManualReference(WalletReferenceType.OTHERS);walletService.addAmountToWallet(fofoId, reference, WalletReferenceType.ADVANCE_AMOUNT, "Sytematically added for internal PO", (float) walletDiff + 5000, LocalDateTime.now());}List<CartItem> cartItems = new ArrayList<>();for (DebitNote debitNote : debitNotes) {debitNote.setCreateTimestamp(debitNoteDate);//Try to refund amount per debit notecartItems.addAll(this.refundDnAmount(debitNote));}//If order createdMap<Integer, List<CartItem>> warehouseCartItemsMap = cartItems.stream().collect(groupingBy(x -> x.getWarehouseId()));for (Entry<Integer, List<CartItem>> warehouseCartItemsEntry : warehouseCartItemsMap.entrySet()) {List<CartItem> warehouseCartItems = warehouseCartItemsEntry.getValue();List<CartItem> mergedCartItems = warehouseCartItems.stream().collect(Collectors.collectingAndThen(groupingBy(x -> x.getItemId(), Collectors.collectingAndThen(Collectors.reducing((a, b) -> {a.setQuantity(a.getQuantity() + b.getQuantity());return a;}), Optional::get)),m -> new ArrayList<>(m.values())));double walletTotalAmount = mergedCartItems.stream().mapToDouble(x -> x.getQuantity() * x.getSellingPrice()).sum();com.spice.profitmandi.dao.entity.user.User user = userRepository.selectById(fofoId);cartService.clearCart(user.getActiveCartId());cartService.addItemsToCart(user.getActiveCartId(), mergedCartItems);UserCart userCart = new UserCart();userCart.setCartId(user.getActiveCartId());userCart.setUserId(user.getId());int transactionId = transactionService.createTransactionInternally(userCart, walletTotalAmount, warehouseCartItemsEntry.getKey());commonPaymentService.payThroughWallet(transactionId);transactionService.processTransaction(transactionId, 0);}}}@AutowiredCartService cartService;@AutowiredUserRepository userRepository;@AutowiredWarehouseScanRepository warehouseScanRepository;@AutowiredWarehouseInventoryService warehouseInventoryService;@AutowiredCommonPaymentService commonPaymentService;@AutowiredLineItemImeisRepository lineItemImeisRepository;//Also create orderprivate List<CartItem> refundDnAmount(DebitNote debitNote) throws ProfitMandiBusinessException {List<Integer> inventoryItemIds = purchaseReturnItemRepository.selectAllByDebitNoteId(debitNote.getId()).stream().map(x -> x.getInventoryItemId()).collect(Collectors.toList());Map<Integer, Long> inventoryItemCountMap = inventoryItemIds.stream().collect(groupingBy(x -> x, Collectors.counting()));List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllByIds(new ArrayList<>(inventoryItemCountMap.keySet()));Purchase purchase = purchaseRepository.selectById(inventoryItems.get(0).getPurchaseId());String invoice = purchase.getPurchaseReference();List<Order> orders = orderRepository.selectByInvoiceNumber(invoice);Set<Integer> orderIds = orders.stream().map(x -> x.getId()).collect(Collectors.toSet());Order order = orders.get(0);float totalAmount = 0;int totalQty = 0;Map<Integer, CartItem> itemIdCartItemMap = new HashMap<>();// Batch fetch all TagListings by itemIds to avoid N+1 queriesSet<Integer> allItemIds = inventoryItems.stream().map(InventoryItem::getItemId).collect(Collectors.toSet());List<TagListing> allTagListings = tagListingRepository.selectByItemIdsAndTagIds(allItemIds, null);Map<Integer, TagListing> itemIdTagListingMap = allTagListings.stream().collect(Collectors.toMap(TagListing::getItemId, t -> t, (u, v) -> u));List<CartItem> cartItems = new ArrayList<>();for (InventoryItem inventoryItem : inventoryItems) {TagListing tagListing = itemIdTagListingMap.get(inventoryItem.getItemId());long quantity = inventoryItemCountMap.get(inventoryItem.getId());totalAmount += inventoryItem.getUnitPrice() * quantity;totalQty += quantity;if (!itemIdCartItemMap.containsKey(inventoryItem.getItemId())) {CartItem cartItem = new CartItem();cartItem.setItemId(inventoryItem.getItemId());cartItem.setSellingPrice(tagListing.getSellingPrice());cartItem.setWarehouseId(order.getWarehouseId());cartItems.add(cartItem);itemIdCartItemMap.put(inventoryItem.getItemId(), cartItem);}CartItem cartItem = itemIdCartItemMap.get(inventoryItem.getItemId());cartItem.setQuantity((int) quantity + cartItem.getQuantity());}String rollbackDescription = String.format("Refunded against DN %s, %d pc(s)", debitNote.getDebitNoteNumber(), totalQty);walletService.addAmountToWallet(debitNote.getFofoId(), order.getTransactionId(), WalletReferenceType.PURCHASE, rollbackDescription, totalAmount, LocalDateTime.now());//Before creating order lets try to in the stock//All scans pertaining to specific InvoicesList<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(new ArrayList<>(orderIds));Map<Integer, Integer> inventoryItemIdOrderIdMap = new HashMap<>();try {inventoryItemIdOrderIdMap = warehouseScans.stream().collect(Collectors.toMap(x -> x.getInventoryItemId(), x -> x.getQuantity()));} catch (Exception e) {LOGGER.info("Could not process for fofoId - {}, {}", debitNote.getFofoId(), warehouseScans);}List<Integer> warehouseInventoryItemIds = warehouseScans.stream().filter(x -> !(x.getType().equals(in.shop2020.warehouse.ScanType.SALE_RET) || x.getType().equals(in.shop2020.warehouse.ScanType.SALE_RET_UNUSABLE))).map(x -> x.getInventoryItemId()).collect(Collectors.toList());List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectAllByIds(warehouseInventoryItemIds);Map<String, WarehouseInventoryItem> serialNumberWarehouseInventoryItemMap = warehouseInventoryItems.stream().filter(x -> StringUtils.isNotBlank(x.getSerialNumber())).collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x));for (InventoryItem inventoryItem : inventoryItems) {if (StringUtils.isBlank(inventoryItem.getSerialNumber())) {//As of now this should be happening as dn are specifically for serialized devices/*int returnQty = inventoryItemCountMap.get(inventoryItem.getId()).intValue();List<WarehouseInventoryItem> warehouseInventoryItemList = itemIdWarehouseInventoryItemsMap.get(inventoryItem.getItemId());warehouseInventoryService.returnNonSerializedQty(warehouseInventoryItem)*/} else if (StringUtils.isNotBlank(inventoryItem.getSerialNumber())) {String serialNumber = inventoryItem.getSerialNumber();WarehouseInventoryItem warehouseInventoryItem = serialNumberWarehouseInventoryItemMap.get(serialNumber);warehouseInventoryItem.setLastScanType(in.shop2020.warehouse.ScanType.SALE_RET);warehouseInventoryService.addQuantity(warehouseInventoryItem.getId(), 1);WarehouseScan warehouseScan = new WarehouseScan();warehouseScan.setInventoryItemId(warehouseInventoryItem.getId());warehouseScan.setQuantity(1);warehouseScan.setOrderId(inventoryItemIdOrderIdMap.get(warehouseInventoryItem.getItemId()));warehouseScan.setScannedAt(LocalDateTime.now());warehouseScan.setType(in.shop2020.warehouse.ScanType.SALE_RET);warehouseScanRepository.persist(warehouseScan);}}//Create Order as wellreturn cartItems;}void addToCartAndCreateOrder() {}@AutowiredWarehouseDebitNoteRepository warehouseDebitNoteRepository;@AutowiredWarehouseDebitNoteLineRepository warehouseDebitNoteLineRepository;@AutowiredWarehouseInvoiceItemRepository warehouseInvoiceItemRepository;@AutowiredWarehouseSupplierInvoiceRepository warehouseSupplierInvoiceRepository;@AutowiredPurchaseOrderService purchaseOrderService;@AutowiredVendorCatalogPricingLogRepository vendorCatalogPricingLogRepository;// private void checkItelImeiActivationNew(LocalDate now, int i) {// }@AutowiredSessionFactory sessionFactory;public void sendMailForSamsungRebilling() throws Exception {List<BilledImeiModel> samsungModels = warehouseInventoryItemRepository.findByBillingDateBrand(LocalDate.now(), "Samsung");LOGGER.info("SamsungModels {}", samsungModels);samsungModels = samsungModels.stream().sorted(Comparator.comparing(x -> x.getPcmDate() == null ? -1 : 1)).collect(Collectors.toList());if (samsungModels.size() > 0) {List<String> headers = Arrays.asList("Partner Id", "Code", "Name", "City", "Brand", "Model Name", "Model Number", "Color", "Serial Number", "Remarks");List<List<?>> rows = new ArrayList<>();for (BilledImeiModel billedImeiModel : samsungModels) {List<Serializable> row = Arrays.asList(billedImeiModel.getFofoId(), billedImeiModel.getStoreCode(), billedImeiModel.getStoreName(), billedImeiModel.getStoreCity(), billedImeiModel.getBrand(), billedImeiModel.getModelName(), billedImeiModel.getModelNumber(), billedImeiModel.getColor(), billedImeiModel.getSerialNumber(), billedImeiModel.getPcmDate() == null ? "PCM date Missing" : "Rebill Imeis");rows.add(row);}ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);String[] sendToArray = new String[]{"kamini.sharma@smartdukaan.com", "praveen.sharma@smartdukaan.com"};String fileName = "Imeis need Rebilling -" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";Utils.sendMailWithAttachment(googleMailSender, sendToArray, new String[]{"tarun.verma@smartdukaan.com"}, "Samsung Rebilling IMEI Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));}}public void sendPartnerInvestmentDetails(List<String> sendTo) throws Exception {LocalDate yesterDay = LocalDate.now().minusDays(1);List<FofoStore> fofoStores = fofoStoreRepository.selectActiveStores();Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoStores.stream().map(x -> x.getId()).collect(Collectors.toList()));List<String> headers = Arrays.asList("Code", "Outlet name", "State Manager", "Territory/Team Lead", "Wallet Amount", "In Stock Amount", "Activated Stock", "Return In Transit Stock", "Unbilled Amount", "Grn Pending Amount", "Min Investment", "Investment Amount", "Investment Short", "Unbilled Qty", "Short Days");List<List<?>> rows = new ArrayList<>();Map<Integer, List<?>> partnerRowsMap = new HashMap<>();Map<Integer, FofoReportingModel> partnerIdSalesHeaderMap = this.getPartnerIdSalesHeaders();Map<Integer, Integer> shortDaysMap = partnerDailyInvestmentRepository.selectAll(LocalDate.now().withDayOfMonth(1), LocalDate.now()).stream().collect(groupingBy(x -> x.getFofoId(), Collectors.summingInt(x -> x.getShortPercentage() > 10 ? 1 : 0)));for (FofoStore fofoStore : fofoStores) {LOGGER.info("Fofo Store {}, {}", fofoStore.getId(), fofoStore.getCode());int fofoId = fofoStore.getId();PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoId, 1);partnerDailyInvestment.setDate(yesterDay);try {partnerDailyInvestmentRepository.persist(partnerDailyInvestment);shortDaysMap.put(fofoId, shortDaysMap.get(fofoId) + (partnerDailyInvestment.getShortPercentage() > 10 ? 1 : 0));} catch (Exception e) {// ignore the exceptions during persist}CustomRetailer retailer = customRetailerMap.get(fofoStore.getId());if (retailer == null || partnerIdSalesHeaderMap.get(fofoStore.getId()) == null) {LOGGER.info("Could not find retailer with retailer Id {}", fofoStore.getId());continue;}FofoReportingModel reportingModel = partnerIdSalesHeaderMap.get(fofoStore.getId());List<Serializable> row = new ArrayList<>();row.addAll(Arrays.asList(reportingModel.getCode(), reportingModel.getBusinessName(), reportingModel.getRegionalManager(), reportingModel.getTerritoryManager()));row.addAll(Arrays.asList(partnerDailyInvestment.getWalletAmount(), partnerDailyInvestment.getInStockAmount(), partnerDailyInvestment.getActivatedStockAmount() == 0 ? "-" : "(" + partnerDailyInvestment.getActivatedStockAmount() + ")", 0, partnerDailyInvestment.getUnbilledAmount(), partnerDailyInvestment.getGrnPendingAmount(), partnerDailyInvestment.getMinInvestment(), partnerDailyInvestment.getTotalInvestment(), partnerDailyInvestment.getShortInvestment(), partnerDailyInvestment.getUnbilledQty(), shortDaysMap.get(fofoId)));partnerRowsMap.put(fofoStore.getId(), row);rows.add(row);}String fileName = "InvestmentSummary-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";if (sendTo == null) {for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMapping().entrySet()) {List<List<?>> filteredRows = storeGuyEntry.getValue().stream().map(x -> partnerRowsMap.get(x)).filter(x -> x != null).collect(Collectors.toList());ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, filteredRows);String[] sendToArray = new String[]{storeGuyEntry.getKey()};Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Franchise Investment Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));}sendTo = Arrays.asList("tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com", "neeraj.gupta@smartdukaan.com", "amit.gupta@shop2020.in", "manish.gupta1@smartdukaan.com", "niranjan.kala@smartdukaan.com");}ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);String[] sendToArray = sendTo.toArray(new String[sendTo.size()]);Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Franchise Investment Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));}private Map<Integer, FofoReportingModel> getPartnerIdSalesHeaders() throws ProfitMandiBusinessException {Map<String, SaleRoles> partnerEmailSalesMap = new HashMap<>();Map<String, SaleRoles> partnerEmailRBMMap = new HashMap<>();Map<String, SaleRoles> partnerEmailABMMap = new HashMap<>();List<Position> positions = positionRepository.selectPositionByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_ABM));Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));Map<Integer, List<CustomRetailer>> positionIdRetailerMap = csService.getPositionCustomRetailerMap(positions);for (Position position : positions) {List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());if (crList == null)continue;if (position.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES) {for (CustomRetailer cr : crList) {if (!partnerEmailSalesMap.containsKey(cr.getEmail())) {partnerEmailSalesMap.put(cr.getEmail(), new SaleRoles());}SaleRoles saleRoles = partnerEmailSalesMap.get(cr.getEmail());AuthUser authUser = authUsersMap.get(position.getAuthUserId());if (authUser == null) {continue;}String name = authUser.getFirstName() + " " + authUser.getLastName();if (position.getEscalationType().equals(EscalationType.L1)) {saleRoles.getL1().add(name);} else if (position.getEscalationType().equals(EscalationType.L2)) {saleRoles.getL2().add(name);}}}if (position.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_RBM) {for (CustomRetailer cr : crList) {if (!partnerEmailRBMMap.containsKey(cr.getEmail())) {partnerEmailRBMMap.put(cr.getEmail(), new SaleRoles());}SaleRoles saleRoles = partnerEmailRBMMap.get(cr.getEmail());AuthUser authUser = authUsersMap.get(position.getAuthUserId());if (authUser == null) {continue;}String name = authUser.getFirstName() + " " + authUser.getLastName();if (position.getEscalationType().equals(EscalationType.L1) || position.getEscalationType().equals(EscalationType.L1)) {saleRoles.getL1().add(name);}/*else if (position.getEscalationType().equals(EscalationType.L2)) {saleRoles.getL2().add(name);}*/}}if (position.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_ABM) {for (CustomRetailer cr : crList) {if (!partnerEmailABMMap.containsKey(cr.getEmail())) {partnerEmailABMMap.put(cr.getEmail(), new SaleRoles());}SaleRoles saleRoles = partnerEmailABMMap.get(cr.getEmail());AuthUser authUser = authUsersMap.get(position.getAuthUserId());if (authUser == null) {continue;}String name = authUser.getFirstName() + " " + authUser.getLastName();if (position.getEscalationType().equals(EscalationType.L1) || position.getEscalationType().equals(EscalationType.L1)) {saleRoles.getL1().add(name);} else if (position.getEscalationType().equals(EscalationType.L2)) {saleRoles.getL2().add(name);}}}}Set<CustomRetailer> allCrList = new HashSet<>();for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {allCrList.addAll(cr);}Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));Map<Integer, FofoReportingModel> partnerIdSalesHeadersMap = new HashMap<>();for (CustomRetailer cr : allCrList) {FofoStore fofoStore = fofoStoresMap.get(cr.getPartnerId());if (fofoStore == null) {LOGGER.info("Could not find Store {} in active Store", cr.getBusinessName());continue;}String code = fofoStore.getCode();// String storeName = "SmartDukaan-" +// fofoStore.getCode().replaceAll("[a-zA-Z]", "");String businessName = cr.getBusinessName();try {String stateManager = StringUtils.join(partnerEmailSalesMap.get(cr.getEmail()).getL2(), ", ");String territoryManager = StringUtils.join(partnerEmailSalesMap.get(cr.getEmail()).getL1(), ", ");String bdm = StringUtils.join(partnerEmailRBMMap.get(cr.getEmail()).getL1(), ", ");FofoReportingModel reportingModel = new FofoReportingModel();reportingModel.setBusinessName(businessName);reportingModel.setCode(code);reportingModel.setFofoId(fofoStore.getId());reportingModel.setRegionalManager(stateManager);reportingModel.setTerritoryManager(territoryManager);reportingModel.setBusinessManager(bdm);partnerIdSalesHeadersMap.put(fofoStore.getId(), reportingModel);} catch (Exception e) {LOGGER.warn("Could not find partner with email - {}", cr.getEmail());}}return partnerIdSalesHeadersMap;}public void persistRbmTodayTargets() throws Exception {rbmTargetService.setMovementWiseRbmTargets();}public void persistRbmTodayAchievements() throws Exception {rbmTargetService.setMovementWiseRbmAchievement();}public void sendPartnerInvestmentDetails() throws Exception {this.sendPartnerInvestmentDetails(null);}public void sendAgeingReport(String... sendTo) throws Exception {InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.WAREHOUSENEW, "itemstockageing.xml");InputStreamSource isr1 = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "ItemwiseOverallPendingIndent.xml");Attachment attachment = new Attachment("ageing-report-" + FormattingUtils.formatDate(LocalDateTime.now().minusDays(1)) + ".csv", isr);Attachment attachment1 = new Attachment("pending-indent-" + FormattingUtils.formatDate(LocalDateTime.now().minusDays(1)) + ".csv", isr1);Utils.sendMailWithAttachments(googleMailSender, STOCK_AGEING_MAIL_LIST, null, "Stock Ageing Report", "PFA", attachment);Utils.sendMailWithAttachments(googleMailSender, ITEMWISE_PENDING_INDENT_MAIL_LIST, null, "Itemwise Pending indent", "PFA", attachment1);// Reports to be sent to mapped partnersMap<String, Set<String>> storeGuysMap = csService.getAuthUserPartnerEmailMapping();for (Entry<String, Set<String>> storeGuyEntry : storeGuysMap.entrySet()) {Map<String, String> params = new HashMap<>();if (storeGuyEntry.getValue().size() == 0)continue;params.put("MANUAL_email", String.join(",", storeGuyEntry.getValue()));InputStreamSource isr3 = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "focostockreport.xml", params);Attachment attache = new Attachment("Franchise-stock-report" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr3);System.out.println(storeGuyEntry.getValue());Utils.sendMailWithAttachments(googleMailSender, new String[]{storeGuyEntry.getKey()}, null, "Franchise Stock Report", "PFA", attache);}}public void sendIndentTertiary() throws Exception {InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "indentandtertiary.xml");Attachment attachment = new Attachment("indentandtertiary-report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr);Utils.sendMailWithAttachments(googleMailSender, INDENT_TERTIARY_MAIL_LIST, null, "Indent Tertiary Report", "PFA", attachment);}public void sendAttendanceMorningAlert() throws Exception {LocalDateTime moriningTime = LocalDate.now().atTime(10, 31);List<AuthUser> authUsers = authRepository.selectAllActiveUser();Map<String, AuthUser> authUserEmailMap = authUsers.stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getEmailId(), x -> x));List<User> users = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.keySet()));Map<String, User> userMap = users.stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x));List<EmployeeAttendance> employeeAttendances = employeeAttendanceRepository.selectAllByDatesBetween(LocalDate.now().atStartOfDay(), LocalDateTime.now());Map<Integer, Optional<EmployeeAttendance>> employeeMorningAttendance = employeeAttendances.stream().collect(groupingBy(EmployeeAttendance::getUserId, Collectors.minBy(Comparator.comparing(EmployeeAttendance::getCreateTimestamp))));for (AuthUser authUser : authUsers) {User user = userMap.get(authUser.getEmailId());Optional<EmployeeAttendance> employeeAttendanceOptional = employeeMorningAttendance.get(user.getId());LOGGER.info("AuthUser - {}, employeeAttendanceOptional {}", authUser.getName(), employeeAttendanceOptional);if (employeeAttendanceOptional != null) {LOGGER.info("employeeAttendanceOptional.orElse {}", employeeAttendanceOptional.orElse(null));if (employeeAttendanceOptional.orElse(null) != null) {LOGGER.info("employeeAttendanceOptional.get().getCreateTimestamp() {}", employeeAttendanceOptional.get().getCreateTimestamp());}}if (employeeAttendanceOptional == null || employeeAttendanceOptional.orElse(null) == null || employeeAttendanceOptional.get().getCreateTimestamp().isAfter(moriningTime)) {LOGGER.info("Will Send Email to {}", authUser.getFullName());String body = String.format("Dear %s,\n Pls note that you haven't punched your attendance by 10:30am%s. You have been marked absent for half the day.\n\nRegards\nHR Team", authUser.getFullName(), (employeeAttendanceOptional == null || employeeAttendanceOptional.orElse(null) == null) ? "" : "(Punched at " + FormattingUtils.format(employeeAttendanceOptional.get().getCreateTimestamp()) + ")");Utils.sendMailWithAttachments(googleMailSender, new String[]{authUser.getEmailId()}, new String[]{"kangan.monga@smartdukaan.com"}, "Attendance Alert", body);}}}public void sendAttendanceEveningAlert() throws Exception {List<AuthUser> authUsers = authRepository.selectAllActiveUser();Map<String, AuthUser> authUserEmailMap = authUsers.stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getEmailId(), x -> x));List<User> users = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.keySet()));Map<String, User> userMap = users.stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x));Map<Integer, List<EmployeeAttendance>> employeeAttendancesMap = employeeAttendanceRepository.selectAllByDatesBetween(LocalDate.now().atStartOfDay(), LocalDateTime.now()).stream().collect(groupingBy(x -> x.getUserId()));for (AuthUser authUser : authUsers) {User user = userMap.get(authUser.getEmailId());String body = null;List<EmployeeAttendance> employeeAttendances = employeeAttendancesMap.get(user.getId());if (employeeAttendances == null) {body = String.format("Dear %s,\n No attendance has been registered by you today. You have been marked absent for the day.\n\nRegards\nHR Team", authUser.getFullName());} else {List<LocalDateTime> punchTimes = employeeAttendances.stream().sorted(Comparator.comparing(EmployeeAttendance::getCreateTimestamp)).map(x -> x.getCreateTimestamp()).collect(Collectors.toList());if (punchTimes.size() == 1) {// body = String.format("Dear %s,\n Pls note that you haven't punched out yet.// You have been marked absent for half the day. You may contact your manager// and get it regularise.\n\nRegards\nHR Team", authUser.getFullName());} else {LocalDateTime firstPunch = punchTimes.get(0);LocalDateTime lastPunch = punchTimes.get(punchTimes.size() - 1);Duration duration = Duration.between(firstPunch, lastPunch);boolean hoursCompleted = lastPunch.isAfter(firstPunch.plusHours(8).plusMinutes(30));if (!hoursCompleted) {body = String.format("Dear %s,\n Pls note that you haven't completed 8.30 Hrs (%d.%d Hrs). You have been marked absent for half the day.\n\nRegards\nHR Team", authUser.getFullName(), duration.toHours(), duration.toMinutes() - duration.toHours() * 60);}}}if (body != null) {Utils.sendMailWithAttachments(googleMailSender, new String[]{authUser.getEmailId()}, new String[]{"kangan.monga@smartdukaan.com"}, "Attendance Alert", body);}}this.sendMailToHR();}private void sendMailToHR() throws Exception {Map<String, String> map = new HashMap<>();String reporticoDate = FormattingUtils.formatReporitcoDate(LocalDateTime.now());map.put("MANUAL_datesBetween_FROMDATE", reporticoDate);map.put("MANUAL_datesBetween_FROMDATE", reporticoDate);InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO, "employeeattendance.xml");Attachment attachment = new Attachment("attendance-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr);Utils.sendMailWithAttachments(googleMailSender, EMPLOYEE_ATTENDANCE_MAIL_LIST, null, "Attendance - " + FormattingUtils.formatDate(LocalDateTime.now()), "PFA Attendance", attachment);}public void checkPartnerActiveStore() throws Exception {List<FofoStore> fofoStores = fofoStoreRepository.selectByStatus(true);LocalDateTime currentDate = LocalDate.now().atStartOfDay();if (!fofoStores.isEmpty()) {for (FofoStore fofoStore : fofoStores) {if (currentDate.isBefore(fofoStore.getActiveTimeStamp())) {fofoStore.setActive(true);fofoStoreRepository.persist(fofoStore);LOGGER.info("inserted into InActiveFofoStore successfully");} else {fofoStore.setActive(false);fofoStore.setActiveTimeStamp(null);fofoStoreRepository.persist(fofoStore);LOGGER.info("inserted into InActiveFofoStore successfully");}}}}public void sendAgeingReport() throws Exception {sendAgeingReport("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com", "niranjan.kala@smartdukaan.com", "kuldeep.kumar@smartdukaan.com");}public void moveImeisToPriceDropImeis() throws Exception {List<PriceDrop> priceDrops = priceDropRepository.selectAll();for (PriceDrop priceDrop : priceDrops) {priceDropService.priceDropStatus(priceDrop.getId());}}public void walletmismatch() throws Exception {LocalDate curDate = LocalDate.now();List<PartnerDailyInvestment> pdis = partnerDailyInvestmentRepository.selectAll(curDate.minusDays(2));System.out.println(pdis.size());for (PartnerDailyInvestment pdi : pdis) {int fofoId = pdi.getFofoId();for (PartnerDailyInvestment investment : Lists.reverse(partnerDailyInvestmentRepository.selectAll(fofoId, null, null))) {float statementAmount = walletService.getOpeningTill(fofoId, investment.getDate().plusDays(1).atTime(LocalTime.of(4, 0)));CustomRetailer retailer = retailerService.getFofoRetailer(fofoId);LOGGER.info("{}\t{}\t{}\t{}\t{}", fofoId, retailer.getBusinessName(), retailer.getMobileNumber(), investment.getDate().toString(), investment.getWalletAmount(), statementAmount);}}}@AutowiredStateRepository stateRepository;public void gst() throws Exception {List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(LocalDate.of(2021, 8, 16).atStartOfDay(), LocalDateTime.now());for (FofoOrder fofoOrder : fofoOrders) {int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoOrder.getFofoId());Address retailerAddress = addressRepository.selectById(retailerAddressId);CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());Integer stateId = null;if (customerAddress.getState().equals(retailerAddress.getState())) {try {stateId = stateRepository.selectByName(customerAddress.getState()).getId();} catch (Exception e) {LOGGER.error("Cannot found state named {}", customerAddress.getState());continue;}}Map<Integer, GstRate> itemIdStateTaxRateMap = null;List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());if (stateId != null) {itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(itemIds, stateId);} else {itemIdStateTaxRateMap = stateGstRateRepository.getIgstTaxRate(itemIds);}for (FofoOrderItem foi : fofoOrderItems) {float sgstRate = foi.getSgstRate();float cgstRate = foi.getCgstRate();float igstRate = foi.getIgstRate();foi.setCgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getCgstRate());foi.setSgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getSgstRate());foi.setIgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getIgstRate());LOGGER.info("Invoice {}, Date {}", fofoOrder.getInvoiceNumber(), fofoOrder.getCreateTimestamp());LOGGER.info("customerAddress.getState() {}, retailerAddress.getState() {}", customerAddress.getState(), retailerAddress.getState());LOGGER.info("Rates getIgstRate() {}", itemIdStateTaxRateMap.get(foi.getItemId()).getIgstRate());LOGGER.info("Rates getCgstRate() {}, getSgstRate() {}", itemIdStateTaxRateMap.get(foi.getItemId()).getCgstRate(), itemIdStateTaxRateMap.get(foi.getItemId()).getSgstRate());}}}public void schemewalletmismatch() throws ProfitMandiBusinessException {LocalDate dateToReconcile = LocalDate.of(2018, 4, 1);while (dateToReconcile.isBefore(LocalDate.now())) {reconcileSchemes(dateToReconcile);// reconcileOrders(dateTime);// reconcileRecharges(dateTime);dateToReconcile = dateToReconcile.plusDays(1);}}private void reconcileSchemes(LocalDate date) throws ProfitMandiBusinessException {LocalDateTime startDate = date.atStartOfDay();LocalDateTime endDate = startDate.plusDays(1);List<SchemeInOut> siosCreated = schemeInOutRepository.selectAllByCreateDate(startDate, endDate);List<SchemeInOut> siosRefunded = schemeInOutRepository.selectAllByRefundDate(startDate, endDate);double totalSchemeDisbursed = siosCreated.stream().mapToDouble(x -> x.getAmount()).sum();double totalSchemeRolledback = siosRefunded.stream().mapToDouble(x -> x.getAmount()).sum();double netSchemeDisbursed = totalSchemeDisbursed - totalSchemeRolledback;List<WalletReferenceType> walletReferenceTypes = Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT);List<UserWalletHistory> history = userWalletHistoryRepository.selectAllByDateType(startDate, endDate, walletReferenceTypes);double schemeAmountWalletTotal = history.stream().mapToDouble(x -> x.getAmount()).sum();if (Math.abs(netSchemeDisbursed - schemeAmountWalletTotal) > 10d) {LOGGER.info("Scheme Amount mismatched for Date {}", date);Map<Integer, Double> inventoryItemSchemeIO = siosCreated.stream().collect(groupingBy(x -> x.getInventoryItemId(), Collectors.summingDouble(SchemeInOut::getAmount)));Map<Integer, Double> userSchemeMap = inventoryItemRepository.selectByIds(inventoryItemSchemeIO.keySet()).stream().collect(groupingBy(x -> x.getFofoId(), Collectors.summingDouble(x -> inventoryItemSchemeIO.get(x.getId()))));Map<Integer, Double> inventoryItemSchemeIORefunded = siosRefunded.stream().collect(groupingBy(x -> x.getInventoryItemId(), Collectors.summingDouble(SchemeInOut::getAmount)));Map<Integer, Double> userSchemeRefundedMap = inventoryItemRepository.selectByIds(inventoryItemSchemeIORefunded.keySet()).stream().collect(groupingBy(x -> x.getFofoId(), Collectors.summingDouble(x -> inventoryItemSchemeIORefunded.get(x.getId()))));Map<Integer, Double> finalUserSchemeAmountMap = new HashMap<>();for (Entry<Integer, Double> schemeAmount : userSchemeRefundedMap.entrySet()) {if (!finalUserSchemeAmountMap.containsKey(schemeAmount.getKey())) {finalUserSchemeAmountMap.put(schemeAmount.getKey(), schemeAmount.getValue());} else {finalUserSchemeAmountMap.put(schemeAmount.getKey(), finalUserSchemeAmountMap.get(schemeAmount.getKey()) + schemeAmount.getValue());}}Map<Integer, Integer> userWalletMap = userWalletRepository.selectByRetailerIds(finalUserSchemeAmountMap.keySet()).stream().collect(Collectors.toMap(UserWallet::getUserId, UserWallet::getId));Map<Integer, Double> walletAmountMap = history.stream().collect(groupingBy(UserWalletHistory::getWalletId, Collectors.summingDouble((UserWalletHistory::getAmount))));for (Entry<Integer, Double> userAmount : walletAmountMap.entrySet()) {double diff = Math.abs(finalUserSchemeAmountMap.get(userAmount.getKey()) - userAmount.getValue());if (diff > 5) {LOGGER.info("Partner scheme mismatched for Userid {}", userWalletMap.get(userAmount.getKey()));}}}}public void sendDailySalesNotificationToPartner(Integer fofoIdInt) throws Exception {LocalDateTime now = LocalDateTime.now();LocalDateTime from = now.with(LocalTime.MIN);String timeString = "Today %s";// Send yesterday's report/** if (now.getHour() < 13) { timeString = "Yesterday %s"; from =* now.minusDays(1).; now = from.with(LocalTime.MAX);** }*/List<Integer> fofoIds = null;Map<Integer, FofoStore> fofoStoreMap = fofoStoreRepository.selectAll().stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getId(), x -> x));if (fofoIdInt == null) {fofoIds = new ArrayList<>(fofoStoreMap.keySet());} else {fofoIds = Arrays.asList(fofoIdInt);}DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:m a");Map<Integer, Float> partnerPolicyAmountMap = insurancePolicyRepository.selectAmountSumGroupByRetailerId(now, null);Map<Integer, Long> partnerPolicyQtyMap = insurancePolicyRepository.selectQtyGroupByRetailerId(now, null);Map<Integer, Double> spPartnerOrderValMap = fofoOrderItemRepository.selectSumAmountGroupByRetailer(from, now, 0, true);Map<Integer, Double> spPartner3DaysOrderValMap = fofoOrderItemRepository.selectSumAmountGroupByRetailer(from.minusDays(3), now, 0, true);Map<Integer, Long> spPartnerOrderQtyMap = fofoOrderItemRepository.selectQtyGroupByRetailer(from, now, 0, true);Map<Integer, Double> partnerOrderValMap = fofoOrderItemRepository.selectSumAmountGroupByRetailer(from, now, 0, false);Map<Integer, Long> partnerOrderQtyMap = fofoOrderItemRepository.selectQtyGroupByRetailer(from, now, 0, false);//4 days + current day runningMap<Integer, Double> partnerBilledValueMap = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(from.minusDays(4), now);Map<Integer, SaleTargetReportModel> saleTargetReportModelMap = new HashMap<>();for (int fofoId : fofoIds) {SaleTargetReportModel model = new SaleTargetReportModel();model.setInsuranceSale(partnerPolicyAmountMap.containsKey(fofoId) ? partnerPolicyAmountMap.get(fofoId).doubleValue() : 0);model.setInsruanceQty(partnerPolicyQtyMap.containsKey(fofoId) ? partnerPolicyQtyMap.get(fofoId) : 0);model.setSecondary(partnerBilledValueMap.containsKey(fofoId) ? partnerBilledValueMap.get(fofoId) : 0);model.setSmartphoneSale(spPartnerOrderValMap.containsKey(fofoId) ? spPartnerOrderValMap.get(fofoId) : 0);model.setSmartphoneQty(spPartnerOrderQtyMap.containsKey(fofoId) ? spPartnerOrderQtyMap.get(fofoId) : 0);model.setTotalSale(partnerOrderValMap.containsKey(fofoId) ? partnerOrderValMap.get(fofoId) : 0);model.setTotalQty(partnerOrderQtyMap.containsKey(fofoId) ? partnerOrderQtyMap.get(fofoId) : 0);model.setPast3daysSale(spPartner3DaysOrderValMap.containsKey(fofoId) ? spPartner3DaysOrderValMap.get(fofoId) : 0);model.setFofoId(fofoId);model.setCode(fofoStoreMap.get(fofoId).getCode());model.setActivationType(fofoStoreMap.get(fofoId).getActivationType());saleTargetReportModelMap.put(fofoId, model);}Map<Integer, FofoReportingModel> partnerSalesHeadersMap = this.getPartnerIdSalesHeaders();for (Integer fofoId : fofoIds) {SaleTargetReportModel model = saleTargetReportModelMap.get(fofoId);// com.spice.profitmandi.dao.entity.user.User user =// userUserRepository.selectById(fofoId);// Address address = addressRepository.selectById(user.getAddressId());String title = "Sale Update";String messageTemplate = String.format("Smartphones Rs.%.0f, Insurance Rs.%.0f, Total Rs.%.0f till %s.", model.getSmartphoneSale(), model.getInsuranceSale(), model.getTotalSale(), String.format(timeString, now.format(timeFormatter)));SendNotificationModel sendNotificationModel = new SendNotificationModel();sendNotificationModel.setCampaignName("Sales update alert");sendNotificationModel.setTitle(title);sendNotificationModel.setMessage(messageTemplate);sendNotificationModel.setType("url");sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));sendNotificationModel.setMessageType(MessageType.notification);int userId = userAccountRepository.selectUserIdByRetailerId(fofoId);sendNotificationModel.setUserIds(Arrays.asList(userId));notificationService.sendNotification(sendNotificationModel);String whatsappMessageTemplate = String.format("Dear Partner, Your sale update is Smartphones Rs.%.0f, Insurance Rs.%.0f, Total Rs.%.0f till %s.", model.getSmartphoneSale(), model.getInsuranceSale(), model.getTotalSale(), String.format(timeString, now.format(timeFormatter)));// notificationService.sendWhatsappMessage(whatsappMessageTemplate, title,// address.getPhoneNumber());}// String saleReport = this.getDailySalesReportHtml(partnerSalesHeadersMap,// saleTargetReportModelMap);this.getStateWiseSales(saleTargetReportModelMap, partnerSalesHeadersMap);}public void checkRazorPayPaymentStatus() throws Exception {List<PendingOrder> pendingOrder = pendingOrderRepository.selectAllByStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.PENDING);for (PendingOrder po : pendingOrder) {RazorPay razorPay = razorPayRepository.selectByOrdeId(po.getId());List<PendingOrderItem> poItems = pendingOrderItemRepository.selectByOrderId(po.getId());LOGGER.info("razorPay" + razorPay);if (razorPay != null) {List<Payment> payments = razorPaymentService.fetchOrderForPayment(razorPay.getRazorOrderId());if (!payments.isEmpty()) {List<String> statusList = new ArrayList<>();for (Payment payment : payments) {JSONObject jsonObj = new JSONObject(payment.toString());String status = jsonObj.getString("status");statusList.add(status);}LOGGER.info("statusList" + statusList);if (statusList.contains("authorized") || statusList.contains("captured")) {po.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.PROCESSING);po.setPaidAmount(po.getTotalAmount());for (PendingOrderItem poi : poItems) {poi.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.PROCESSING);}Map<String, Object> emailModel = pendingOrderService.sendCreateOrderMail(po);CustomRetailer customRetailer = retailerService.getFofoRetailer(po.getFofoId());Customer customer = customerRepository.selectById(po.getCustomerId());String[] customerEmail = null;if (customer.getEmailId() != null) {customerEmail = new String[]{customer.getEmailId()};}List<String> bccTo = Arrays.asList("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com", "niranjan.kala@smartdukaan.com", "sm@smartdukaan.com", "tejbeer.kaur@shop2020.in", customRetailer.getEmail());List<String> authUserEmails = csService.getAuthUserByPartnerId(customRetailer.getPartnerId());if (authUserEmails != null) {authUserEmails = new ArrayList<>();}authUserEmails.addAll(bccTo);// emailService.sendMailWithAttachments("Order Created with SmartDukaan",// "order-confirm.vm",// emailModel, customerEmail, null, authUserEmails.toArray(new String[0]));} else if (statusList.contains("refunded") || statusList.contains("failed")) {for (PendingOrderItem poi : poItems) {poi.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.FAILED);}po.setStatus(com.spice.profitmandi.dao.enumuration.transaction.OrderStatus.FAILED);}}// LOGGER.info("payment" + payments);}}}public static class SaleTargetReportModel {private double totalSale;private long totalQty;private double past3daysSale;private int fofoId;private String code;private ActivationType activationType;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;SaleTargetReportModel that = (SaleTargetReportModel) o;return Double.compare(that.totalSale, totalSale) == 0 && totalQty == that.totalQty && Double.compare(that.past3daysSale, past3daysSale) == 0 && fofoId == that.fofoId && Double.compare(that.secondary, secondary) == 0 && Double.compare(that.smartphoneSale, smartphoneSale) == 0 && smartphoneQty == that.smartphoneQty && Double.compare(that.insuranceSale, insuranceSale) == 0 && insruanceQty == that.insruanceQty && Objects.equals(code, that.code) && activationType == that.activationType;}@Overridepublic int hashCode() {return Objects.hash(totalSale, totalQty, past3daysSale, fofoId, code, activationType, secondary, smartphoneSale, smartphoneQty, insuranceSale, insruanceQty);}public ActivationType getActivationType() {return activationType;}public void setActivationType(ActivationType activationType) {this.activationType = activationType;}public double getSecondary() {return secondary;}public void setSecondary(double secondary) {this.secondary = secondary;}private double secondary;public int getFofoId() {return fofoId;}@Overridepublic String toString() {return "SaleTargetReportModel{" + "totalSale=" + totalSale + ", totalQty=" + totalQty + ", past3daysSale=" + past3daysSale + ", fofoId=" + fofoId + ", code='" + code + '\'' + ", secondary=" + secondary + ", smartphoneSale=" + smartphoneSale + ", smartphoneQty=" + smartphoneQty + ", insuranceSale=" + insuranceSale + ", insruanceQty=" + insruanceQty + '}';}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public void setFofoId(int fofoId) {this.fofoId = fofoId;}private double smartphoneSale;private long smartphoneQty;private double insuranceSale;private long insruanceQty;public long getTotalQty() {return totalQty;}public void setTotalQty(long totalQty) {this.totalQty = totalQty;}public double getPast3daysSale() {return past3daysSale;}public void setPast3daysSale(double past3daysSale) {this.past3daysSale = past3daysSale;}public double getTotalSale() {return totalSale;}public void setTotalSale(double totalSale) {this.totalSale = totalSale;}public double getSmartphoneSale() {return smartphoneSale;}public void setSmartphoneSale(double smartphoneSale) {this.smartphoneSale = smartphoneSale;}public long getSmartphoneQty() {return smartphoneQty;}public void setSmartphoneQty(long smartphoneQty) {this.smartphoneQty = smartphoneQty;}public double getInsuranceSale() {return insuranceSale;}public void setInsuranceSale(double insuranceSale) {this.insuranceSale = insuranceSale;}public long getInsruanceQty() {return insruanceQty;}public void setInsruanceQty(long insruanceQty) {this.insruanceQty = insruanceQty;}}private void getStateWiseSales(Map<Integer, SaleTargetReportModel> saleTargetReportModelMap, Map<Integer, FofoReportingModel> partnerSalesHeadersMap) throwsException {String timeString = "Today %s";LocalDateTime now = LocalDateTime.now();DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:m a");List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_LOGISTICS, ProfitMandiConstants.TICKET_CATEGORY_FINANCIAL_SERVICES, ProfitMandiConstants.TICKET_CATEGORY_CATEGORY, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_MARKETING, ProfitMandiConstants.TICKET_CATEGORY_ACCOUNTS, ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT, ProfitMandiConstants.TICKET_CATEGORY_TECHNOLOGY);Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {String email = storeGuyEntry.getKey();Set<Integer> fofoIds = storeGuyEntry.getValue();LOGGER.info("fofoIds {}", fofoIds);if (!fofoIds.isEmpty()) {List<FofoStore> stores = fofoStoreRepository.selectActivePartnersByRetailerIds(new ArrayList<>(fofoIds));Map<String, List<Integer>> stateMap = stores.stream().collect(groupingBy(x -> x.getCode().substring(0, 2), mapping(x -> x.getId(), Collectors.toList())));List<List<Serializable>> stateWiseSales = new ArrayList<>();for (Entry<String, List<Integer>> stateMapEntry : stateMap.entrySet()) {long totalQty = stateMapEntry.getValue().stream().collect(Collectors.summingLong(x -> saleTargetReportModelMap.get(x).getTotalQty()));double totalSale = stateMapEntry.getValue().stream().collect(Collectors.summingDouble(x -> saleTargetReportModelMap.get(x).getTotalSale()));long smartPhoneQty = stateMapEntry.getValue().stream().collect(Collectors.summingLong(x -> saleTargetReportModelMap.get(x).getSmartphoneQty()));double smartPhoneSale = stateMapEntry.getValue().stream().collect(Collectors.summingDouble(x -> saleTargetReportModelMap.get(x).getSmartphoneSale()));stateWiseSales.add(Arrays.asList(stateMapEntry.getKey(), smartPhoneQty, smartPhoneSale, totalQty, totalSale));}StringBuilder sb = new StringBuilder();sb.append("<html><body>");sb.append("<p>Statewise Sale Report:</p><br/><table style=\"border-collapse: collapse;\">");sb.append("<tbody>\n" + " <tr>" + " <th style='border:1px solid black;padding: 5px'>State</th>" + " <th style='border:1px solid black;padding: 5px'>SmartPhone Qty</th>" + " <th style='border:1px solid black;padding: 5px'>SmartPhone Value</th>" + " <th style='border:1px solid black;padding: 5px'>Total Qty</th>" + " <th style='border:1px solid black;padding: 5px'>Total Value</th>" + " </tr>");for (List<Serializable> stateSale : stateWiseSales) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(0) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(1) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(2) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(3) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + stateSale.get(4) + "</td>");sb.append("</tr>");}sb.append("</tbody></table><br><br>");sb.append("<p>Partnerwise Report:</p><br/><table style=\"border-collapse: collapse;\">");sb.append("<tbody>\n" + " <tr>\n" + " <th style='border:1px solid black;padding: 5px'>Code</th>" + " <th style='border:1px solid black;padding: 5px'>Business Name</th>" + " <th style='border:1px solid black;padding: 5px'>BDM Name</th>" + " <th style='border:1px solid black;padding: 5px'>Regional Manager</th>" + " <th style='border:1px solid black;padding: 5px'>Territory Manager</th>" + " <th style='border:1px solid black;padding: 5px'>Billed(4 days)</th>" + " <th style='border:1px solid black;padding: 5px'>Sale</th>" + " <th style='border:1px solid black;padding: 5px'>Smartphone Sale</th>" + " <th style='border:1px solid black;padding: 5px'>SmartPhone Qty</th>" + " </tr>");List<Integer> sortedSaleTargetReport = saleTargetReportModelMap.values().stream().filter(x -> fofoIds.contains(x.getFofoId())).sorted(Comparator.comparing(SaleTargetReportModel::getCode).thenComparing(SaleTargetReportModel::getSecondary)).map(SaleTargetReportModel::getFofoId).collect(Collectors.toList());String subject = String.format("Sale till %s", String.format(timeString, now.format(timeFormatter)));List<String> headers = Arrays.asList("Store Id", "Store Code", "Store Name", "Activation Type", "BDM Name", "Regional Manager", "Territory Manager", "Secondary(4 days)", "Sale", "Smartphone Value", "Smartphone Qty");List<List<?>> rows = new ArrayList<>();for (Integer fofoId : sortedSaleTargetReport) {FofoReportingModel fofoReportingModel = partnerSalesHeadersMap.get(fofoId);rows.add(Arrays.asList(fofoId, fofoReportingModel.getCode(), fofoReportingModel.getBusinessName(), saleTargetReportModelMap.get(fofoId).getActivationType(), fofoReportingModel.getBusinessManager(), fofoReportingModel.getRegionalManager(), fofoReportingModel.getTerritoryManager(), saleTargetReportModelMap.get(fofoId).getSecondary(), saleTargetReportModelMap.get(fofoId).getTotalSale(), saleTargetReportModelMap.get(fofoId).getSmartphoneSale(), saleTargetReportModelMap.get(fofoId).getSmartphoneQty()));//Now try to populate html rowsif (!saleTargetReportModelMap.get(fofoId).getActivationType().equals(ActivationType.ACTIVE)) {continue;}if (saleTargetReportModelMap.get(fofoId).getSecondary() == 0) {sb.append("<tr style='background-color:#D21F3C;color:white'>");} else {sb.append("<tr>");}sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getCode() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getBusinessName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getBusinessManager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getRegionalManager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + partnerSalesHeadersMap.get(fofoId).getTerritoryManager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getSecondary() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getTotalSale() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getSmartphoneSale() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + saleTargetReportModelMap.get(fofoId).getSmartphoneQty() + "</td>");sb.append("</tr>");}sb.append("</tr>");sb.append("</body></html>");String statewiseSaleReport = sb.toString();ByteArrayOutputStream baos = null;try {baos = FileUtil.getCSVByteStream(headers, rows);} catch (Exception e2) {e2.printStackTrace();}Attachment attachment = new Attachment("PartnerSalePerformance.csv", new ByteArrayResource(baos.toByteArray()));Utils.sendHtmlMailWithAttachments(googleMailSender, new String[]{email}, null, "Statewise " + subject, statewiseSaleReport, attachment);}}}private void sendMailOfHtmlFormat(JavaMailSender sender, String[] email, String body, String cc[], String subject) throwsMessagingException, ProfitMandiBusinessException, IOException {MimeMessage message = sender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message);helper.setSubject(subject);helper.setText(body, true);helper.setTo(email);if (cc != null) {helper.setCc(cc);}InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smart Dukaan");helper.setFrom(senderAddress);mailSender.send(message);}public void sendNotification() throws Exception {LOGGER.info("FCM sendNotification");List<PushNotifications> pushNotifications = pushNotificationRepository.selectAllPendingNotifications();if (!pushNotifications.isEmpty()) {InputStream serviceAccount = getClass().getClassLoader().getResourceAsStream("service-account.json");GoogleCredentials googleCredentials = GoogleCredentials.fromStream(serviceAccount).createScoped(FCM_SCOPED);googleCredentials.refreshIfExpired();String accessToken = googleCredentials.getAccessToken().getTokenValue();for (PushNotifications pushNotification : pushNotifications) {Device device = deviceRepository.selectById(pushNotification.getDeviceId());NotificationCampaign notificationCampaign = notificationCampaignRepository.selectById(pushNotification.getNotificationCampaignid());SimpleCampaignParams scp = gson.fromJson(notificationCampaign.getImplementationParams(), SimpleCampaignParams.class);Campaign campaign = new SimpleCampaign(scp);String result_url = campaign.getUrl() + "&user_id=" + device.getUser_id();JSONObject message = new JSONObject();message.put("token", device.getFcmId());JSONObject notification = new JSONObject();notification.put("title", campaign.getTitle());notification.put("body", campaign.getMessage());message.put("notification", notification);JSONObject data = new JSONObject();data.put("type", campaign.getType());data.put("url", result_url);data.put("time_to_live", campaign.getExpireTimestamp());data.put("image", campaign.getImageUrl());data.put("largeIcon", "large_icon");data.put("smallIcon", "small_icon");data.put("vibrate", "1");data.put("pid", String.valueOf(pushNotification.getId()));data.put("sound", "1");data.put("priority", "high");message.put("data", data);JSONObject payload = new JSONObject();payload.put("message", message);try {CloseableHttpClient client = HttpClients.createDefault();HttpPost httpPost = new HttpPost(FCM_URL);httpPost.setHeader("Authorization", "Bearer " + accessToken);httpPost.setHeader("Content-Type", "application/json");StringEntity entity = new StringEntity(payload.toString());httpPost.setEntity(entity);CloseableHttpResponse response = client.execute(httpPost);LOGGER.info("google FCM status code: {}", response.getStatusLine().getStatusCode());String responseBody = new BufferedReader(new InputStreamReader(response.getEntity().getContent())).lines().collect(Collectors.joining("\n"));if (response.getStatusLine().getStatusCode() == 200) {pushNotification.setSentTimestamp(LocalDateTime.now());} else {pushNotification.setSentTimestamp(LocalDateTime.of(1970, 1, 1, 00, 00));LOGGER.info("FCM Response message" + responseBody);response.toString();}} catch (Exception e) {e.printStackTrace();pushNotification.setSentTimestamp(LocalDateTime.of(1970, 1, 1, 00, 00));LOGGER.info("message " + "not sent " + e.getMessage());}}}}public void grouping() throws Exception {DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-yyyy hh:mm");List<PriceDropIMEI> priceDropImeis = priceDropIMEIRepository.selectByStatus(PriceDropImeiStatus.APPROVED);System.out.println(String.join("\t", Arrays.asList("IMEI", "ItemId", "Brand", "Model Name", "Model Number", "Franchise Id", "Franchise Name", "Grn On", "Price Dropped On", "Approved On", "Returned On", "Price Drop Paid", "Is Doa")));Map<Integer, CustomRetailer> retailersMap = retailerService.getFofoRetailers(false);for (PriceDropIMEI priceDropIMEI : priceDropImeis) {if (priceDropIMEI.getPartnerId() == 0)continue;HashSet<String> imeis = new HashSet<>();PriceDrop priceDrop = priceDropRepository.selectById(priceDropIMEI.getPriceDropId());imeis.add(priceDropIMEI.getImei());List<InventoryItem> inventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(priceDropIMEI.getPartnerId(), imeis, false);if (inventoryItems.size() == 0) {LOGGER.info("Need to investigate partnerId - {} imeis - {}", priceDropIMEI.getPartnerId(), imeis);continue;}InventoryItem inventoryItem = inventoryItems.get(0);CustomRetailer customRetailer = retailersMap.get(inventoryItem.getFofoId());if (inventoryItem.getLastScanType().equals(ScanType.DOA_OUT) || inventoryItem.getLastScanType().equals(ScanType.PURCHASE_RET)) {// check if pricedrop has been rolled outList<UserWalletHistory> uwh = walletService.getAllByReference(inventoryItem.getFofoId(), priceDropIMEI.getPriceDropId(), WalletReferenceType.PRICE_DROP);if (uwh.size() > 0) {Item item = itemRepository.selectById(inventoryItem.getItemId());System.out.println(String.join("\t", Arrays.asList(priceDropIMEI.getImei(), inventoryItem.getItemId() + "", item.getBrand(), item.getModelName(), item.getModelNumber(), inventoryItem.getFofoId() + "", customRetailer.getBusinessName(), inventoryItem.getCreateTimestamp().format(dtf), priceDrop.getAffectedOn().format(dtf), priceDropIMEI.getUpdateTimestamp().format(dtf), inventoryItem.getUpdateTimestamp().format(dtf), priceDrop.getAutoPartnerPayout(inventoryItem.getUpdateTimestamp()) + "", inventoryItem.getLastScanType().equals(ScanType.DOA_OUT) + "")));}}}}public void toffeeRollback() throws Exception {toffeeService.cancelPolicyCopy("110143521986");toffeeService.getOrderId("110143521986");}public void attachToffeeInvoices() throws Exception {List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectAllByProviderId(3, Optional.of(false));for (InsurancePolicy insurancePolicy : insurancePolicies) {String invoiceNumber = insurancePolicy.getInvoiceNumber();FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);InvoicePdfModel pdfModel = orderService.getInvoicePdfModel(fofoOrder.getId());java.io.ByteArrayOutputStream byteArrayOutputStream = new java.io.ByteArrayOutputStream();PdfUtils.generateAndWrite(Arrays.asList(pdfModel), byteArrayOutputStream);String pdfInvoiceString = "data:application/pdf;base64," + Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());boolean attached = toffeeService.attachInvoice(insurancePolicy.getPolicyNumber().split("#")[1], pdfInvoiceString);if (attached) {insurancePolicy.setPosted(true);}}}public void sendBAGPendingPolicies() throws Exception {List<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectAllByProviderId(4, Optional.of(false));for (InsurancePolicy insurancePolicy : insurancePolicies) {String invoiceNumber = insurancePolicy.getInvoiceNumber();FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId()).get(0);CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());BAGInsuranceModel bagInsuranceModel = new BAGInsuranceModel();// bagInsuranceModel.setModelId();bagInsuranceModel.setAddressLine1(customerAddress.getLine1());bagInsuranceModel.setAddressLine2(customerAddress.getLine2());bagInsuranceModel.setCity(customerAddress.getCity());bagInsuranceModel.setBrandWarranty("1 Year");Item item = itemRepository.selectById(fofoOrderItem.getId());bagInsuranceModel.setModelName(item.getItemDescription());bagInsuranceModel.setDateOfPurchase(fofoOrder.getFormattedDate());bagInsuranceModel.setEmail(customer.getEmailId());bagInsuranceModel.setImei1(insurancePolicy.getSerialNumber());bagInsuranceModel.setFirstName(customer.getFirstName());bagInsuranceModel.setLastName(customer.getLastName());bagInsuranceModel.setMobileNumber(customer.getMobileNumber());bagInsuranceModel.setPlanId("");insurancePolicy.setPosted(true);}}public void schemeRollback(List<String> schemeIds) throws Exception {List<Integer> schemeIdsInt = schemeIds.stream().map(x -> Integer.parseInt(x)).collect(Collectors.toList());Map<Integer, Scheme> schemesMap = schemeRepository.selectBySchemeIds(schemeIdsInt, 0, schemeIds.size()).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectBySchemeIds(new HashSet<>(schemeIdsInt));for (SchemeInOut sio : schemeInOuts) {Scheme scheme = schemesMap.get(sio.getSchemeId());if (scheme.getType().getTransactionType().equals(StockTransactionType.IN)) {} else if (scheme.getType().getTransactionType().equals(StockTransactionType.OUT)) {InventoryItem inventoryItem = inventoryItemRepository.selectById(sio.getInventoryItemId());List<ScanRecord> sr = scanRecordRepository.selectByInventoryItemId(sio.getInventoryItemId());ScanRecord scanRecord = sr.stream().filter(x -> x.getType().equals(ScanType.SALE)).max((x1, x2) -> x1.getCreateTimestamp().compareTo(x2.getCreateTimestamp())).get();if (scanRecord.getCreateTimestamp().isAfter(scheme.getEndDateTime()) || scanRecord.getCreateTimestamp().isBefore(scheme.getStartDateTime())) {sio.setRolledBackTimestamp(LocalDateTime.now());FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(scanRecord.getOrderId());String rollbackReason = "Scheme reversed for " + itemRepository.selectById(inventoryItem.getItemId()).getItemDescription() + "/Inv - " + fofoOrder.getInvoiceNumber();walletService.rollbackAmountFromWallet(scanRecord.getFofoId(), sio.getAmount(), scanRecord.getOrderId(), WalletReferenceType.SCHEME_OUT, rollbackReason, LocalDateTime.now());System.out.printf("Amount %f,SchemeId %d,Reason %s\n", sio.getAmount(), sio.getSchemeId(), rollbackReason);}}}// throw new Exception();}public void checkfocusedModelInPartnerStock() throws Exception {// ========== PHASE 1: Batch fetch all data upfront ==========Map<Integer, FofoStore> fofoStoreMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(FofoStore::getId, x -> x));List<Integer> allPartnerIds = new ArrayList<>(fofoStoreMap.keySet());Map<Integer, Map<Integer, List<SaholicCIS>>> warehouseItemAvailabilityMap = saholicInventoryService.getSaholicStock();Map<Integer, String> warehouseMap = ProfitMandiConstants.WAREHOUSE_MAP;Map<Integer, FofoReportingModel> partnerIdSalesHeadersMap = this.getPartnerIdSalesHeaders();Map<Integer, List<FocusedModel>> regionFocusedModelsMap = focusedModelRepository.selectAll().stream().collect(Collectors.groupingBy(FocusedModel::getRegionId));LOGGER.info("regionFocusedModelsMap - {}", regionFocusedModelsMap);Map<Integer, Map<Integer, List<SaholicPOItem>>> warehousePoItemAvailabilityMap = saholicInventoryService.getSaholicPOItems();// Batch fetch all customRetailers upfrontMap<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(allPartnerIds);LOGGER.info("Fetched {} customRetailers", customRetailerMap.size());// Batch fetch all inventory snapshots upfrontMap<Integer, List<CurrentInventorySnapshot>> allInventorySnapshotsMap = currentInventorySnapshotRepository.selectByFofoId(allPartnerIds).stream().collect(Collectors.groupingBy(CurrentInventorySnapshot::getFofoId));LOGGER.info("Fetched inventory snapshots for {} partners", allInventorySnapshotsMap.size());// Batch fetch all pending GRN orders upfrontMap<Integer, List<Order>> allGrnPendingOrdersMap = orderRepository.selectPendingGrnOrders(allPartnerIds).stream().collect(Collectors.groupingBy(Order::getRetailerId));LOGGER.info("Fetched GRN pending orders for {} partners", allGrnPendingOrdersMap.size());// Batch fetch all processing orders upfrontMap<Integer, List<Order>> allProcessingOrdersMap = orderRepository.selectOrders(allPartnerIds, orderStatusList).stream().collect(Collectors.groupingBy(Order::getRetailerId));LOGGER.info("Fetched processing orders for {} partners", allProcessingOrdersMap.size());// Collect all focused catalog IDsSet<Integer> allFocusedCatalogIds = regionFocusedModelsMap.values().stream().flatMap(List::stream).map(FocusedModel::getCatalogId).collect(Collectors.toSet());// Batch fetch all items by catalog IDs upfrontList<Item> allItemsByCatalogId = itemRepository.selectAllByCatalogIds(allFocusedCatalogIds);Map<Integer, List<Item>> itemsByCatalogIdMap = allItemsByCatalogId.stream().collect(Collectors.groupingBy(Item::getCatalogItemId));LOGGER.info("Fetched items for {} catalog IDs", itemsByCatalogIdMap.size());// Batch fetch all tagListings using pre-fetched items to avoid duplicate item fetchMap<Integer, TagListing> tagListingByCatalogIdMap = tagListingRepository.selectAllByItems(allItemsByCatalogId);LOGGER.info("Fetched {} tagListings", tagListingByCatalogIdMap.size());// Collect all item IDs from inventory, GRN orders, and processing orders for batch item lookupSet<Integer> allItemIds = new HashSet<>();allInventorySnapshotsMap.values().forEach(list ->list.forEach(cis -> allItemIds.add(cis.getItemId())));allGrnPendingOrdersMap.values().forEach(orders ->orders.forEach(o -> allItemIds.add(o.getLineItem().getItemId())));allProcessingOrdersMap.values().forEach(orders ->orders.forEach(o -> allItemIds.add(o.getLineItem().getItemId())));// Batch fetch all items and create itemId -> catalogId mappingMap<Integer, Integer> itemIdToCatalogIdMap = new HashMap<>();if (!allItemIds.isEmpty()) {itemRepository.selectByIds(allItemIds).forEach(item ->itemIdToCatalogIdMap.put(item.getId(), item.getCatalogItemId()));}LOGGER.info("Built itemId->catalogId mapping for {} items", itemIdToCatalogIdMap.size());// ========== PHASE 2: Build partner region mappings ==========Map<Integer, Set<Integer>> partnerToRegions = partnerRegionRepository.selectAll().stream().collect(Collectors.groupingBy(pr -> pr.getFofoId(),Collectors.mapping(pr -> pr.getRegionId(), Collectors.toSet())));Map<Set<Integer>, List<Integer>> regionPartnerMap = partnerToRegions.entrySet().stream().collect(Collectors.groupingBy(Map.Entry::getValue,Collectors.mapping(Map.Entry::getKey, Collectors.toList())));LOGGER.info("regionPartnerMap - {}", regionPartnerMap.keySet());// ========== PHASE 3: Process partners using pre-fetched data ==========Map<Integer, List<FocusedModelShortageModel>> focusedModelShortageReportMap = new HashMap<>();for (Map.Entry<Set<Integer>, List<Integer>> regionPartnerEntry : regionPartnerMap.entrySet()) {Set<Integer> regionIds = regionPartnerEntry.getKey();List<Integer> partnerIds = new ArrayList<>(regionPartnerEntry.getValue());if (regionIds.stream().anyMatch(x -> !regionFocusedModelsMap.containsKey(x))) continue;LOGGER.info("Processing regionIds: {}", regionIds);if (regionIds == null || regionIds.isEmpty()) {LOGGER.info("No region found for partner {}", partnerIds);continue;}if (regionIds.contains(5)) {partnerIds.addAll(fofoStoreMap.keySet());}Map<Integer, Optional<Integer>> focusedCatalogIdAndQtyMap = regionIds.stream().map(regionFocusedModelsMap::get).flatMap(x -> x != null ? x.stream() : Stream.empty()).collect(groupingBy(FocusedModel::getCatalogId,mapping(FocusedModel::getObsMinimumQty, Collectors.maxBy(Integer::compareTo))));if (focusedCatalogIdAndQtyMap.isEmpty()) continue;for (int partnerId : partnerIds) {if (partnerId == 0) continue;FofoStore fofoStore = fofoStoreMap.get(partnerId);if (fofoStore == null) continue;CustomRetailer customRetailer = customRetailerMap.get(partnerId);if (customRetailer == null) continue;List<FocusedModelShortageModel> focusedModelShortageList = new ArrayList<>();focusedModelShortageReportMap.put(fofoStore.getId(), focusedModelShortageList);// Build catalogIdAndQtyMap from pre-fetched inventory snapshotsMap<Integer, Integer> catalogIdAndQtyMap = new HashMap<>();List<CurrentInventorySnapshot> inventorySnapshots = allInventorySnapshotsMap.get(partnerId);if (inventorySnapshots != null) {Map<Integer, Integer> itemQtyMap = inventorySnapshots.stream().collect(Collectors.toMap(CurrentInventorySnapshot::getItemId, CurrentInventorySnapshot::getAvailability));for (Map.Entry<Integer, Integer> e : itemQtyMap.entrySet()) {Integer catalogId = itemIdToCatalogIdMap.get(e.getKey());if (catalogId != null) {catalogIdAndQtyMap.merge(catalogId, e.getValue(), Integer::sum);}}}// Build grnPendingOrdersMap from pre-fetched ordersMap<Integer, Integer> grnPendingOrdersMap = new HashMap<>();List<Order> grnOrders = allGrnPendingOrdersMap.get(partnerId);if (grnOrders != null) {for (Order order : grnOrders) {Integer catalogId = itemIdToCatalogIdMap.get(order.getLineItem().getItemId());if (catalogId != null) {grnPendingOrdersMap.merge(catalogId, order.getLineItem().getQuantity(), Integer::sum);}}}// Build processingOrderMap from pre-fetched ordersMap<Integer, Integer> processingOrderMap = new HashMap<>();List<Order> processingOrders = allProcessingOrdersMap.get(partnerId);if (processingOrders != null) {for (Order order : processingOrders) {Integer catalogId = itemIdToCatalogIdMap.get(order.getLineItem().getItemId());if (catalogId != null) {processingOrderMap.merge(catalogId, order.getLineItem().getQuantity(), Integer::sum);}}}Map<Integer, List<SaholicCIS>> itemAvailabilityMap = warehouseItemAvailabilityMap.get(fofoStore.getWarehouseId());Map<Integer, List<SaholicPOItem>> poItemAvailabilityMap = warehousePoItemAvailabilityMap.get(fofoStore.getWarehouseId());for (Entry<Integer, Optional<Integer>> entry : focusedCatalogIdAndQtyMap.entrySet()) {int catalogId = entry.getKey();int minQty = entry.getValue().orElse(0);int inStockQty = catalogIdAndQtyMap.getOrDefault(catalogId, 0);int processingQty = processingOrderMap.getOrDefault(catalogId, 0);int grnPendingQty = grnPendingOrdersMap.getOrDefault(catalogId, 0);int grnStockQty = grnPendingQty + inStockQty;int totalQty = processingQty + grnPendingQty + inStockQty;int shortageQty = minQty - totalQty;// Use pre-fetched itemsList<Item> items = itemsByCatalogIdMap.get(catalogId);if (items == null || items.isEmpty()) continue;// Use pre-fetched tagListingTagListing tagListing = tagListingByCatalogIdMap.get(catalogId);if (tagListing == null) continue;int allColorNetAvailability = 0;int allColorPoAvailability = 0;for (Item item : items) {if (itemAvailabilityMap != null) {List<SaholicCIS> currentAvailability = itemAvailabilityMap.get(item.getId());if (currentAvailability != null) {allColorNetAvailability += currentAvailability.stream().mapToInt(SaholicCIS::getNetavailability).sum();}}if (poItemAvailabilityMap != null) {List<SaholicPOItem> poItemAvailability = poItemAvailabilityMap.get(item.getId());if (poItemAvailability != null) {allColorPoAvailability += poItemAvailability.stream().mapToInt(SaholicPOItem::getUnfulfilledQty).sum();}}}FocusedModelShortageModel fm = new FocusedModelShortageModel();fm.setFofoId(fofoStore.getId());fm.setStoreCode(fofoStore.getCode());fm.setStoreName(customRetailer.getBusinessName());fm.setBrandName(items.get(0).getBrand());fm.setModelName(items.get(0).getModelName());fm.setModelNumber(items.get(0).getModelNumber());fm.setGrnStockQty(grnStockQty);fm.setPendingIndentQty(processingQty);fm.setShortageQty(shortageQty);fm.setPoAvailability(allColorPoAvailability);fm.setDp(tagListing.getSellingPrice());fm.setWarehouseName(warehouseMap.get(customRetailer.getWarehouseId()));// FIX: Use fofoStore.getId() instead of fofoStore object as keyFofoReportingModel reportingModel = partnerIdSalesHeadersMap.get(fofoStore.getId());if (reportingModel != null) {fm.setStateManager(reportingModel.getRegionalManager());fm.setTerritoryManager(reportingModel.getTerritoryManager());} else {fm.setStateManager("");fm.setTerritoryManager("");}fm.setItemName(items.get(0).getBrand() + items.get(0).getModelNumber() + items.get(0).getModelName());fm.setAvailability(allColorNetAvailability);focusedModelShortageList.add(fm);}}}// ========== PHASE 4: Send emails ==========LOGGER.info("focusedModelShortageReportMap size: {}", focusedModelShortageReportMap.size());if (!focusedModelShortageReportMap.isEmpty()) {String fileName = "Stock Alert-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();Map<String, List<List<?>>> emailRowsMap = new HashMap<>();for (Map.Entry<Integer, List<FocusedModelShortageModel>> x : focusedModelShortageReportMap.entrySet()) {for (Map.Entry<String, Set<Integer>> y : storeGuyMap.entrySet()) {if (y.getValue().contains(x.getKey())) {emailRowsMap.computeIfAbsent(y.getKey(), k -> new ArrayList<>());List<List<? extends Serializable>> fms = x.getValue().stream().map(r -> Arrays.asList(r.getStoreCode(), r.getStoreName(), r.getBrandName(),r.getModelName(), r.getModelNumber(), r.getDp(), r.getWarehouseName(),r.getStateManager(), r.getTerritoryManager(), r.getPendingIndentQty(),r.getGrnStockQty(), r.getShortageQty(), r.getAvailability())).collect(Collectors.toList());emailRowsMap.get(y.getKey()).addAll(fms);}}}List<String> headers = Arrays.asList("Store Code", "Store Name", "Brand", "Model Name", "Model Number","DP", "Warehouse Name", "State Manager", "Territory Manager", "Pending Indent", "InStock","Shortage Qty", "Availability");for (Map.Entry<String, List<List<?>>> entry : emailRowsMap.entrySet()) {try {ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, entry.getValue());String[] sendToArray = new String[]{entry.getKey()};Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Stock Alert", "PFA",fileName, new ByteArrayResource(baos.toByteArray()));} catch (Exception e) {LOGGER.error("Failed to send email to {}", entry.getKey(), e);}}}}private String getNotificationMessage(List<FocusedModelShortageModel> focusedModelShortageModel) {StringBuilder sb = new StringBuilder();sb.append("Focused Model Shortage in Your Stock : \n");for (FocusedModelShortageModel entry : focusedModelShortageModel) {sb.append(entry.getItemName() + "-" + entry.getShortageQty());sb.append(String.format("%n", ""));}return sb.toString();}private void sendMailWithAttachments(String subject, String messageText, String email) throws Exception {MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);helper.setSubject(subject);helper.setText(messageText, true);helper.setTo(email);InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");helper.setFrom(senderAddress);mailSender.send(message);}private String getMessage(List<FocusedModelShortageModel> focusedModelShortageModel) {StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Focused Model Shortage in Your Stock:-</p>" + "<br/><table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" + " <tr>\n" + " <th style='border:1px solid black;padding: 5px'>Item</th>\n" + " <th style='border:1px solid black;padding: 5px'>Shortage Qty</th>\n" + " </tr>");for (FocusedModelShortageModel entry : focusedModelShortageModel) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getItemName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getShortageQty() + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}public void notifyLead() throws Exception {List<Lead> leadsToNotify = leadRepository.selectLeadsScheduledBetweenDate(null, LocalDateTime.now().minusDays(15), LocalDateTime.now().plusHours(4));Map<Integer, String> authUserEmailMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getEmailId()));LOGGER.info("authUserEmailMap {}", authUserEmailMap);Map<String, Integer> dtrEmailMap = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.values())).stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x.getId()));LOGGER.info("dtrEmailMap {}", dtrEmailMap);Map<Integer, Integer> authUserKeyMap = new HashMap<>();for (Entry<Integer, String> authUserEmail : authUserEmailMap.entrySet()) {int authId = authUserEmail.getKey();String email = authUserEmail.getValue();authUserKeyMap.put(authId, dtrEmailMap.get(email));}LOGGER.info("authUserKeyMap", authUserKeyMap);LOGGER.info("leadsToNotify {}", leadsToNotify);String templateMessage = "Lead followup for %s %s, %s, %s is due by %s";for (Lead lead : leadsToNotify) {if (authUserKeyMap.get(lead.getAssignTo()) == null) {LOGGER.info("Assignee no longer part of system {}", lead.getAssignTo());continue;}String title = "Leads followup Reminder";String notificationMessage = String.format(templateMessage, lead.getFirstName(), lead.getLastName(), lead.getAddress(), lead.getLeadMobile(), leadTimeFormatter.format(lead.getScheduledTimestamp()));String url = "https://app.smartdukaan.com/pages/home/leadUpdate?leadId=" + lead.getId();SendNotificationModel sendNotificationModel = new SendNotificationModel();sendNotificationModel.setCampaignName("Lead Reminder");sendNotificationModel.setTitle(title);sendNotificationModel.setMessage(notificationMessage);sendNotificationModel.setType("url");sendNotificationModel.setUrl(url);sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(2));sendNotificationModel.setMessageType(MessageType.reminder);sendNotificationModel.setUserIds(Arrays.asList(authUserKeyMap.get(lead.getAssignTo())));System.out.println(sendNotificationModel);notificationService.sendNotification(sendNotificationModel);}}@AutowiredAuthService authService;public void sendUnscheduledFollowUpMail() throws Exception {List<Lead> missedScheduleLeads = leadRepository.selectLeadsScheduledBetweenDate(null, LocalDate.now().atStartOfDay().minusDays(30), LocalDateTime.now().toLocalDate().atStartOfDay());List<Lead> leadsScheduledForToday = leadRepository.selectLeadsScheduledBetweenDate(null, LocalDate.now().atStartOfDay(), LocalDate.now().atTime(LocalTime.MAX));List<Integer> authIds = missedScheduleLeads.stream().map(x -> x.getAssignTo()).distinct().collect(Collectors.toList());LOGGER.info(authIds.size());Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));LOGGER.info(authUserMap.size());//if(true) return;missedScheduleLeads = missedScheduleLeads.stream().sorted(Comparator.comparing(Lead::getState, String.CASE_INSENSITIVE_ORDER).thenComparing(Lead::getAssignTo).thenComparing(Lead::getScheduledTimestamp)).collect(Collectors.toList());//leadsScheduledForTodayList<AuthUser> authUsers = authRepository.selectAllActiveUser();LOGGER.info("Auth Users Size - {}", authUsers.size());for (AuthUser authUser : authUsers) {LOGGER.info("Auth Name - {}", authUser.getFullName());List<Integer> reporteeAuthIds = authService.getAllReportees(authUser.getId());reporteeAuthIds.add(authUser.getId());StringBuilder sb = new StringBuilder();sb.append("<html><body>");List<Lead> authMissedScheduledLeads = missedScheduleLeads.stream().filter(x -> reporteeAuthIds.contains(x.getAssignTo())).collect(Collectors.toList());LOGGER.info("authMissedScheduledLeads {}", authMissedScheduledLeads.size());if (authMissedScheduledLeads.size() > 0) {addMissedScheduledLeadsTable(sb, authMissedScheduledLeads, authUserMap);sb.append("</body></html>");String subject = "Lead Updates Summary";String[] email = Arrays.asList(authUser.getEmailId()).toArray(new String[1]);//String[] email = Arrays.asList("amit.gupta@smartdukaan.com").toArray(new String[1]);this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);//break;}}}private void addMissedScheduledLeadsTable(StringBuildersb, List<Lead> missedScheduleLeads, Map<Integer, AuthUser> authUserMap) {sb.append("<h3>Leads That Missed the schedule</h3>");sb.append("<table style='border:1px solid black' cellspacing='0'>").append("<tr>").append("<th style='border:1px solid black;padding: 5px'>").append("Lead Id").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("Lead Name").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("Mobile No").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("City").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("State").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("Created On").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("Assigned To").append("</th>").append("<th style='border:1px solid black;padding: 5px'>").append("Scheduled On").append("</th>").append("</tr>");for (Lead lead : missedScheduleLeads) {sb.append("<tr style='background-color:").append(lead.getColor()).append("'>").append("<td style='border:1px solid black;padding: 5px'>").append(lead.getId()).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(lead.getFullName()).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(lead.getLeadMobile()).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(lead.getCity()).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(lead.getState()).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(FormattingUtils.formatDate(lead.getCreatedTimestamp())).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(authUserMap.containsKey(lead.getAssignTo()) ? authUserMap.get(lead.getAssignTo()).getFullName() : lead.getAssignTo()).append("</td>").append("<td style='border:1px solid black;padding: 5px'>").append(FormattingUtils.formatDate(lead.getScheduledTimestamp())).append("</td>").append("</tr>");}sb.append("</table>");}public void notifyVisits() throws Exception {List<FranchiseeVisit> franchiseeVisits = franchiseeVisitRepository.selectVisitsScheduledBetweenDate(LocalDateTime.now().minusDays(15), LocalDateTime.now().plusHours(4));Map<Integer, String> authUserEmailMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getEmailId()));Map<String, Integer> dtrEmailMap = dtrUserRepository.selectAllByEmailIds(new ArrayList<>(authUserEmailMap.values())).stream().collect(Collectors.toMap(x -> x.getEmailId(), x -> x.getId()));Map<Integer, Integer> authUserKeyMap = new HashMap<>();for (Entry<Integer, String> authUserEmail : authUserEmailMap.entrySet()) {int authId = authUserEmail.getKey();String email = authUserEmail.getValue();authUserKeyMap.put(authId, dtrEmailMap.get(email));}String visitTemplate = "Planned visit to franchisee %s is due by %s";String followupTemplate = "Lead followup for franchisee %s is due by %s";DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("MMM 7, EEEE h:m a");for (FranchiseeVisit visit : franchiseeVisits) {if (authUserKeyMap.containsKey(visit.getAuthId())) {continue;}SendNotificationModel sendNotificationModel = new SendNotificationModel();String message = null;if (visit.getFranchiseActivityId() == 0) {message = String.format(visitTemplate, visit.getPartnerName(), timeFormatter.format(visit.getScheduleTimestamp()));sendNotificationModel.setCampaignName("Franchisee visit Reminder");} else {message = String.format(followupTemplate, visit.getPartnerName(), timeFormatter.format(visit.getScheduleTimestamp()));sendNotificationModel.setCampaignName("Franchisee followup Reminder");}sendNotificationModel.setMessage(message);sendNotificationModel.setType("url");sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(2));sendNotificationModel.setMessageType(MessageType.reminder);sendNotificationModel.setUserIds(Arrays.asList(authUserKeyMap.get(visit.getAuthId())));// notificationService.sendNotification(sendNotificationModel);}}public void ticketClosed() throws Exception {List<Ticket> tickets = ticketRepository.selectAllNotClosedTicketsWithStatus(ActivityType.RESOLVED);for (Ticket ticket : tickets) {if (ticket.getUpdateTimestamp().toLocalDate().isBefore(LocalDate.now().minusDays(7))) {ticket.setCloseTimestamp(LocalDateTime.now());ticket.setLastActivity(ActivityType.RESOLVED_ACCEPTED);ticket.setUpdateTimestamp(LocalDateTime.now());ticketRepository.persist(ticket);}}}public void checkValidateReferral() throws Exception {List<Refferal> referrals = refferalRepository.selectByStatus(RefferalStatus.pending);LOGGER.info("referrals" + referrals);if (!referrals.isEmpty()) {String subject = "Referral Request";String messageText = this.getMessageForReferral(referrals);MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);String[] email = {"kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com"};helper.setSubject(subject);helper.setText(messageText, true);helper.setTo(email);InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");helper.setFrom(senderAddress);mailSender.send(message);}}private String getMessageForReferral(List<Refferal> referrals) {StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Pending Referrals:-</p>" + "<br/><table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" + " <tr>\n" + " <th style='border:1px solid black;padding: 5px'>RefereeName</th>\n" + " <th style='border:1px solid black;padding: 5px'>Referee Email</th>\n" + " <th style='border:1px solid black;padding: 5px'>Referral Name</th>\n" + " <th style='border:1px solid black;padding: 5px'>Refferal Mobile</th>\n" + " <th style='border:1px solid black;padding: 5px'>city</th>\n" + " <th style='border:1px solid black;padding: 5px'>state</th>\n" + " </tr>");for (Refferal entry : referrals) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getRefereeName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getRefereeEmail() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getFirstName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getMobile() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCity() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getState() + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}private String getMessageForRBMEscalatedPartners(List<PartnerCollectionRemark> pcrs) throwsProfitMandiBusinessException {StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Escalated by RBM-L1:-</p>" + "<br/><table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>" +"<tr>" +"<th style='border:1px solid black;padding: 5px'>PartnerName</th>" +"<th style='border:1px solid black;padding: 5px'>Escalated Since</th>" +"<th style='border:1px solid black;padding: 5px'>Message</th>" +"</tr>");for (PartnerCollectionRemark entry : pcrs) {CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCreateTimestamp().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getMessage() + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}private String getMessageForSalesEscalatedPartners(List<PartnerCollectionRemark> pcrs) throwsProfitMandiBusinessException {StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Escalated to Sales Team:-</p>" + "<br/>" +"<table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>" +"<tr>" +"<th style='border:1px solid black;padding: 5px'>PartnerName</th>" +"<th style='border:1px solid black;padding: 5px'>Escalated Since</th>" +"<th style='border:1px solid black;padding: 5px'>Message</th>" +"</tr>");for (PartnerCollectionRemark entry : pcrs) {CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCreateTimestamp().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getMessage() + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}private String getMessageForUnauthorizedBuying(List<NonSdBuying> nsb) throwsProfitMandiBusinessException {StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Unauthorized Buying-</p>" + "<br/>" +"<table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>" +"<tr>" +"<th style='border:1px solid black;padding: 5px'>PartnerName</th>" +"<th style='border:1px solid black;padding: 5px'>Brand Name</th>" +"<th style='border:1px solid black;padding: 5px'>Brand Value</th>" +"<th style='border:1px solid black;padding: 5px'>Created At</th>" +"<th style='border:1px solid black;padding: 5px'>Reason</th>" +"</tr>");for (NonSdBuying entry : nsb) {CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());List<Integer> brandIds = Collections.singletonList(entry.getBrandId());BrandCatalog brandsDisplay = brandsRepository.selectByIds(brandIds).get(0);sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + brandsDisplay.getName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getBrandValue() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getCreateTimestamp().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getReason() + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}public void reverseWallet() throws Exception {LocalDate localDate = LocalDate.of(2020, 10, 28);List<UserWalletHistory> uwhList = userWalletHistoryRepository.selectAllByDateType(localDate.atStartOfDay(), localDate.plusDays(1).atStartOfDay(), Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT));for (UserWalletHistory uwh : uwhList) {if (uwh.getBusinessTimestamp().getMonth().equals(Month.SEPTEMBER)) {UserWallet uw = userWalletRepository.selectById(uwh.getWalletId());// LOGGER.info("UWH - {}", uwh);// amount += uwh.getAmount();// System.out.println("Amount is - " + amount);// walletService.rollbackAmountFromWallet(uw.getUserId(), uwh.getAmount(),// uwh.getReference(), uwh.getReferenceType(), "Margin reversal for error prone// run", uwh.getBusinessTimestamp());int orderId = uwh.getReference();FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);int inventoryItemId = 0;// fofoOrderRepository.delete(fofoOrder);List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());/** List<PaymentOptionTransaction> paymentOptionTransactions =* paymentOptionTransactionRepository.selectByReferenceIdAndType(fofoOrder.getId* (), PaymentOptionReferenceType.ORDER); for(PaymentOptionTransaction* paymentOptionTransaction : paymentOptionTransactions) {* //paymentOptionTransactionRepository.delete(paymentOptionTransaction); }*/for (FofoOrderItem foi : fofoOrderItems) {// fofoOrderItemRepository.delete(foi);List<FofoLineItem> flis = fofoLineItemRepository.selectByFofoOrderItemId(foi.getId());for (FofoLineItem fli : flis) {// fofoLineItemRepository.delete(fli);inventoryItemId = fli.getInventoryItemId();}}List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(Stream.of(inventoryItemId).collect(Collectors.toSet()));for (SchemeInOut sio : schemeInOuts) {if (sio.getCreateTimestamp().toLocalDate().equals(localDate)) {LOGGER.info("SIO - {}", sio);sio.setRolledBackTimestamp(LocalDateTime.now());}}}}}public void partnerProblemAlert() throws Exception {LocalDateTime curDate = LocalDate.now().atStartOfDay();Map<Integer, Double> lmtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1), 0, false);Map<Integer, Double> mtdSales = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX), 0, false);Map<Integer, PartnerDailyInvestment> pdi = partnerDailyInvestmentRepository.selectAll(LocalDate.now()).stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));for (Entry<Integer, Double> ls : lmtdSale.entrySet()) {double lmtdTwentyPercentSale = ls.getValue() * 0.2;LOGGER.info("lmtdTwentyPercentSale" + lmtdTwentyPercentSale);double mtdSale = mtdSales.get(ls.getKey()) == null ? 0 : mtdSales.get(ls.getKey());LOGGER.info("mtdSale" + mtdSale);double totalSixtyPercentInvestment = pdi.get(ls.getKey()) == null ? 0 : pdi.get(ls.getKey()).getTotalInvestment() * 0.6;LOGGER.info("totalSixtyPercentInvestment" + totalSixtyPercentInvestment);double stockInvestment = pdi.get(ls.getKey()) == null ? 0 : pdi.get(ls.getKey()).getInStockAmount();LOGGER.info("stockInvestment" + stockInvestment);boolean Investmentvalue = partnerInvestmentService.isInvestmentBelow(ls.getKey(), 25);PartnerProblem partnerProblem = partnerProblemRepository.selectByFofoId(ls.getKey());if (partnerProblem == null) {partnerProblem = new PartnerProblem();partnerProblem.setFofoId(ls.getKey());if (mtdSale < lmtdTwentyPercentSale) {partnerProblem.setMtd(1);}if (Investmentvalue) {partnerProblem.setInvestment(1);}if (stockInvestment < totalSixtyPercentInvestment) {partnerProblem.setInvestment(1);}partnerProblemRepository.persist(partnerProblem);} else {if (mtdSale < lmtdTwentyPercentSale) {partnerProblem.setMtd(partnerProblem.getMtd() + 1);} else {partnerProblem.setMtd(0);}if (Investmentvalue) {partnerProblem.setInvestment(partnerProblem.getInvestment() + 1);} else {partnerProblem.setInvestment(0);}if (stockInvestment < totalSixtyPercentInvestment) {partnerProblem.setStockInvestment(partnerProblem.getStockInvestment() + 1);} else {partnerProblem.setStockInvestment(0);}}}List<PartnerProblem> partnerProblems = partnerProblemRepository.selectAll().stream().filter(x -> x.getMtd() + x.getInvestment() + x.getStockInvestment() > 0).collect(Collectors.toList());partnerProblems = partnerProblems.stream().sorted((x1, x2) -> {return x1.getMtd() + x1.getInvestment() + x1.getStockInvestment() < x2.getMtd() + x2.getInvestment() + x2.getStockInvestment() ? 1 : -1;}).collect(Collectors.toList());Map<Integer, PartnerProblem> partnerProblemMap = partnerProblems.stream().sorted((x1, x2) -> {return x1.getMtd() + x1.getInvestment() + x1.getStockInvestment() < x2.getMtd() + x2.getInvestment() + x2.getStockInvestment() ? 1 : -1;}).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailers();List<Integer> assignTo = Arrays.asList(15, 9, 54, 53);Map<Integer, AuthUser> assignAuthUserMap = authRepository.selectByIds(assignTo).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));List<String> sendTo = Arrays.asList("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com", "sm@smartdukaan.com");LOGGER.info("partnerProblem" + partnerProblems);StringBuilder sb = new StringBuilder();sb.append("<htl><body>");sb.append("<p>Number against MTD or Investment are the count of days the MTD is low VS LMTD OR Investment is below 75%.</p><br/><p>These partners needs immediate attention.</p><br/><table style='border:1px solid black';cellspacing=0>");sb.append("<tbody>\n" + " <tr>" + " <th style='border:1px solid black;padding: 5px'>Partner Name</th>" + " <th style='border:1px solid black;padding: 5px'>Assign TO</th>" + " <th style='border:1px solid black;padding: 5px'>Mtd</th>" + " <th style='border:1px solid black;padding: 5px'>Investment</th>" + " <th style='border:1px solid black;padding: 5px'>Stock</th>" + " <th style='border:1px solid black;padding: 5px'>Manager</th>"+ " </tr>");for (PartnerProblem pp : partnerProblems) {int value = pp.getFofoId() % 4;Map<EscalationType, AuthUser> authUserMap = csService.getAuthUserAndEsclationByPartnerId(pp.getFofoId());LOGGER.info("authUserMap" + authUserMap);sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailers.get(pp.getFofoId()).getBusinessName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + assignAuthUserMap.get(assignTo.get(value)).getName() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + pp.getMtd() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + pp.getInvestment() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + pp.getStockInvestment() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + (authUserMap.get(EscalationType.L1) == null ? "N/A" : authUserMap.get(EscalationType.L1).getFirstName()) + " ," + (authUserMap.get(EscalationType.L2) == null ? "N/A" : authUserMap.get(EscalationType.L2).getFirstName()) + "</td>");sb.append("</tr>");}sb.append("</tbody></table><br><br>");String subject = "Partner Problem Alert!";String[] email = sendTo.toArray(new String[sendTo.size()]);this.sendMailOfHtmlFormat(googleMailSender, email, sb.toString(), null, subject);Map<Integer, List<Integer>> authUserPartnerMapping = csService.getAuthUserIdPartnerIdMapping();for (Entry<Integer, List<Integer>> authUserPartner : authUserPartnerMapping.entrySet()) {AuthUser authUser = authRepository.selectById(authUserPartner.getKey());for (Integer patnerId : authUserPartner.getValue()) {if (partnerProblemMap.get(patnerId) != null) {StringBuilder sbbuilder = new StringBuilder();sbbuilder.append("<hml><body>");sb.append("<p>Number against MTD or Investment are the count of days the MTD is low VS LMTD OR Investment is below 75%.</p><br/><p>These partners needs immediate attention.</p><br/><table style='border:1px solid black';cellspacing=0>");sbbuilder.append("<tbody>\n" + " <tr>" + " <th style='border:1px solid black;padding: 5px'>Partner Name</th>" + " <th style='border:1px solid black;padding: 5px'>Mtd</th>" + " <th style='border:1px solid black;padding: 5px'>Investment</th>" + " <th style='border:1px solid black;padding: 5px'>Stock</th>"+ " </tr>");for (Integer partnerId : authUserPartner.getValue()) {if (partnerProblemMap.get(partnerId) != null) {PartnerProblem pp = partnerProblemMap.get(partnerId);sbbuilder.append("<tr>");sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + customRetailers.get(pp.getFofoId()).getBusinessName() + "</td>");sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + pp.getMtd() + "</td>");sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + pp.getInvestment() + "</td>");sbbuilder.append("<td style='border:1px solid black;padding: 5px'>" + pp.getStockInvestment() + "</td>");sbbuilder.append("</tr>");}}sbbuilder.append("</tbody></table><br><br>");this.sendMailOfHtmlFormat(googleMailSender, new String[]{authUser.getEmailId()}, sbbuilder.toString(), null, subject);}}}}@AutowiredWarehouseRepository warehouseRepository;public void getVendorWarehouses(int warehouseId) throws ProfitMandiBusinessException {LOGGER.info("Warehouses - {}", warehouseRepository.getVendorWarehouses().get(warehouseId));}public void checkImeiActivation() {try {vivoImeiActivationService.checkImeiActivation();} catch (ProfitMandiBusinessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void checkItelImeiActivation(LocalDate date, Integer day) {LOGGER.info("Hello - {}", "hhh");try {itelImeiActivationService.checkItelImeiActivation(date, day);} catch (ProfitMandiBusinessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void selectFinServiceFollowUpDateByCurrDate(LocalDate currentDate) throwsMessagingException, ProfitMandiBusinessException, IOException {LOGGER.info("selectfinServiceFollow - {}", "selectfinServiceFollowUpDateByCurrDate");serviceConfigService.selectFinServicePartnerfollowUpDateByCurrentDate(currentDate);}public void checkTecnoImeiActivation(LocalDate date, Integer day) {LOGGER.info("Hello - {}", "hhh");try {tecnoImeiActivation.checkTecnoImeiActivation(date, day);} catch (ProfitMandiBusinessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void checkCancellationMargin() throws Exception {LocalDateTime startDate = LocalDate.of(2021, 4, 1).atStartOfDay();List<FofoOrder> fofoOrders = fofoOrderRepository.selectCancelledBetweenSaleDate(startDate, LocalDateTime.now());LOGGER.info("Total Orders = {}", fofoOrders.size());for (FofoOrder fofoOrder : fofoOrders) {List<UserWalletHistory> history = userWalletHistoryRepository.selectAllByreferenceIdandreferenceType(fofoOrder.getId(), WalletReferenceType.SCHEME_OUT);history.addAll(userWalletHistoryRepository.selectAllByreferenceIdandreferenceType(fofoOrder.getId(), WalletReferenceType.ACTIVATION_SCHEME));int walletSum = history.stream().mapToInt(x -> x.getAmount()).sum();if (Math.abs(walletSum) > 1) {// LOGGER.info("Cancelled invoice {}, Order Id = {}, = havent rolledback, Value// = {}", fofoOrder.getInvoiceNumber(), fofoOrder.getId(), walletSum);List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());List<FofoLineItem> flis = fofoLineItemRepository.selectByFofoOrderItemId(fofoOrderItems.get(0).getId());FofoLineItem fli = flis.get(0);if (StringUtils.isEmpty(fli.getSerialNumber()))continue;List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectByInventoryItemIds(new HashSet<>(Arrays.asList(fli.getInventoryItemId())));InventoryItem inventoryItem = inventoryItemRepository.selectById(fli.getInventoryItemId());double schemeSum = schemeInOuts.stream().filter(x -> x.getRolledBackTimestamp() == null).mapToDouble(x -> x.getAmount()).sum();/** if(inventoryItem.getGoodQuantity()==1) {* LOGGER.info("GoodQty, Serial Number {}, InventoryItem = {}, Billed on {}",* inventoryItem.getSerialNumber(), inventoryItem.getId(),* inventoryItem.getUpdateTimestamp()); } else* if(inventoryItem.getBadQuantity()==1){* LOGGER.info("Bad Qty, Serial Number {}, InventoryItem = {}, Billed on {}",* inventoryItem.getSerialNumber(), inventoryItem.getId(),* inventoryItem.getUpdateTimestamp()); } else if* (inventoryItem.getLastScanType().equals(ScanType.SALE)) { LOGGER.* info("Problem Sold, Serial Number {}, InventoryItem = {}, Billed on {}",* inventoryItem.getSerialNumber(), inventoryItem.getId(),* inventoryItem.getUpdateTimestamp()); }*/if (inventoryItem.getLastScanType().equals(ScanType.SALE) || inventoryItem.getLastScanType().equals(ScanType.SALE_RET)) {Map<String, Double> map = schemeInOuts.stream().collect(groupingBy(x -> DateTimeFormatter.ofPattern("yyyyMMddHH").format(x.getCreateTimestamp()) + "- " + x.getSchemeId(), Collectors.summingDouble(x -> x.getAmount())));for (Entry<String, Double> entry : map.entrySet()) {LOGGER.info("{} = {}", entry.getKey(), entry.getValue());}LOGGER.info("id- {}, imei- {}, lastScan = {}, Scheme sum - {}", inventoryItem.getId(), inventoryItem.getSerialNumber(), inventoryItem.getLastScanType(), schemeSum);}}}}public static String readFileAsString(String file) throws Exception {String data = "";data = new String(Files.readAllBytes(Paths.get(file)));return data;}@Autowiredprivate PartnerCollectionRemarkRepository partnerCollectionRemarkRepository;//RBM L2 Escalationspublic void reviewUncontactablePartner() throwsProfitMandiBusinessException, MessagingException, UnsupportedEncodingException {Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(true);List<Integer> partnerLastCollectionRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(new ArrayList<>(customRetailerMap.keySet()));if (!partnerLastCollectionRemarkIds.isEmpty()) {List<PartnerCollectionRemark> partnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(partnerLastCollectionRemarkIds);Map<Integer, PartnerCollectionRemark> rbmEscalatedRemarksMap = partnerCollectionRemarks.stream().filter(x -> x.getRemark().equals(CollectionRemark.RBM_L2_ESCALATION)).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));Map<Integer, PartnerCollectionRemark> salesEscalatedRemarksMap = partnerCollectionRemarks.stream().filter(x -> x.getRemark().equals(CollectionRemark.SALES_ESCALATION)).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));if (!rbmEscalatedRemarksMap.isEmpty()) {//for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream().map(x -> rbmEscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());String subject = "Partners escalated to RBM-L2";String messageText = this.getMessageForRBMEscalatedPartners(filteredRows);MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);String[] email = new String[]{storeGuyEntry.getKey()};helper.setSubject(subject);helper.setText(messageText, true);helper.setTo(email);InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");helper.setFrom(senderAddress);mailSender.send(message);LOGGER.info("filteredRows {}", filteredRows);}}if (!salesEscalatedRemarksMap.isEmpty()) {//for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_RBM), true).entrySet()) {List<PartnerCollectionRemark> filteredRows = storeGuyEntry.getValue().stream().map(x -> salesEscalatedRemarksMap.get(x)).filter(x -> x != null).collect(Collectors.toList());String subject = "Partners escalated to Sales";String messageText = this.getMessageForSalesEscalatedPartners(filteredRows);MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);String[] email = new String[]{storeGuyEntry.getKey()};helper.setSubject(subject);helper.setText(messageText, true);helper.setTo(email);InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");helper.setFrom(senderAddress);mailSender.send(message);LOGGER.info("filteredRows {}", filteredRows);}}}}@Autowiredprivate NonSdBuyingRepository nonSdBuyingRepository;//Non Sd Buyingpublic void reviewNonSdBuyingBrand() throwsProfitMandiBusinessException, MessagingException, UnsupportedEncodingException {List<NonSdBuying> nonSdByuingActiveList = nonSdBuyingRepository.selectAllActiveNonSDBuyingList(true);Map<Integer, NonSdBuying> unAuthorizedBuyingMap = nonSdByuingActiveList.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));if (!unAuthorizedBuyingMap.isEmpty()) {for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM), true).entrySet()) {List<NonSdBuying> unAuthorizedfilteredRows = storeGuyEntry.getValue().stream().map(x -> unAuthorizedBuyingMap.get(x)).filter(x -> x != null).collect(Collectors.toList());if (!unAuthorizedfilteredRows.isEmpty()) {String subject = "Unauthorized Buying";String messageText = this.getMessageForUnauthorizedBuying(unAuthorizedfilteredRows);MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);String[] email = new String[]{storeGuyEntry.getKey()};helper.setSubject(subject);helper.setText(messageText, true);helper.setTo(email);InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smartdukaan Alerts");helper.setFrom(senderAddress);mailSender.send(message);LOGGER.info("unAuthorizedfilteredRows {}", unAuthorizedfilteredRows);}}}}@Autowiredprivate LoanRepository loanRepository;@Autowiredprivate LoanStatementRepository loanStatementRepository;@Autowiredprivate SDCreditRequirementRepository sdCreditRequirementRepository;@Autowiredprivate CurrentPartnerDailyInvestmentRepository currentPartnerDailyInvestmentRepository;@Autowiredprivate TransactionRepository transactionRepository;@Autowiredprivate SanctionRequestRepository sanctionRequestRepository;public void calculateInterestAccured() throws ProfitMandiBusinessException {List<Loan> loans = loanRepository.selectAllActiveLoan();//List<Loan> loans = Arrays.asList(loanRepository.selectByLoanId(52669));for (Loan loan : loans) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(loan.getId());Map<LoanReferenceType, Double> loanStatusAmount = loanStatements.stream().collect(groupingBy(x -> x.getLoanReferenceType(), Collectors.summingDouble(x -> x.getAmount().doubleValue())));int freeDays = loan.getFreeDays();LocalDate freeDaysLimitDate = loan.getCreatedOn().plusDays(freeDays).toLocalDate();LOGGER.info("Loan id - {}, freeDaysLimitDate {}", loan.getId(), freeDaysLimitDate);if (LocalDate.now().isAfter(freeDaysLimitDate)) {int loanStatementId = loanStatementRepository.selectLatestLoanSatement(loan.getFofoId(), loan.getId());LOGGER.info("loanStatementId {}", loanStatementId);if (loanStatementId != 0) {this.calculateInterest(loan, loanStatusAmount, loanStatementId);} else {sdCreditService.addInterest(freeDaysLimitDate, LocalDate.now(), loan, loanStatusAmount);}}}}@AutowiredFofoPaymentRepository fofoPaymentRepository;@AutowiredCCAvenuePaymentService ccAvenuePaymentService;public void settleCCAvePayments() throws Exception {List<FofoPayment> fofoPayments = fofoPaymentRepository.selectAllByGatewayStatus(Gateway.CCAVENUE, PaymentStatus.INIT).stream().filter(x -> x.getCreateTimestamp().isBefore(LocalDateTime.now().minusMinutes(30l))).collect(Collectors.toList());for (FofoPayment fofoPayment : fofoPayments) {ccAvenuePaymentService.updatePayment(fofoPayment);}}/** public void getCCAvenuePendingOrderStatus(int pendingOrderId) { PendingOrder* pendingOrder = pendingOrderRepository.selectById(pendingOrderId);* ccAvenuePaymentService.getPaymentStatusMap(pendingOrder); }*/private void calculateInterest(Loan loan, Map<LoanReferenceType, Double> loanStatusAmount,int loanStatementId) throws ProfitMandiBusinessException {LoanStatement loanStatement = loanStatementRepository.selectById(loanStatementId);if (loanStatement.getLoanId() == loan.getId()) {sdCreditService.addInterest(loanStatement.getCreatedAt().toLocalDate().plusDays(1), LocalDate.now(), loan, loanStatusAmount);} else {throw new ProfitMandiBusinessException("loanstament", loanStatement.getLoanId(), "Invalid LoanId");}}public void loanSettlement() throws Exception {List<Loan> loans = loanRepository.selectAllActiveLoanForSettlement().stream().filter(x -> x.canBeSettled()).collect(toList());//TODO:Upto hereif (!loans.isEmpty()) {for (Loan loan : loans) {LOGGER.info("Loan - {}, {}", loan.getId(), loan.canBeSettled());double settledAmount = sdCreditService.settleLoan(loan);List<SanctionRequest> sanctionRequests = sanctionRequestRepository.selectHoldSanctionByFofoId(loan.getFofoId());for (SanctionRequest sanctionRequest : sanctionRequests) {List<Order> orders = orderRepository.selectAllByTransactionId(sanctionRequest.getTransactionId());if (orders.size() == 0) {LOGGER.info("Could not find orders - for Sanction Request {}", sanctionRequest);continue;}if (settledAmount >= sanctionRequest.getPendingAmount().doubleValue()) {settledAmount -= sanctionRequest.getPendingAmount().doubleValue();sanctionRequest.setPendingAmount(BigDecimal.valueOf(0));this.sendUnholdEmail(orders);} else {double pendinAmount = sanctionRequest.getPendingAmount().doubleValue() - settledAmount;System.out.println("Pending Amount - " + pendinAmount);sanctionRequest.setPendingAmount(BigDecimal.valueOf(pendinAmount));break;}}}}}private void sendUnholdEmail(List<Order> orders) throws Exception {orders.forEach(x -> x.setShipmentHold(false));orders = orders.stream().filter(x -> x.getRefundTimestamp() != null).collect(Collectors.toList());if (orders.size() > 0) {double totalAmount = orders.stream().collect(Collectors.summingDouble(x -> x.getTotalAmount()));List<String> authUserEmail = csService.getAuthUserIdByPartnerId(orders.get(0).getRetailerId()).stream().map(x -> x.getEmailId()).collect(Collectors.toList());authUserEmail.add("vinay.p@smartdukaan.com");authUserEmail.add("shivam.gupta@smartdukaan.com");String[] emailTo = authUserEmail.toArray(new String[authUserEmail.size()]);String[] ccTo = {"tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com"};String subject = "Dispatch held orders of - " + (orders.get(0).getRetailerName());String message = String.format("Dear Team, \n" + "kindly note the material for the " + orders.get(0).getRetailerName() + "of Rs." + totalAmount + "is unhold now and needs to be dispatched.");Utils.sendMailWithAttachments(mailSender, emailTo, ccTo, subject, message);}}public void dailyLoanAlert() throws Exception {List<Loan> loans = loanRepository.selectAllActiveLoan();Map<Integer, Double> partnerLoanAmount = new HashMap<>();if (!loans.isEmpty()) {for (Loan loan : loans) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(loan.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));if (partnerLoanAmount.get(loan.getFofoId()) != null) {amount += partnerLoanAmount.get(loan.getFofoId());partnerLoanAmount.put(loan.getFofoId(), amount);} else {partnerLoanAmount.put(loan.getFofoId(), amount);}}}if (!partnerLoanAmount.isEmpty()) {for (Entry<Integer, Double> partnerLoanAmountEnrty : partnerLoanAmount.entrySet()) {int fofoId = partnerLoanAmountEnrty.getKey();com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(fofoId);Address address = addressRepository.selectById(user.getAddressId());String title = "Alert Credit Outstanding!";String url = "http://app.smartdukaan.com/pages/home/credit";String message = "Your total outstanding Credit Balance is Rs." + FormattingUtils.formatDecimal(Math.abs(partnerLoanAmountEnrty.getValue())) + ".";notificationService.sendNotification(fofoId, title, MessageType.notification, title, message, url);//notificationService.sendWhatsappMessage(message, title, address.getPhoneNumber());}}}public void processActivatedImeisForSchemes() throws ProfitMandiBusinessException {schemeService.processActivatedImeisForSchemes();}@AutowiredSidbiService sidbiService;public void processSidbiDeductions() throws ProfitMandiBusinessException {//sidbiService.migrateSanctions();sidbiService.processDeductions();}public void updatePartnerLimit(int fofoId) throws ProfitMandiBusinessException {LocalDateTime firstBillingDate = transactionRepository.getFirstBillingDate(fofoId);CreditAccount creditAccount = creditAccountRepository.selectByFofoIdAndGateway(fofoId, Gateway.SDDIRECT);BigDecimal utilizationAmount = sdCreditService.getUtilizationAmount(fofoId);PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoId, 0);BigDecimal suggestedAmount = this.getSuggestedAmount(creditAccount, partnerDailyInvestment, utilizationAmount, null);SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(fofoId);LOGGER.info("suggestedAmount {} ", suggestedAmount);if (sdCreditRequirement == null) {sdCreditRequirement = new SDCreditRequirement();sdCreditRequirement.setFofoId(fofoId);sdCreditRequirement.setCreditDays(15);sdCreditRequirement.setInterestRate(ProfitMandiConstants.NEW_INTEREST_RATE);sdCreditRequirement.setRisk(CreditRisk.HIGH_RISK);sdCreditRequirement.setUtilizedAmount(BigDecimal.ZERO);sdCreditRequirement.setCreateTimestamp(LocalDateTime.now());sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());sdCreditRequirementRepository.persist(sdCreditRequirement);}CreditRisk creditRisk = sdCreditService.getCurrentRisk(sdCreditRequirement, firstBillingDate);sdCreditRequirement.setRisk(creditRisk);LOGGER.info("Suggested Amount - {}", suggestedAmount);sdCreditRequirement.setSuggestedLimit(suggestedAmount);if (!sdCreditRequirement.isHardLimit()) {sdCreditRequirement.setLimit(suggestedAmount);}BigDecimal utilizedLimit = sdCreditService.getUtilizationAmount(fofoId);BigDecimal availableLimit = sdCreditRequirement.getLimit().subtract(utilizedLimit);LOGGER.info("utilizedLimit {} ", utilizedLimit);LOGGER.info("availableLimit {} ", availableLimit);sdCreditRequirement.setUtilizedAmount(utilizedLimit);sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());if (creditAccount != null) {creditAccount.setInterestRate(sdCreditRequirement.getInterestRate().floatValue());creditAccount.setSanctionedAmount(sdCreditRequirement.getLimit().floatValue());creditAccount.setAvailableAmount(availableLimit.floatValue());creditAccount.setFreeDays(sdCreditRequirement.getFreeDays());creditAccount.setUpdatedOn(LocalDateTime.now());}}public void updatePartnerLimit() throws ProfitMandiBusinessException {Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(true);Map<Integer, BigDecimal> fofoSidbiLimitMap = sidbiService.getSuggestedLimitMap();Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));Map<Integer, CreditAccount> creditAccountMap = creditAccountRepository.selectAllByGateways(Arrays.asList(Gateway.SIDBI, Gateway.SDDIRECT)).stream().filter(x -> x.isActive()).collect(Collectors.toMap(x -> x.getFofoId(), x -> x));for (Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {int fofoId = customRetailerEntry.getKey();LocalDateTime firstBillingDate = transactionRepository.getFirstBillingDate(fofoId);CreditAccount creditAccount = creditAccountMap.get(fofoId);BigDecimal utilizationAmount = sdCreditService.getUtilizationAmount(fofoId);PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoId, 0);BigDecimal suggestedAmount = this.getSuggestedAmount(creditAccount, partnerDailyInvestment, utilizationAmount, fofoSidbiLimitMap.get(fofoId));SDCreditRequirement sdCreditRequirement = sdCreditRequirementMap.get(fofoId);LOGGER.info("suggestedAmount {} ", suggestedAmount);if (sdCreditRequirement == null) {sdCreditRequirement = new SDCreditRequirement();sdCreditRequirement.setFofoId(fofoId);sdCreditRequirement.setCreditDays(15);sdCreditRequirement.setInterestRate(ProfitMandiConstants.NEW_INTEREST_RATE);sdCreditRequirement.setRisk(CreditRisk.HIGH_RISK);sdCreditRequirement.setUtilizedAmount(BigDecimal.ZERO);sdCreditRequirement.setCreateTimestamp(LocalDateTime.now());sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());sdCreditRequirementRepository.persist(sdCreditRequirement);}CreditRisk creditRisk = sdCreditService.getCurrentRisk(sdCreditRequirement, firstBillingDate);sdCreditRequirement.setRisk(creditRisk);sdCreditRequirement.setSuggestedLimit(suggestedAmount);if (!sdCreditRequirement.isHardLimit()) {sdCreditRequirement.setLimit(suggestedAmount);}BigDecimal utilizedLimit = sdCreditService.getUtilizationAmount(fofoId);BigDecimal availableLimit = sdCreditRequirement.getLimit().subtract(utilizedLimit);LOGGER.info("utilizedLimit {} ", utilizedLimit);LOGGER.info("availableLimit {} ", availableLimit);sdCreditRequirement.setUtilizedAmount(utilizedLimit);sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());if (creditAccount != null) {creditAccount.setInterestRate(sdCreditRequirement.getInterestRate().floatValue());creditAccount.setSanctionedAmount(sdCreditRequirement.getLimit().floatValue());creditAccount.setAvailableAmount(availableLimit.floatValue());creditAccount.setFreeDays(sdCreditRequirement.getFreeDays());creditAccount.setUpdatedOn(LocalDateTime.now());}}}private static final NavigableMap<Double, Double> discountMap = new TreeMap<>();static {discountMap.put(4 * ProfitMandiConstants.ONE_LAC - 1, 0.2); // Up to 3,99,999 -> 20%discountMap.put(10 * ProfitMandiConstants.ONE_LAC - 1, 0.25); // 4,00,000 to 9,99,999 -> 25%discountMap.put(20 * ProfitMandiConstants.ONE_LAC - 1, 0.3); // 10,00,000 to 19,99,999 -> 30%discountMap.put(Double.MAX_VALUE, 0.4); // 20,00,000 and above -> 40%}public BigDecimal getSuggestedLimit(double investmentValue) {double percentageValue = discountMap.ceilingEntry(investmentValue).getValue();return this.getSuggestedAmount(investmentValue, percentageValue);}private BigDecimal getSuggestedAmount(double investmentValue, double percentageValue) {return BigDecimal.valueOf(investmentValue * percentageValue);}/*private static List<Integer> hundredPercentLimitPartnerIds = Arrays.asList(175139630,175139815,175139844,175140101);*/private static List<Integer> hundredPercentLimitPartnerIds = Arrays.asList();private BigDecimal getSuggestedAmount(CreditAccount creditAccount, PartnerDailyInvestmentpartnerDailyInvestment, BigDecimal utilizationAmount, BigDecimal sidbiLimit) {BigDecimal suggestedAmount = BigDecimal.ZERO;double utilization = utilizationAmount != null ? utilizationAmount.doubleValue() : 0;//1 LACif (creditAccount == null || creditAccount.getGateway().equals(Gateway.SDDIRECT)) {if (partnerDailyInvestment != null) {if (hundredPercentLimitPartnerIds.contains(partnerDailyInvestment.getFofoId())) {suggestedAmount = getSuggestedAmount(partnerDailyInvestment.getTotalInvestment() - utilization, 1);suggestedAmount = suggestedAmount.min(BigDecimal.valueOf(1500000));} else {suggestedAmount = getSuggestedLimit(partnerDailyInvestment.getTotalInvestment() - utilization);}}if (suggestedAmount.doubleValue() < 0) {suggestedAmount = BigDecimal.ZERO;}} else if (creditAccount.getGateway().equals(Gateway.SIDBI) && sidbiLimit != null) {suggestedAmount = getSuggestedLimit(partnerDailyInvestment.getTotalInvestment() - utilization);suggestedAmount = suggestedAmount.max(sidbiLimit);}return suggestedAmount;}public void notifyDefaultLoans() throws ProfitMandiBusinessException, MessagingException, IOException {sdCreditService.updateRisk();List<Loan> defaultLoans = sdCreditService.getDefaultLoans();if (!defaultLoans.isEmpty()) {this.sendDefaultLoanAlert(defaultLoans);}}public void sendDefaultLoanAlert(List<Loan> defaultLoans) throwsProfitMandiBusinessException, MessagingException, IOException {String subject = "Default Partners";List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_ACCOUNTS, ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {List<Loan> filteredRows = new ArrayList<>();for (Loan loan : defaultLoans) {if (storeGuyEntry.getValue().contains(loan.getFofoId())) {filteredRows.add(loan);}}if (!filteredRows.isEmpty()) {String[] email = new String[]{storeGuyEntry.getKey()};String messageText = this.getMessageForDueDateExtend(filteredRows);this.sendMailOfHtmlFormat(googleMailSender, email, messageText, null, subject);}}String messageText = this.getMessageForDueDateExtend(defaultLoans);this.sendMailOfHtmlFormat(googleMailSender, new String[]{"puneet.wahi@smartdukaan.com", "rahul.latwal@smartdukaan.com", "dilbag.singh@smartdukaan.com"}, messageText, null, subject);for (Loan defaultLoan : defaultLoans) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(defaultLoan.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(defaultLoan.getFofoId());Address address = addressRepository.selectById(user.getAddressId());String title = "Outstanding Credit Payment Overdue!";String url = "http://app.smartdukaan.com/pages/home/credit";String message = "Your Outstanding Credit payment due date " + defaultLoan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + " has been exceeded. Please note " + ProfitMandiConstants.NEW_DELAYED_INTEREST_RATE + " shall be levied on daily basis." + " Your total pending Loan amount is Rs." + FormattingUtils.formatDecimal(Math.abs(amount)) + ". !!Pay Now!!";notificationService.sendNotification(defaultLoan.getFofoId(), title, MessageType.notification, title, message, url);// notificationService.sendWhatsappMessage(message, title,// address.getPhoneNumber());}}private String getMessageForDueDateExtend(List<Loan> loans) throws ProfitMandiBusinessException {Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();List<AST> asts = astRepository.selectAll();Map<Integer, AST> astMap = asts.stream().collect(Collectors.toMap(AST::getId, ast -> ast));StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Default Partners :-</p>" + "<br/><p>EveryDay Rs.100 charged as Penalty</p>" + "<br/>" +"<table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" +"<tr>\n" +"<th style='border:1px solid black;padding: 5px'>PartnerName</th>\n" +"<th style='border:1px solid black;padding: 5px'>State Name</th>\n" +"<th style='border:1px solid black;padding: 5px'>Area</th>\n" +"<th style='border:1px solid black;padding: 5px'>Territory</th>\n" +"<th style='border:1px solid black;padding: 5px'>due date</th>\n" +"<th style='border:1px solid black;padding: 5px'>Days</th>\n" +"<th style='border:1px solid black;padding: 5px'>Pending Amount</th>\n" +"<th style='border:1px solid black;padding: 5px'>RBM L2</th>\n" +"<th style='border:1px solid black;padding: 5px'>RBM L1</th>\n" +"<th style='border:1px solid black;padding: 5px'>Sales L1</th>\n" +"<th style='border:1px solid black;padding: 5px'>Sales L2</th>\n" +"</tr>");for (Loan entry : loans) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getAddress().getState() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getArea() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getTerritory() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + noOfdaysBetween + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + new DecimalFormat("#.##").format(Math.abs(amount)) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager() + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}private String getMessageForDueDateCross(List<Loan> dueDateCrossLoans) throws ProfitMandiBusinessException {Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();List<AST> asts = astRepository.selectAll();Map<Integer, AST> astMap = asts.stream().collect(Collectors.toMap(AST::getId, ast -> ast));StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Alert</p><p>Partner Credit Report :-</p>" + "<br/><p>Additional penal interest of shall be levied on daily basis.</p>" + "<br/>" +"<table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" + "<tr>\n" +"<th style='border:1px solid black;padding: 5px'>PartnerName</th>\n" +"<th style='border:1px solid black;padding: 5px'>State Name</th>\n" +"<th style='border:1px solid black;padding: 5px'>Area</th>\n" +"<th style='border:1px solid black;padding: 5px'>Territory</th>\n" +"<th style='border:1px solid black;padding: 5px'>due date</th>\n" +"<th style='border:1px solid black;padding: 5px'>Days</th>\n" +"<th style='border:1px solid black;padding: 5px'>Pending Amount</th>\n" +"<th style='border:1px solid black;padding: 5px'>RBM L2</th>\n" +"<th style='border:1px solid black;padding: 5px'>RBM L1</th>\n" +"<th style='border:1px solid black;padding: 5px'>Sales L1</th>\n" +"<th style='border:1px solid black;padding: 5px'>Sales L2</th>\n" +"<th style='border:1px solid black;padding: 5px'>Limit Assigned</th>\n" +"</tr>");for (Loan entry : dueDateCrossLoans) {DecimalFormat df = new DecimalFormat("#.##");List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(customRetailer.getPartnerId());sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")" + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customRetailer.getAddress().getState() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getArea() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + astMap.get(customRetailer.getAstId()).getTerritory() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + noOfdaysBetween + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + new DecimalFormat("#.##").format(Math.abs(amount)) + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager() + "</td>");sb.append("<td style='border:1px solid black;padding: 5px'>" + df.format(sdCreditRequirement.getLimit()) + "</td>");sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}public void notifyLoanDueDateCross() throws Exception {List<Loan> dueDateCrossLoans = sdCreditService.getDueDateCrossLoan();List<Loan> allActiveLoans = sdCreditService.getAllActiveLoan();if (!dueDateCrossLoans.isEmpty()) {this.sendDueDateCrossLoanAlert(dueDateCrossLoans, allActiveLoans);}}private void sendDueDateCrossLoanAlert(List<Loan> dueDateCrossLoans, List<Loan> allActiveLoans) throws Exception {List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_ACCOUNTS, ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);for (Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {List<Loan> filteredRows = new ArrayList<>();for (Loan loan : dueDateCrossLoans) {if (storeGuyEntry.getValue().contains(loan.getFofoId())) {filteredRows.add(loan);}}List<Loan> filteredAllActiveLoans = new ArrayList<>();for (Loan loan : allActiveLoans) {if (storeGuyEntry.getValue().contains(loan.getFofoId())) {filteredAllActiveLoans.add(loan);}}ByteArrayOutputStream byteArrayOutputStream = null;Utils.Attachment attachment1 = null;if (!filteredAllActiveLoans.isEmpty()) {byteArrayOutputStream = this.generateLoanCsv(filteredAllActiveLoans);attachment1 = new Utils.Attachment("partnner-credit.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));}if (!filteredRows.isEmpty()) {String messageText = this.getMessageForDueDateCross(filteredRows);String[] email = new String[]{storeGuyEntry.getKey()};if (attachment1 != null) {Utils.sendMailWithAttachments(googleMailSender, email, null, null, "Partner Credit Report", messageText, true, attachment1);} else {this.sendMailOfHtmlFormat(googleMailSender, email, messageText, null, "Due Date Cross");}}}String messageText = this.getMessageForDueDateCross(dueDateCrossLoans);ByteArrayOutputStream byteArrayOutputStream = this.generateLoanCsv(allActiveLoans);Utils.Attachment attachment = null;if (byteArrayOutputStream != null) {attachment = new Utils.Attachment("partnner-credit.csv", new ByteArrayResource(byteArrayOutputStream.toByteArray()));}if (attachment != null) {Utils.sendMailWithAttachments(googleMailSender, new String[]{"sdtech@smartdukaan.com"}, null, null, "Partner Credit Report", messageText, true, attachment);} else {this.sendMailOfHtmlFormat(googleMailSender, new String[]{"sdtech@smartdukaan.com"}, messageText, null, "Due Date Cross");}if (!dueDateCrossLoans.isEmpty()) {for (Loan loan : dueDateCrossLoans) {long noOfdaysBetween = ChronoUnit.DAYS.between(loan.getDueDate().toLocalDate(), LocalDate.now());com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(loan.getFofoId());Address address = addressRepository.selectById(user.getAddressId());LOGGER.info("noOfdaysBetween {} ", noOfdaysBetween);List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(loan.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));String url = "http://app.smartdukaan.com/pages/home/credit";String title = "Alert!";String message = "Your Outstanding Credit Payment due date " + loan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + " has been exceeded. Additional penal interest of " + loan.getInterestRate().setScale(2, RoundingMode.HALF_UP) + "% shall be levied on daily basis. Your total pending loan amount is Rs." + FormattingUtils.formatDecimal(Math.abs(amount)) + ". !!Pay Now!!";notificationService.sendNotification(loan.getFofoId(), title, MessageType.notification, title, message, url);//notificationService.sendWhatsappMessage(message, title, address.getPhoneNumber());}}}private ByteArrayOutputStream generateLoanCsv(List<Loan> loans) throws ProfitMandiBusinessException {org.apache.commons.io.output.ByteArrayOutputStream byteArrayOutputStream = null;if (!loans.isEmpty()) {Map<Integer, com.spice.profitmandi.dao.model.FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();Map<Integer, FofoRBMReportingModel> fofoRbmReportingModelMap = csService.getPartnerIdRBMHeaders();List<AST> asts = astRepository.selectAll();Map<Integer, AST> astMap = asts.stream().collect(Collectors.toMap(AST::getId, ast -> ast));try {List<String> headers = Arrays.asList("PartnerName", "State Name", "Area", "Territory","Due Date", "Days", "Pending Amount","RBM L2", "RBM L1", "Sales L1", "Sales L2", "Limit Assigned");List<List<?>> rows = new ArrayList<>();for (Loan entry : loans) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));// long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getDueDate().toLocalDate(), LocalDateTime.now());long noOfdaysBetween = ChronoUnit.DAYS.between(entry.getCreatedOn().toLocalDate(), LocalDateTime.now());CustomRetailer customRetailer = retailerService.getFofoRetailer(entry.getFofoId());SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(customRetailer.getPartnerId());DecimalFormat df = new DecimalFormat("#.##");List<String> row = Arrays.asList(customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")",customRetailer.getAddress().getState(),astMap.get(customRetailer.getAstId()).getArea(),astMap.get(customRetailer.getAstId()).getTerritory(),entry.getDueDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")),String.valueOf(noOfdaysBetween),df.format(Math.abs(amount)),fofoRbmReportingModelMap.get(entry.getFofoId()).getL1Manager(),fofoRbmReportingModelMap.get(entry.getFofoId()).getL2Manager(),fofoReportingModelMap.get(entry.getFofoId()).getTerritoryManager(),fofoReportingModelMap.get(entry.getFofoId()).getRegionalManager(),df.format(sdCreditRequirement.getLimit()));rows.add(row);}byteArrayOutputStream = FileUtil.getCSVByteStream(headers, rows);} catch (Exception e) {throw new RuntimeException(e);}}return byteArrayOutputStream;}public void alertForDueDate() throws Exception {List<Loan> loans = loanRepository.selectAllActiveLoan();if (!loans.isEmpty()) {for (Loan loan : loans) {com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(loan.getFofoId());Address address = addressRepository.selectById(user.getAddressId());long noOfdaysBetween = ChronoUnit.DAYS.between(LocalDate.now(), loan.getDueDate().toLocalDate());LOGGER.info("noOfdaysBetween {} ", noOfdaysBetween);if (noOfdaysBetween <= 4 && noOfdaysBetween >= 0) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(loan.getId());double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));String title = "Alert!";String url = "http://app.smartdukaan.com/pages/home/credit";String message = null;if (noOfdaysBetween == 0) {message = "Your total outstanding Credit amount is Rs." + FormattingUtils.formatDecimal(Math.abs(amount)) + " is due for Today, Pay Now!!";} else {message = "Your total outstanding Credit amount is Rs." + FormattingUtils.formatDecimal(Math.abs(amount)) + " is due by " + loan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + " , Pay Now!!";}notificationService.sendNotification(loan.getFofoId(), title, MessageType.notification, title, message, url);//notificationService.sendWhatsappMessage(message, title, address.getPhoneNumber());}}}}public void userMobileNumberOptIn() throws Exception {List<FofoStore> fofoStores = fofoStoreRepository.selectActiveStores();List<com.spice.profitmandi.dao.entity.user.User> users = userUserRepository.selectByIds(fofoStores.stream().map(x -> x.getId()).collect(Collectors.toList()));List<Address> addresses = addressRepository.selectByIds(users.stream().map(x -> x.getAddressId()).collect(Collectors.toList()));LOGGER.info("addresses" + addresses);for (Address address : addresses) {notificationService.optIn(address.getPhoneNumber());}}public void authUserMobileNumberOptIn() throws HttpHostConnectException, ProfitMandiBusinessException {List<AuthUser> authUsers = authRepository.selectAllActiveUser();LOGGER.info("authUsers" + authUsers);for (AuthUser authUser : authUsers) {Map<String, String> requestheaders = new HashMap<>();requestheaders.put("Content-Type", "application/x-www-form-urlencoded");Map<String, String> requestParams = new HashMap<>();requestParams.put("userid", String.valueOf(2000215976));requestParams.put("password", "MFRd!BBL");requestParams.put("phone_number", authUser.getMobileNumber());requestParams.put("auth_scheme", "plain");requestParams.put("v", "1.1");requestParams.put("format", "json");requestParams.put("method", "OPT_IN");requestParams.put("channel", "WHATSAPP");String response = restClient.get("https://media.smsgupshup.com/GatewayAPI/rest", requestParams, requestheaders);LOGGER.info("response" + response);}}@Autowiredprivate HygieneDataRepository hygieneDataRepository;public void hygineAlertForPartner() throws ProfitMandiBusinessException, MessagingException, IOException {List<String> remarks = new ArrayList<>();remarks.add("Out of Service");remarks.add("Duplicate number");remarks.add("Partner number");List<HygieneData> hygieneData = hygieneDataRepository.selectAllByDisposedDateAndRemark(LocalDate.now(), remarks);if (!hygieneData.isEmpty()) {Map<Integer, List<HygieneData>> partnerHygieneDataMap = hygieneData.stream().collect(groupingBy(x -> x.getFofoId()));for (Entry<Integer, List<HygieneData>> partnerHygieneDataMapEntry : partnerHygieneDataMap.entrySet()) {CustomRetailer customRetailer = retailerService.getFofoRetailer(partnerHygieneDataMapEntry.getKey());StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Dear Partner," + "</p><br/><p>It has been observed in our calls to the respective customers that the contact no is either not correct or does not have incoming calls.\n"+ " </p>" + "<p>We would like to inform you that this will hinder all our marketing initiatives to bring this customer back to our smartdukaan or cross sell any product from your inventory." + "</p><p>Kindly ensure going forward that the details are correct so to avoid 1% margin loss.\n" + "</p><p>In case the data is found to be incorrect there is a loss of 1% margin on this sales under SmartDukaan hygiene guidelines.\n" + " " + "</p>"+ "<br/><table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" + " " + " " + "<tr>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Invoice Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Customer Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Customer Number</th>\n");sb.append("</tr>\n");List<HygieneData> hygienes = partnerHygieneDataMapEntry.getValue();List<Integer> orderIds = hygienes.stream().map(x -> x.getOrderId()).collect(Collectors.toList());List<FofoOrder> fofoOrders = fofoOrderRepository.selectAllByOrderIds(orderIds);for (FofoOrder fofoOrder : fofoOrders) {Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + fofoOrder.getInvoiceNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + customer.getFirstName() + "" + customer.getLastName() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + customer.getMobileNumber() + "</td>\n");sb.append("</tr>\n");}sb.append("</tbody></table></body></html>");String subject = "Customer Info - Hygiene Alert";this.sendMailOfHtmlFormat(mailSender, new String[]{customRetailer.getEmail()}, sb.toString(), null, subject);}}}//public void setInventoryItemIdToPriceDropImei() {List<PriceDropIMEI> priceDropIMEIList = priceDropIMEIRepository.selectAllMissingInventoryItemIds();LOGGER.info("Problems with - {} entries", priceDropIMEIList.size());//priceDropIMEIList.stream().collect(C)for (PriceDropIMEI priceDropIMEI : priceDropIMEIList) {System.out.println(priceDropIMEI.getImei());List<InventoryItem> inventoryItems = inventoryItemRepository.selectAllBySerialNumberFofoId(priceDropIMEI.getImei(), priceDropIMEI.getPartnerId());if (inventoryItems.size() == 0) {LOGGER.info("Could not find Grn - FofoID {} , Imei {} ", priceDropIMEI);} else if (inventoryItems.size() > 1) {LOGGER.info("Found 2 such instance for - FofoID {} , Imei {} ", priceDropIMEI.getImei(), priceDropIMEI.getPartnerId());} else {priceDropIMEI.setInventoryItemId(inventoryItems.get(0).getId());}}}@AutowiredSaholicReservationSnapshotRepository saholicReservationSnapshotRepository;public void removePartialBillingForTransaction(int transactionId) throws ProfitMandiBusinessException {// Fetch with pessimistic lock to prevent concurrent modificationsList<Order> orderList = orderRepository.selectAllByTransactionIdForUpdate(transactionId);Map<Integer, Order> orderMap = orderList.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));//Delete scanRecordsList<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(new ArrayList<>(orderMap.keySet()));for (WarehouseScan warehouseScan : warehouseScans) {warehouseScanRepository.delete(warehouseScan);WarehouseInventoryItem warehouseInventoryItem = warehouseInventoryItemRepository.selectById(warehouseScan.getInventoryItemId());warehouseInventoryItem.setLastScanType(in.shop2020.warehouse.ScanType.PURCHASE);warehouseInventoryItem.setCurrentQuantity(warehouseInventoryItem.getCurrentQuantity() + warehouseScan.getQuantity());}for (Order order : orderList) {if (order.getBillingTimestamp() != null) {order.setStatus(OrderStatus.ACCEPTED);order.setStatusDescription("Submitted for Processing");order.setBillingTimestamp(null);order.setBilledBy(null);order.setSerialNumber(null);order.setJacketNumber(null);order.getLineItem().setSerialNumber(null);List<LineItemImei> lineItemImeis = lineItemImeisRepository.selectByLineItemId(order.getLineItem().getId());for (LineItemImei lineItemImei : lineItemImeis) {lineItemImeisRepository.delete(lineItemImei);}SaholicReservationSnapshot saholicReservationSnapshot = saholicReservationSnapshotRepository.selectByOrderId(order.getId());if (saholicReservationSnapshot == null) {saholicInventoryService.addReservationCount(order.getLineItem().getItemId(),order.getFulfilmentWarehouseId(), order.getLineItem().getQuantity(), order.getId());}}}}public void hygineAlertForInternalTeam() throws ProfitMandiBusinessException, MessagingException, IOException {List<String> remarks = new ArrayList<>();remarks.add("Out of Service");remarks.add("Duplicate number");remarks.add("Partner number");List<HygieneData> hygieneDataLastThreeMonth = hygieneDataRepository.selectDisposedDateAndRemarks(LocalDate.now().withDayOfMonth(1).minusMonths(3).atStartOfDay(), LocalDate.now().minusMonths(1).withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth()).atTime(LocalTime.MAX), remarks);List<HygieneData> hygieneDataRecentMonth = hygieneDataRepository.selectDisposedDateAndRemarks(LocalDate.now().withDayOfMonth(1), remarks);Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();Map<Integer, List<HygieneData>> partnerHygieneLastThreeMonthMap = null;Map<Integer, List<HygieneData>> partnerHygieneDataRecentMonth = null;if (!hygieneDataLastThreeMonth.isEmpty()) {partnerHygieneLastThreeMonthMap = hygieneDataLastThreeMonth.stream().collect(groupingBy(x -> x.getFofoId()));}if (!hygieneDataRecentMonth.isEmpty()) {partnerHygieneDataRecentMonth = hygieneDataRecentMonth.stream().collect(groupingBy(x -> x.getFofoId()));}for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {String email = storeGuyEntry.getKey();List<Integer> fofoIds = new ArrayList<>(storeGuyEntry.getValue());Map<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthData = new HashMap<>();Map<Integer, Map<LocalDate, List<HygieneData>>> partnerDateWiseData = new HashMap<>();for (Integer fofoId : fofoIds) {partnerYearMonthData.put(fofoId, null);partnerDateWiseData.put(fofoId, null);if (!partnerHygieneLastThreeMonthMap.isEmpty()) {List<HygieneData> hygienes = partnerHygieneLastThreeMonthMap.get(fofoId);if (hygienes != null) {Map<YearMonth, List<HygieneData>> yearMonthData = hygienes.stream().collect(groupingBy(x -> YearMonth.from(x.getDisposedTimestamp())));partnerYearMonthData.put(fofoId, yearMonthData);}List<HygieneData> dateWiseHygienes = partnerHygieneDataRecentMonth.get(fofoId);if (dateWiseHygienes != null) {Map<LocalDate, List<HygieneData>> dateWiseData = hygienes.stream().collect(groupingBy(x -> (x.getDisposedTimestamp()).toLocalDate()));partnerDateWiseData.put(fofoId, dateWiseData);}}}String subject = "Customer Info - Hygiene Alert";LOGGER.info("hygieneData {}", partnerDateWiseData.values());boolean partnerDateWise = partnerDateWiseData.values().stream().allMatch(Objects::isNull);boolean partnerYearMonth = partnerYearMonthData.values().stream().allMatch(Objects::isNull);if (!partnerDateWise && !partnerYearMonth) {String sb = this.getMessageHygieneAlertForPartner(partnerYearMonthData, partnerDateWiseData);this.sendMailOfHtmlFormat(googleMailSender, new String[]{email}, sb, null, subject);}}}private String getMessageHygieneAlertForPartner(Map<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthData, Map<Integer, Map<LocalDate, List<HygieneData>>> partnerDateWiseData)throws ProfitMandiBusinessException {Map<Integer, CustomRetailer> customeRetailerMap = retailerService.getAllFofoRetailers();LocalDateTime startDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();LocalDateTime endDate = LocalDateTime.now();LocalDateTime startYearMonth = LocalDate.now().withDayOfMonth(1).minusMonths(3).atStartOfDay();LocalDateTime endYearMonth = LocalDate.now().minusMonths(1).withDayOfMonth(LocalDate.now().minusMonths(1).lengthOfMonth()).atTime(LocalTime.MAX);DateTimeFormatter dateYearMonthFormatter = DateTimeFormatter.ofPattern("MMM''uu");List<YearMonth> yearMonthRange = new ArrayList<>();yearMonthRange.add(YearMonth.from(startYearMonth));yearMonthRange.add(YearMonth.from(startYearMonth.plusMonths(1)));yearMonthRange.add(YearMonth.from(endYearMonth));long noOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate.plusDays(1));List<LocalDate> dateRange = Stream.iterate(startDate.toLocalDate(), date -> date.plusDays(1)).limit(noOfDaysBetween).collect(Collectors.toList());StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Hi," + "</p><br/><p>Kindly advise below mentioned partner to input correct details in the system else this will hinder all our marketing initiatives to bring this customer back to our smartdukaan or cross sell any product from partner's inventory.\n" + " </p>" + "<p>Kindly ensure going forward that the details are correct so to avoid 1% margin loss.\n" + "</p><p>In case the data is found to be incorrect there is a loss of 1% margin on this sales under SmartDukaan hygiene guidelines.\n</p>"+ "<table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" + " " + " " + "<tr>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Partner Name</th>\n");for (YearMonth yearMonth : yearMonthRange) {sb.append("<th style='border:1px solid black;padding: 5px'>" + yearMonth.format(dateYearMonthFormatter) + "</th>\n");}for (LocalDate localDate : dateRange) {sb.append("<th style='border:1px solid black;padding: 5px'>" + localDate + "</th>\n");}sb.append("</tr>\n");for (Entry<Integer, Map<YearMonth, List<HygieneData>>> partnerYearMonthEntry : partnerYearMonthData.entrySet()) {int fofoId = partnerYearMonthEntry.getKey();Map<YearMonth, List<HygieneData>> yearMonthData = partnerYearMonthEntry.getValue();Map<LocalDate, List<HygieneData>> dateWiseData = partnerDateWiseData.get(fofoId);if (yearMonthData == null && dateWiseData == null) {continue;}sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + customeRetailerMap.get(fofoId).getBusinessName() + "</td>\n");for (YearMonth yearMonth : yearMonthRange) {if (yearMonthData == null) {sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");} else {List<HygieneData> hygieneList = yearMonthData.get(yearMonth);if (hygieneList != null) {sb.append("<td style='border:1px solid black;padding: 5px'>" + hygieneList.size() + "</td>\n");} else {sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");}}}for (LocalDate localDate : dateRange) {if (dateWiseData == null) {sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");} else {List<HygieneData> hygieneList = dateWiseData.get(localDate);if (hygieneList != null) {sb.append("<td style='border:1px solid black;padding: 5px'>" + hygieneList.size() + "</td>\n");} else {sb.append("<td style='border:1px solid black;padding: 5px'>-</td>\n");}}}sb.append("</tr>");}sb.append("</tbody></table></body></html>");return sb.toString();}@Autowiredprivate MonthlyTargetRepository monthlyTargetRepository;public void monthlyTargetForPartner() throws MessagingException, ProfitMandiBusinessException, IOException {LocalDateTime curDate = LocalDateTime.now();List<MonthlyTarget> monthlyTargets = monthlyTargetRepository.selectByDate(YearMonth.now());Map<Integer, MonthlyTarget> partnersMonthlyTarget = monthlyTargets.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));Map<Integer, Double> todaytertiary = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate, curDate.with(LocalTime.MAX), 0, false);String subject = "Monthly Target Vs Achievement";for (Entry<Integer, MonthlyTarget> partnerMonthlyTargetEntry : partnersMonthlyTarget.entrySet()) {int fofoId = partnerMonthlyTargetEntry.getKey();CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoId);Double purchaseTarget = partnerMonthlyTargetEntry.getValue().getPurchaseTarget();Double saleTarget = partnerMonthlyTargetEntry.getValue().getSaleTarget();if (purchaseTarget > 0) {Double purchase = secondaryMtd.get(fofoId);if (purchase == null) {purchase = 0.0;}Double balanceTarget = purchaseTarget - purchase;if (balanceTarget <= 0) {balanceTarget = 0.0;}StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Dear Partner,\n");sb.append("<p>Pls note your agreed monthly target is Rs." + purchaseTarget + " and your achievement till date is Rs." + purchase + "</p>");sb.append("<p>Pls note that your balance target is Rs." + balanceTarget + "</p>\n");sb.append("<p>We wish you all the best and we are confident that this focused approach towards our outlet sales will help us take our outlet to the best SmartDukaan in your city.\n" + "</p>\n");this.sendMailOfHtmlFormat(mailSender, new String[]{customRetailer.getEmail()}, sb.toString(), null, subject);}}}public void findAllLiveDemoBrandItemsByBillingDate() throwsMessagingException, ProfitMandiBusinessException, IOException {LocalDateTime endDate = LocalDate.now().atStartOfDay().minusDays(8);List<LiveDemoOrderLineItemModel> liveDemoOrderLineItemModels = orderRepository.findAllLiveDemoBrandItemsByBillingDate(endDate.minusDays(60), endDate);LOGGER.info("liveDemoOrderLineItemModels {}", liveDemoOrderLineItemModels);String subject = "Billed Live Demo Model";StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Hi,\n");sb.append("<p>Please check live demo billed order :</p>\n" + " <table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");sb.append("<th style='border:1px solid black;padding: 5px'>Item Id</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Invoice Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Serial Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Retailer Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Retailer City</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Retailer Pincode</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Retailer State</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Billing Date</th>\n");sb.append("</tr>\n");for (LiveDemoOrderLineItemModel liveDemoModel : liveDemoOrderLineItemModels) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getItemId() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getInvoiceNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getBrand() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getModelNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getModelName() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getSerialNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerName() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerCity() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getRetailerPincode() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getState() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + liveDemoModel.getFormattedBillingDate() + "</td>\n");sb.append("</tr>\n");}List<String> sendTo = Arrays.asList("kamini.sharma@smartdukaan.com", "niranjan.kala@smartdukaan.com","mohit.gulati@smartdukaan.com", "vinay.p@smartdukaan.com", "shivam.gupta@smartdukaan.com");String[] email = sendTo.toArray(new String[sendTo.size()]);this.sendMailOfHtmlFormat(mailSender, email, sb.toString(), null, subject);}public void findTodayPocoBillingItems() throws MessagingException, ProfitMandiBusinessException, IOException {LocalDateTime endDate = LocalDate.now().atStartOfDay().plusDays(1);LocalDateTime startDate = LocalDate.now().atStartOfDay().minusDays(1);List<LiveDemoOrderLineItemModel> pocoBillingOrderLineItemModels = orderRepository.findTodayPocoBillingItems(startDate, endDate);LOGGER.info("pocoBillingOrderLineItemModels {}", pocoBillingOrderLineItemModels);String subject = "Poco Billing";StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Hi,\n");sb.append("<p>Please check poco billed order :</p>\n" + " <table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Serial Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Retailer State</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Billing Date</th>\n");sb.append("</tr>\n");for (LiveDemoOrderLineItemModel pocoModel : pocoBillingOrderLineItemModels) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getBrand() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getModelNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getModelName() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getSerialNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getState() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + pocoModel.getFormattedBillingDate() + "</td>\n");sb.append("</tr>\n");}List<String> sendTo = Arrays.asList("uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "nishant.ohri@smartdukaan.com", "ritesh.chauhan1@smartdukaan.com");String[] email = sendTo.toArray(new String[sendTo.size()]);this.sendMailOfHtmlFormat(mailSender, email, sb.toString(), null, subject);}public void monthlyTargetForInternalTeam() throws MessagingException, ProfitMandiBusinessException, IOException {LocalDateTime curDate = LocalDateTime.now();List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY, ProfitMandiConstants.TICKET_CATEGORY_RBM, ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_ABM, ProfitMandiConstants.TICKET_CATEGORY_MARKETING, ProfitMandiConstants.TICKET_CATEGORY_ACCOUNTS, ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false);List<MonthlyTarget> monthlyTargets = monthlyTargetRepository.selectByDate(YearMonth.now());Map<Integer, CustomRetailer> customeRetailerMap = retailerService.getAllFofoRetailers();Map<Integer, MonthlyTarget> partnersMonthlyTarget = monthlyTargets.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));Map<Integer, Double> secondaryMtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));Map<Integer, Double> todaytertiary = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate, curDate.with(LocalTime.MAX), 0, false);String subject = "Monthly Target Vs Achievement";for (Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {String email = storeGuyEntry.getKey();List<Integer> fofoIds = new ArrayList<>(storeGuyEntry.getValue());Map<Integer, MonthlyTarget> monthlyTargetAchievement = new HashMap<>();for (Integer fofoId : fofoIds) {MonthlyTarget monthlyTarget = partnersMonthlyTarget.get(fofoId);if (monthlyTarget != null) {Double purchaseTarget = monthlyTarget.getPurchaseTarget();Double saleTarget = monthlyTarget.getSaleTarget();if (purchaseTarget != null && purchaseTarget > 0) {Double purchase = secondaryMtd.get(fofoId);if (purchase == null) {purchase = 0.0;}monthlyTarget.setPurchaseAchievement(purchase);monthlyTargetAchievement.put(fofoId, monthlyTarget);}}}if (!monthlyTargetAchievement.isEmpty()) {StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Hi,\n");sb.append("<p>Pls note your Partners agreed monthly target foolowing are :</p>\n" + " <table style='border:1px solid black ;padding: 5px';>");sb.append("<tbody>\n" + " " + " " + "<tr>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Partner Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Purchase Target</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Purchase Achievement</th>\n");sb.append("</tr>\n");for (Entry<Integer, MonthlyTarget> monthlyTargetAchievementEntry : monthlyTargetAchievement.entrySet()) {sb.append("<tr>");int fofoId = monthlyTargetAchievementEntry.getKey();MonthlyTarget monthlyTarget = monthlyTargetAchievementEntry.getValue();sb.append("<td style='border:1px solid black;padding: 5px'>" + customeRetailerMap.get(fofoId).getBusinessName() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + monthlyTarget.getPurchaseTarget() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + monthlyTarget.getPurchaseAchievement() + "</td>\n");sb.append("</tr>\n");}this.sendMailOfHtmlFormat(googleMailSender, new String[]{email}, sb.toString(), null, subject);// this.sendMailOfHtmlFormat("tejbeer.kaur@smartdukaan.com", sb.toString(),// null, subject);}}}@Autowiredprivate PerformanceService performanceService;public void sendFilteredRetailerPerformance() throws Exception {RetailerFilterModel retailerFilterModel = performanceService.getRetailerFilterModel();Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(true);List<RetailerPeformanceFilterModel> partnersPerformance = performanceService.getPerformance(retailerFilterModel, customRetailers);Map<Integer, RetailerPeformanceFilterModel> partnersPerformanceMap = new HashMap<>();if (!partnersPerformance.isEmpty()) {partnersPerformanceMap = partnersPerformance.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));performanceService.sendPartnerPerformanceEmail(partnersPerformanceMap, retailerFilterModel, customRetailers);}}@Autowiredprivate VendorItemPricingRepository vendorItemPricingRepository;@Autowiredprivate VendorCatalogPricingService vendorCatalogPricingService;public void migrateVendorItemPricing() throws ProfitMandiBusinessException {List<VendorItemPricing> vendorItemPricings = vendorItemPricingRepository.selectAll();LOGGER.info("At migrate VendorItemPricing");Map<Integer, Item> items = itemRepository.selectByIds(vendorItemPricings.stream().map(x -> x.getItemId()).collect(Collectors.toSet())).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));for (VendorItemPricing vendorItemPricing : vendorItemPricings) {Item item = null;if (items.get(vendorItemPricing.getItemId()) != null) {item = items.get(vendorItemPricing.getItemId());} else {continue;}VendorCatalogPricingModel vendorCatalogPricingModel = new VendorCatalogPricingModel();vendorCatalogPricingModel.setCatalogId(item.getCatalogItemId());vendorCatalogPricingModel.setAuthId(13);vendorCatalogPricingModel.setDp(vendorItemPricing.getDp());vendorCatalogPricingModel.setTp(vendorItemPricing.getTp());vendorCatalogPricingModel.setMop(vendorItemPricing.getMop());vendorCatalogPricingModel.setEffectedOn(LocalDate.of(2023, 8, 22));vendorCatalogPricingModel.setVendorId(vendorItemPricing.getVendorId());try {vendorCatalogPricingService.createVendorCatalogPricingLog(vendorCatalogPricingModel);} catch (ProfitMandiBusinessException e) {continue;}}}public void approveVendorCatalogPricing() {List<VendorCatalogPricingLog> vendorCatalogPricingLogs = vendorCatalogPricingLogRepository.selectByStatus(VendorCatalogPricingStatus.PENDING);for (VendorCatalogPricingLog vendorCatalogPricingLog : vendorCatalogPricingLogs) {vendorCatalogPricingLog.setStatus(VendorCatalogPricingStatus.APPROVED);vendorCatalogPricingLog.setUpdatedTimestamp(LocalDateTime.now());vendorCatalogPricingLog.setApprovedBy(13);vendorCatalogPricingLog.setApprovedTimestamp(LocalDateTime.now());vendorCatalogPricingService.createVendorCatalogPricing(vendorCatalogPricingLog);}}public void sendMailWhatsAppAfterLoanDueDate() throws Exception {sdCreditService.updateRisk();List<Loan> defaultLoans = sdCreditService.getDefaultLoans();if (!defaultLoans.isEmpty()) {this.sendLoanAlert(defaultLoans);}}public void sendLoanAlert(List<Loan> defaultLoans) throwsException {List<Integer> categoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_CATEGORY,ProfitMandiConstants.TICKET_CATEGORY_RBM,ProfitMandiConstants.TICKET_CATEGORY_SALES,ProfitMandiConstants.TICKET_CATEGORY_ABM,ProfitMandiConstants.TICKET_CATEGORY_ACCOUNTS,ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT);/*for (Map.Entry<String, Set<Integer>> storeGuyEntry : csService.getAuthUserPartnerIdMappingByCategoryIds(categoryIds, false).entrySet()) {List<Loan> filteredRows = defaultLoans.stream().filter(loan -> storeGuyEntry.getValue().contains(loan.getFofoId())).collect(Collectors.toList());if (!filteredRows.isEmpty()) {for (Loan defaultLoan : filteredRows) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(defaultLoan.getId());double amount = loanStatements.stream().map(LoanStatement::getAmount).collect(Collectors.summingDouble(BigDecimal::doubleValue));String messageText = getMessageForDueDateExtend(defaultLoan,amount);// String[] email = new String[]{storeGuyEntry.getKey()};sendMailOfHtmlFormat(mailSender, email, messageText, null, subject);}}}*///Send single whatsapp to tvString title = "SD Credit Alert!";boolean notYetSent = true;for (Loan defaultLoan : defaultLoans) {List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(defaultLoan.getId());double amount = loanStatements.stream().map(LoanStatement::getAmount).collect(Collectors.summingDouble(BigDecimal::doubleValue));com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(defaultLoan.getFofoId());Address address = addressRepository.selectById(user.getAddressId());//String url = "http://app.smartdukaan.com/pages/home/credit";String message = getMessageForDueDateExtend(defaultLoan, amount);String whatsAppMessage = getWhatsAppMessageForDueDateExtend(defaultLoan, amount);if (whatsAppMessage != null) {notificationService.sendWhatsappMessage(whatsAppMessage, title, address.getPhoneNumber());if (notYetSent) {notificationService.sendWhatsappMessage(whatsAppMessage, title, "9911565032");notYetSent = false;}}String[] email = {user.getEmailId()};sendMailOfHtmlFormat(mailSender, email, message, null, "Loan Alert - SmartDukaan");}}private String getMessageForDueDateExtend(Loan defaultLoan, double amount) throws ProfitMandiBusinessException {double absoluteAmount = Math.abs(amount);long roundedAmount = Math.round(absoluteAmount);String formattedAmount = (amount < 0) ? "" + roundedAmount : "" + roundedAmount;LocalDate dueDate = defaultLoan.getDueDate().toLocalDate();LocalDate defaultDate = defaultLoan.getDueDate().toLocalDate().plusDays(15);// Retrieve the name of the user associated with the loanString name = userUserRepository.selectById(defaultLoan.getFofoId()).getName();// Initialize a StringBuilder to construct the HTML messageStringBuilder sb = new StringBuilder();if (LocalDate.now().isBefore(dueDate)) {long noOfdaysBetween = ChronoUnit.DAYS.between(LocalDate.now(), defaultLoan.getDueDate().toLocalDate());String payDate = defaultLoan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));// 5 Days Before Due Date - dailyif (noOfdaysBetween <= 5) {sb.append("<html><body><p><b>Loan Repayment Alert !</b></p></br><p>Dear " + name + "</p>");sb.append("<p>This is a friendly reminder that your loan payment is due in " + noOfdaysBetween + "days, on " +payDate +". Please ensure that the payment is made on time to avoid any late fees or penalties.</p>");sb.append("<p>As per the terms of your loan agreement, the total amount due is Rs. " + formattedAmount + ". " +"You can make the payment by adding money to your wallet. If you have any questions or need assistance, " +"our customer service team is available to help you.</p>");sb.append("<p>Thank you for your cooperation and prompt attention to this matter.</p></br><p> Smart Dukaan Team !!</p>");}} else if (LocalDate.now().isBefore(defaultDate)) {long noOfdaysBetween = ChronoUnit.DAYS.between(defaultDate, LocalDate.now());// After Due Date – Alternate daysif ((noOfdaysBetween % 2 == 0) && (noOfdaysBetween > 5)) {sb.append("<html><body><p><b>Loan Repayment Alert !</b></p></br><p>Dear " + name + "</p>");sb.append("<p>We would like to remind you that your payment for the outstanding balance on your account is now overdue. " +"As per our terms and conditions, a higher interest rate will be levied on the overdue amount Rs. " + formattedAmount + ".</p>");sb.append("<p>To avoid further charges and any negative impact on your Credit score, we kindly request that you settle the " +"outstanding balance as soon as possible.</p>");sb.append("<p>Thank you for your attention to this matter.</p></br><p> Smart Dukaan Team !!</p>");}// 5 Days before default - dailyif (noOfdaysBetween <= 5) {sb.append("<html><body><p><b>Loan Repayment Alert !</b></p></br>");sb.append("<p>Attention: High Alert</p>");sb.append("<p>Dear " + name + "</p>");sb.append("<p>This is to inform you that the due date for your payment of Rs. " + formattedAmount + " has been crossed, " +"and you are approaching the default date on " + defaultDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) + ". " +"Please be aware that this will have a significant impact on your Credit score and may result in substantial penalties as well.</p>");sb.append("<p>To rectify this situation, it is imperative that you take immediate action. " +"Please make the necessary payment immediately to avoid further consequences.</p>");sb.append("<p>Thank you for your attention to this matter.</p></br><p> Smart Dukaan Team !!</p>");}} else {// Post Default - Dailysb.append("<html><body><p><b>Loan Repayment Alert !</b></p></br><p>Dear " + name + "</p>");sb.append("<p>We regret to inform you that you are currently in loan default. As a result, " +"higher penalties are being charged, which is also negatively impacting your Credit score. " +"It is imperative that you make an immediate payment to rectify this situation.</p>");sb.append("<p>Please note that failing to make the payment promptly will result in further consequences, " +"including potential legal action and additional financial penalties. " +"We strongly urge you to take this matter seriously and settle the outstanding amount as soon as possible.</p>");sb.append("<p>To make the payment, please add Rs. " + formattedAmount + " to your wallet. We are here to help you resolve this issue and get back on track.</p>");sb.append("<p>Thank you for your attention to this matter.</p></br><p> Smart Dukaan Team !!</p>");}// Return the constructed HTML messagesb.append("</body></html>");return sb.toString();}private String getWhatsAppMessageForDueDateExtend(Loan defaultLoan, double amount) throwsProfitMandiBusinessException {double absoluteAmount = Math.abs(amount);long roundedAmount = Math.round(absoluteAmount);String formattedAmount = (amount < 0) ? "" + roundedAmount : "" + roundedAmount;LocalDate dueDate = defaultLoan.getDueDate().toLocalDate();LocalDate defaultDate = defaultLoan.getDueDate().toLocalDate().plusDays(15);// Retrieve the name of the user associated with the loanString name = userUserRepository.selectById(defaultLoan.getFofoId()).getName();// Initialize a StringBuilder to construct the HTML messageString message = null;if (LocalDate.now().isBefore(dueDate)) {long noOfdaysBetween = ChronoUnit.DAYS.between(LocalDate.now(), defaultLoan.getDueDate().toLocalDate());String payDate = defaultLoan.getDueDate().toLocalDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));// 5 Days Before Due Date - dailyif (noOfdaysBetween <= 5) {message = "Dear %s, This is a friendly reminder that your outstanding credit payment is due in %d days, on %s.\n" +"\n" +"Please ensure that the payment is made on time to avoid any late fees or penalties.As per the terms of your loan agreement, the total amount due is Rs. %s. You can make the payment by adding money to wallet.\n" +"\n" +"If you have any questions or need assistance, our customer service team is available to help you.\n" +"Thank you for your cooperation and prompt attention to this matter.\n" +"\n" +"Team SmartDukaan";message = String.format(message, name, noOfdaysBetween, payDate, formattedAmount);}} else if (LocalDate.now().isBefore(defaultDate)) {long noOfdaysBetween = ChronoUnit.DAYS.between(defaultDate, LocalDate.now());// After Due Date – Alternate daysif ((noOfdaysBetween % 2 == 0) && (noOfdaysBetween > 5)) {message = "Dear %s, We would like to remind you that your payment for the outstanding balance on your account is now overdue. \n" +"As per our terms and conditions, a higher interest rate will be levied on the overdue amount Rs.%s.\n" +"To avoid further charges and any negative impact on your Credit ratings, we kindly request that you settle the outstanding balance as soon as possible.\n" +"Thank you for your attention to this matter. \n" +"\n" +"Team SmartDukaan";message = String.format(message, name, formattedAmount);}// 5 Days before default - dailyif (noOfdaysBetween <= 5) {String defaultPayDate = defaultDate.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));message = "Attention: High Alert!! Dear %s, \n" +"\n" +"This is to inform you that the due date for your payment of Rs. %s has been crossed, and as a result, you are now about to reach default date %s.\n" +"Please be aware that this will have a significant impact on your Credit score and may result in substantial penalties as well. To rectify this situation, it is imperative that you take immediate action.\n" +"\n" +"Please make the necessary payment immediately to avoid further consequences. Thank you for your attention to this matter.\n" +"\n" +"Team SmartDukaan";message = String.format(message, name, formattedAmount, defaultPayDate);}} else {// Post Default - Dailymessage = "Dear %s, We regret to inform you that you are currently in Credit default. As a result, higher penalties are being charged, which is also negatively impacting your Credit score. \n" +"\n" +"It is imperative that you make an immediate payment to rectify this situation. \n" +"\n" +"Please note that failing to make the payment promptly will result in further consequences, including potential legal action and additional financial penalties. \n" +"\n" +"We strongly urge you to take this matter seriously and settle the outstanding amount as soon as possible. \n" +"\n" +"To make the payment, please add Rs. %s to wallet. We are here to help you resolve this issue and get back on track. Thank you for your attention to this matter. \n" +"\n" +"Team SmartDukaan";message = String.format(message, name, formattedAmount);}// Return the constructed HTML messagereturn message;}@Autowiredprivate FofoOpeningStockRepository fofoOpeningStockRepository;@Autowiredprivate SmartCartService smartCartService;public void createOpeningStockPartyWise() throws Exception {// Get all partner stock dataMap<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayInStockMap = currentInventorySnapshotRepository.getAllPartnerTodayInstock();Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayGrnPending = currentInventorySnapshotRepository.getAllPartnerTodayGrnPending();Map<Integer, List<PartnerOpeningStockByTodayModel>> partnerOpeningStockByTodayMap =new HashMap<>();// STEP 1: Copy in-stock datapartnerOpeningStockByTodayInStockMap.forEach((fofoId, list) ->partnerOpeningStockByTodayMap.put(fofoId,new ArrayList<>(list) // deep list copy));// STEP 2: Merge GRN pending using streamspartnerOpeningStockByTodayGrnPending.forEach((fofoId, grnList) -> {// If FOFO missing → simply insert GRN list (deep copy)partnerOpeningStockByTodayMap.computeIfAbsent(fofoId, x -> new ArrayList<>()).addAll(grnList.stream().map(g -> new PartnerOpeningStockByTodayModel(g.getFofoId(),g.getCatalogId(),g.getModelNumber(),g.getOpeningQty())).collect(Collectors.toList()));});// STEP 3: Now merge duplicates per catalogId using groupingpartnerOpeningStockByTodayMap.replaceAll((fofoId, list) ->list.stream().collect(Collectors.toMap(PartnerOpeningStockByTodayModel::getCatalogId,m -> new PartnerOpeningStockByTodayModel(m.getFofoId(),m.getCatalogId(),m.getModelNumber(),m.getOpeningQty()),// merge function: sum openingQty(m1, m2) -> {m1.setOpeningQty(m1.getOpeningQty() + m2.getOpeningQty());return m1;})).values().stream().collect(Collectors.toList()));Map<Integer, Map<Integer, Integer>> activatedButNotBilledCatalogQtyMap = smartCartService.activatedButNotBilledCatalogQtyMap();LOGGER.info("PartnerOpeningStockByTodayModel {}", partnerOpeningStockByTodayMap);for (Map.Entry<Integer, List<PartnerOpeningStockByTodayModel>> entry : partnerOpeningStockByTodayMap.entrySet()) {int fofoId = entry.getKey();List<PartnerOpeningStockByTodayModel> partnerStockList = entry.getValue();// Get the sold (activated-but-not-billed) quantity for this fofo and catalogMap<Integer, Integer> activatedButNotBilledQtyMap = activatedButNotBilledCatalogQtyMap.getOrDefault(fofoId, Collections.emptyMap());// if stock is avaialble in snapshotfor (PartnerOpeningStockByTodayModel partnerStock : partnerStockList) {int catalogId = partnerStock.getCatalogId();int stockCurrentQty = partnerStock.getOpeningQty();LocalDate openingDate = partnerStock.getOpeningDate();int soldButNotBilledQty = activatedButNotBilledQtyMap.getOrDefault(catalogId, 0);if (catalogId == 1025656 && fofoId == 175140232) {LOGGER.info("catalogId {}", catalogId);LOGGER.info("fofoId {}", fofoId);LOGGER.info("soldButNotBilledQty {}", soldButNotBilledQty);LOGGER.info("stockCurrentQty {}", stockCurrentQty);}// Subtract soldQty from partnerCurrentQtyint partnerCurrentQty = Math.max(stockCurrentQty - soldButNotBilledQty, 0); // Ensure it doesn't go negative// Check if an entry already exists in the FofoOpeningStock tableFofoOpeningStock existingStock = fofoOpeningStockRepository.findByFofoIdAndCatalogId(fofoId, catalogId);if (existingStock != null) {if (partnerCurrentQty < 1 && existingStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {fofoOpeningStockRepository.delete(existingStock);}if (existingStock.getOpeningQty() < partnerCurrentQty) {existingStock.setOpeningQty(partnerCurrentQty);existingStock.setCurrentQty(partnerCurrentQty);existingStock.setOpeningDate(openingDate);LOGGER.info("if condition exist {}");} else if (existingStock.getCurrentQty() >= existingStock.getOpeningQty()) {existingStock.setOpeningQty(existingStock.getCurrentQty());existingStock.setCurrentQty(partnerCurrentQty);existingStock.setOpeningDate(LocalDate.now());} else if (existingStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {int averageQty = Math.round((existingStock.getCurrentQty() + existingStock.getOpeningQty()) / 2.0f);if (averageQty == 1 && existingStock.getOpeningQty() == 1 && existingStock.getCurrentQty() == 0) {// Delete the existing stock entry from the tablefofoOpeningStockRepository.delete(existingStock);LOGGER.info("Deleted record with fofoId: {}, catalogId: {} because averageQty, openingQty, and currentQty meet deletion criteria", fofoId, catalogId);} else {// Update the existing stock with the new average quantityexistingStock.setOpeningQty(averageQty);existingStock.setCurrentQty(partnerCurrentQty);existingStock.setOpeningDate(LocalDate.now());LOGGER.info("Updated due to date being older than 5 days with average quantity: {}", averageQty);}} else {existingStock.setCurrentQty(partnerCurrentQty);}} else {LOGGER.info("else condition exist");FofoOpeningStock newStock = new FofoOpeningStock();newStock.setFofoId(fofoId);newStock.setCatalogId(catalogId);newStock.setOpeningQty(partnerCurrentQty);newStock.setCurrentQty(partnerCurrentQty);newStock.setOpeningDate(openingDate);fofoOpeningStockRepository.persist(newStock);}}// if stock is not available in snapshot but available in opening stockList<FofoOpeningStock> fofoOpeningStockList = fofoOpeningStockRepository.selectAllByFofoId(fofoId);for (FofoOpeningStock fofoOpeningStock : fofoOpeningStockList) {if (!partnerStockList.stream().anyMatch(partnerStock -> partnerStock.getCatalogId() == fofoOpeningStock.getCatalogId())) {if (fofoOpeningStock.getOpeningDate().isBefore(LocalDate.now().minusDays(5))) {LOGGER.info("not match stock{}", fofoOpeningStock);fofoOpeningStockRepository.delete(fofoOpeningStock);} else {LOGGER.info("not match stock2{}", fofoOpeningStock);fofoOpeningStock.setCurrentQty(0);}}}}}@Autowiredprivate CategorisedCatalogRepository categorisedCatalogRepository;public void groupHidCatalogsByWeeks() throws ProfitMandiBusinessException, MessagingException, IOException {List<CategorisedCatalogListModel> categorisedCatalogs = categorisedCatalogRepository.getListByStatus(CatalogMovingEnum.HID);LocalDate currentDate = LocalDate.now();LocalDate oneWeekAgo = currentDate.minusDays(7);LocalDate twoWeeksAgo = currentDate.minusDays(14);LocalDate threeWeeksAgo = currentDate.minusDays(21);// This Week (inclusive of the current date)List<CategorisedCatalogListModel> thisWeekCatalogs = categorisedCatalogs.stream().filter(catalog -> !catalog.getStatusCreatedDate().isBefore(oneWeekAgo)).collect(Collectors.toList());// Last Week (from one week ago to two weeks ago, exclusive of this week)List<CategorisedCatalogListModel> lastWeekCatalogs = categorisedCatalogs.stream().filter(catalog -> catalog.getStatusCreatedDate().isBefore(oneWeekAgo) && !catalog.getStatusCreatedDate().isBefore(twoWeeksAgo)).collect(Collectors.toList());// Two Weeks Ago (from two weeks ago to three weeks ago, exclusive of last week)List<CategorisedCatalogListModel> twoWeeksAgoCatalogs = categorisedCatalogs.stream().filter(catalog -> catalog.getStatusCreatedDate().isBefore(twoWeeksAgo) && !catalog.getStatusCreatedDate().isBefore(threeWeeksAgo)).collect(Collectors.toList());// Older than Two Weeks Ago (anything older than three weeks ago)List<CategorisedCatalogListModel> olderCatalogs = categorisedCatalogs.stream().filter(catalog -> catalog.getStatusCreatedDate().isBefore(threeWeeksAgo)).collect(Collectors.toList());String subject = "Hid Catalogs";StringBuilder sb = new StringBuilder();sb.append("<html><body><p>Hi Catagory Team,\n");sb.append("<p style='font-weight:500;'>Please review the HID catalogs for this week:</p>\n" + "<table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");sb.append("</tr>\n");for (CategorisedCatalogListModel catalog : thisWeekCatalogs) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");sb.append("</tr>\n");}sb.append("</table>");sb.append("</br>");sb.append("</br>");sb.append("</br>");sb.append("<p style='font-weight:500;'>Please review the HID catalogs for last week:</p>\n" + "<table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");sb.append("</tr>\n");for (CategorisedCatalogListModel catalog : lastWeekCatalogs) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");sb.append("</tr>\n");}sb.append("</table>");sb.append("</br>");sb.append("</br>");sb.append("</br>");sb.append("<p style='font-weight:500;'>Please review the HID catalogs for two week ago:</p>\n" + "<table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");sb.append("</tr>\n");for (CategorisedCatalogListModel catalog : twoWeeksAgoCatalogs) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");sb.append("</tr>\n");}sb.append("</table>");sb.append("</br>");sb.append("</br>");sb.append("</br>");sb.append("<p style='font-weight:500;'>Please review the HID catalogs for older than two weeks ago:</p>\n" + "<table style='border:1px solid black ;padding: 5px; border-collapse: collapse;'>");sb.append("<th style='border:1px solid black;padding: 5px'>Brand</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Number</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Model Name</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Catalog Id</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>Start Date</th>\n");sb.append("<th style='border:1px solid black;padding: 5px'>End Date</th>\n");sb.append("</tr>\n");for (CategorisedCatalogListModel catalog : olderCatalogs) {sb.append("<tr>");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getBrand() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelNumber() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getModelId() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getCurrentStatus() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusCreatedDate() + "</td>\n");sb.append("<td style='border:1px solid black;padding: 5px'>" + catalog.getStatusEndDate() + "</td>\n");sb.append("</tr>\n");}sb.append("</table>");sb.append("</body></html>");List<String> sendTo = Arrays.asList("uday.singh@smartdukaan.com", "kuldeep.kumar@smartdukaan.com", "nishant.ohri@smartdukaan.com", "ritesh.chauhan1@smartdukaan.com", "shobhit.tandon@smartdukaan.com", "tarun.verma@smartdukaan.com", "niranjan.kala@smartdukaan.com");String[] email = sendTo.toArray(new String[sendTo.size()]);this.sendMailOfHtmlFormat(mailSender, email, sb.toString(), null, subject);}public void send10OrMoreOlderStockReport() throws Exception {System.out.print("testSTart");purSaleService.moreThen10DaysEgedStockReport();System.out.print("testEnd");}public void sendUpdateMobileBrandMarketShareQuaterlyMail() throws Exception {String subject = "Reminder: Please Update Brand-wise Market Share";String body = "Dear Team,\n\n" +"This is a gentle reminder to kindly update the brand-wise market share data for the current quarter.\n\n" +"Best regards,\n" +"SmartDukaan Team";Utils.sendMailWithAttachments(googleMailSender,new String[]{"sm.@smartdukaan.com"},new String[]{"tech@smartdukaan.com"},subject,body);}}// 2284"